From c986058e301c1eda2c8d388b28c4eb9b736d854b Mon Sep 17 00:00:00 2001 From: Emmanuel Garcia Date: Mon, 21 Dec 2020 12:38:48 -0800 Subject: [PATCH 0001/1565] [video_player] Fix video player test (#3361) --- packages/video_player/video_player/CHANGELOG.md | 4 ++++ packages/video_player/video_player/pubspec.yaml | 2 +- .../video_player/video_player/test/video_player_test.dart | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index 4e2826262eaf..c79b0a02bc98 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.6 + +* Fix `VideoPlayerValue toString()` test. + ## 2.0.0-nullsafety.5 * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index 603f2358cd55..a8066e129608 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -4,7 +4,7 @@ description: Flutter plugin for displaying inline video with other Flutter # 0.10.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 2.0.0-nullsafety.5 +version: 2.0.0-nullsafety.6 homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player flutter: diff --git a/packages/video_player/video_player/test/video_player_test.dart b/packages/video_player/video_player/test/video_player_test.dart index 3e9800f2b68e..f3f2b5e8faf1 100644 --- a/packages/video_player/video_player/test/video_player_test.dart +++ b/packages/video_player/video_player/test/video_player_test.dart @@ -567,7 +567,7 @@ void main() { 'VideoPlayerValue(duration: 0:00:05.000000, ' 'size: Size(400.0, 300.0), ' 'position: 0:00:01.000000, ' - 'caption: Caption(number: null, start: null, end: null, text: foo), ' + 'caption: Caption(number: 0, start: 0:00:00.000000, end: 0:00:00.000000, text: foo), ' 'buffered: [DurationRange(start: 0:00:00.000000, end: 0:00:04.000000)], ' 'isInitialized: true, ' 'isPlaying: true, ' From 8980d79446d3196bbd0c1366ab67ab2a5f39da9d Mon Sep 17 00:00:00 2001 From: Mehmet Fidanboylu Date: Mon, 21 Dec 2020 14:33:17 -0800 Subject: [PATCH 0002/1565] [image_picker] Do not copy a static field into another static field (#3353) --- packages/image_picker/image_picker/CHANGELOG.md | 4 ++++ .../image_picker/lib/image_picker.dart | 2 +- packages/image_picker/image_picker/pubspec.yaml | 4 +++- .../image_picker/test/image_picker_test.dart | 16 ++++++++++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md index 4c1553a8ccaf..32d61cc79607 100644 --- a/packages/image_picker/image_picker/CHANGELOG.md +++ b/packages/image_picker/image_picker/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.7+19 + +* Do not copy static field to another static field. + ## 0.6.7+18 * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) diff --git a/packages/image_picker/image_picker/lib/image_picker.dart b/packages/image_picker/image_picker/lib/image_picker.dart index 82c199e007f4..5c0683c3f29f 100755 --- a/packages/image_picker/image_picker/lib/image_picker.dart +++ b/packages/image_picker/image_picker/lib/image_picker.dart @@ -27,7 +27,7 @@ export 'package:image_picker_platform_interface/image_picker_platform_interface. class ImagePicker { /// The platform interface that drives this plugin @visibleForTesting - static ImagePickerPlatform platform = ImagePickerPlatform.instance; + static ImagePickerPlatform get platform => ImagePickerPlatform.instance; /// Returns a [File] object pointing to the image that was picked. /// diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index 29baaa0de5d5..377c3840c2d1 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker description: Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker -version: 0.6.7+18 +version: 0.6.7+19 flutter: plugin: @@ -25,7 +25,9 @@ dev_dependencies: sdk: flutter integration_test: path: ../../integration_test + mockito: ^4.1.3 pedantic: ^1.8.0 + plugin_platform_interface: ^1.0.3 environment: sdk: ">=2.1.0 <3.0.0" diff --git a/packages/image_picker/image_picker/test/image_picker_test.dart b/packages/image_picker/image_picker/test/image_picker_test.dart index 0ada1b261363..7172975ded5d 100644 --- a/packages/image_picker/image_picker/test/image_picker_test.dart +++ b/packages/image_picker/image_picker/test/image_picker_test.dart @@ -5,6 +5,9 @@ import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:image_picker/image_picker.dart'; +import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; +import 'package:mockito/mockito.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); @@ -26,6 +29,15 @@ void main() { log.clear(); }); + test('ImagePicker platform instance overrides the actual platform used', + () { + final ImagePickerPlatform savedPlatform = ImagePickerPlatform.instance; + final MockPlatform mockPlatform = MockPlatform(); + ImagePickerPlatform.instance = mockPlatform; + expect(ImagePicker.platform, mockPlatform); + ImagePickerPlatform.instance = savedPlatform; + }); + group('#pickImage', () { test('passes the image source argument correctly', () async { await picker.getImage(source: ImageSource.camera); @@ -336,3 +348,7 @@ void main() { }); }); } + +class MockPlatform extends Mock + with MockPlatformInterfaceMixin + implements ImagePickerPlatform {} From 0f1c20dd25c070a4b1349bfcbfe0f284ee205150 Mon Sep 17 00:00:00 2001 From: Mehmet Fidanboylu Date: Mon, 21 Dec 2020 14:38:22 -0800 Subject: [PATCH 0003/1565] [url_launcher] forceSafariVC should be nullable to avoid breaking change (#3354) --- packages/url_launcher/url_launcher/CHANGELOG.md | 4 ++++ packages/url_launcher/url_launcher/lib/url_launcher.dart | 4 ++-- packages/url_launcher/url_launcher/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index 9df2d27a2b57..eb08455c4785 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.0.0-nullsafety.3 + +* forceSafariVC should be nullable. + ## 6.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/url_launcher/url_launcher/lib/url_launcher.dart b/packages/url_launcher/url_launcher/lib/url_launcher.dart index 6138fff2e3d9..35833de18738 100644 --- a/packages/url_launcher/url_launcher/lib/url_launcher.dart +++ b/packages/url_launcher/url_launcher/lib/url_launcher.dart @@ -62,7 +62,7 @@ import 'package:url_launcher_platform_interface/url_launcher_platform_interface. /// is set to true and the universal link failed to launch. Future launch( String urlString, { - bool forceSafariVC = true, + bool? forceSafariVC, bool forceWebView = false, bool enableJavaScript = false, bool enableDomStorage = false, @@ -95,7 +95,7 @@ Future launch( final bool result = await UrlLauncherPlatform.instance.launch( urlString, - useSafariVC: forceSafariVC, + useSafariVC: forceSafariVC ?? isWebURL, useWebView: forceWebView, enableJavaScript: enableJavaScript, enableDomStorage: enableDomStorage, diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index e2d7a161e1ea..0ab2d410c000 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -2,7 +2,7 @@ name: url_launcher description: Flutter plugin for launching a URL on Android and iOS. Supports web, phone, SMS, and email schemes. homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher -version: 6.0.0-nullsafety.2 +version: 6.0.0-nullsafety.3 flutter: plugin: From 57087311b64246a0e56b82f918605334e326294d Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Tue, 22 Dec 2020 18:56:02 +0100 Subject: [PATCH 0004/1565] Fix documentation (#3362) --- packages/camera/camera/CHANGELOG.md | 4 ++++ packages/camera/camera/lib/src/camera_controller.dart | 8 +------- packages/camera/camera/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 168ed5557123..2811384a7d3b 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.2+1 + +* Fix the API documentation for the `CameraController.takePicture` method. + ## 0.6.2 * Add zoom support for Android and iOS implementations. diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index b79975fbad8e..1d7aed755f42 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -226,13 +226,7 @@ class CameraController extends ValueNotifier { await CameraPlatform.instance.prepareForVideoRecording(); } - /// Captures an image and saves it to [path]. - /// - /// A path can for example be obtained using - /// [path_provider](https://pub.dartlang.org/packages/path_provider). - /// - /// If a file already exists at the provided path an error will be thrown. - /// The file can be read as this function returns. + /// Captures an image and returns the file where it was saved. /// /// Throws a [CameraException] if the capture fails. Future takePicture() async { diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index d823dd383281..4f6ade284e29 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.6.2 +version: 0.6.2+1 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From 7bc9aa215f885e0ac384082aa8286103329a2d6a Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Tue, 22 Dec 2020 19:02:49 +0100 Subject: [PATCH 0005/1565] Make sure saveTo returns a Future (#3363) --- packages/cross_file/CHANGELOG.md | 4 ++++ packages/cross_file/lib/src/types/base.dart | 2 +- packages/cross_file/lib/src/types/html.dart | 2 +- packages/cross_file/lib/src/types/io.dart | 2 +- packages/cross_file/pubspec.yaml | 2 +- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/cross_file/CHANGELOG.md b/packages/cross_file/CHANGELOG.md index 1716cb5ade7f..5ad91979dc89 100644 --- a/packages/cross_file/CHANGELOG.md +++ b/packages/cross_file/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.0 + +* **breaking change** Make sure the `saveTo` method returns a `Future` so it can be awaited and users are sure the file has been written to disk. + ## 0.1.0+2 * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) diff --git a/packages/cross_file/lib/src/types/base.dart b/packages/cross_file/lib/src/types/base.dart index 6dc2d51b08b1..1a1b5694d58f 100644 --- a/packages/cross_file/lib/src/types/base.dart +++ b/packages/cross_file/lib/src/types/base.dart @@ -18,7 +18,7 @@ abstract class XFileBase { XFileBase(String path); /// Save the CrossFile at the indicated file path. - void saveTo(String path) async { + Future saveTo(String path) { throw UnimplementedError('saveTo has not been implemented.'); } diff --git a/packages/cross_file/lib/src/types/html.dart b/packages/cross_file/lib/src/types/html.dart index 269f2a8d9412..646939612d75 100644 --- a/packages/cross_file/lib/src/types/html.dart +++ b/packages/cross_file/lib/src/types/html.dart @@ -108,7 +108,7 @@ class XFile extends XFileBase { /// Saves the data of this CrossFile at the location indicated by path. /// For the web implementation, the path variable is ignored. - void saveTo(String path) async { + Future saveTo(String path) async { // Create a DOM container where we can host the anchor. _target = ensureInitialized('__x_file_dom_element'); diff --git a/packages/cross_file/lib/src/types/io.dart b/packages/cross_file/lib/src/types/io.dart index 81b8cdd84d67..d9a93559b507 100644 --- a/packages/cross_file/lib/src/types/io.dart +++ b/packages/cross_file/lib/src/types/io.dart @@ -57,7 +57,7 @@ class XFile extends XFileBase { } @override - void saveTo(String path) async { + Future saveTo(String path) async { File fileToSave = File(path); await fileToSave.writeAsBytes(_bytes ?? (await readAsBytes())); await fileToSave.create(); diff --git a/packages/cross_file/pubspec.yaml b/packages/cross_file/pubspec.yaml index 0c7f30677aba..4c9acf9b008a 100644 --- a/packages/cross_file/pubspec.yaml +++ b/packages/cross_file/pubspec.yaml @@ -1,7 +1,7 @@ name: cross_file description: An abstraction to allow working with files across multiple platforms. homepage: https://github.com/flutter/plugins/tree/master/packages/cross_file -version: 0.1.0+2 +version: 0.2.0 dependencies: flutter: From 622ba57c3960e511bdd4adabe800aef844e263fc Mon Sep 17 00:00:00 2001 From: Bodhi Mulders Date: Tue, 22 Dec 2020 23:28:30 +0100 Subject: [PATCH 0006/1565] [camera] Add implementations for the torch flash mode. (#3338) * Added torch mode functionality for Android and iOS. * Format objective c code --- packages/camera/camera/CHANGELOG.md | 4 + .../io/flutter/plugins/camera/Camera.java | 8 +- .../plugins/camera/types/FlashMode.java | 3 +- .../plugins/camera/types/FlashModeTest.java | 4 + packages/camera/camera/example/lib/main.dart | 9 ++ .../camera/camera/ios/Classes/CameraPlugin.m | 99 +++++++++++++++---- packages/camera/camera/pubspec.yaml | 2 +- .../method_channel_camera_test.dart | 3 + 8 files changed, 108 insertions(+), 24 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 2811384a7d3b..b407b83e35db 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.3 + +* Adds torch mode as a flash mode for Android and iOS implementations. + ## 0.6.2+1 * Fix the API documentation for the `CameraController.takePicture` method. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 3e8bbc7b295b..cae666d6742a 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -532,7 +532,6 @@ public void setFlashMode(@NonNull final Result result, FlashMode mode) return; } // Get flash - this.flashMode = mode; initPreviewCaptureBuilder(); this.cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); @@ -553,11 +552,16 @@ private void initPreviewCaptureBuilder() { captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF); break; case always: - default: captureRequestBuilder.set( CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH); captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF); break; + case torch: + default: + captureRequestBuilder.set( + CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); + captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH); + break; } } diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java index eddeddc47eab..99d4915b3a6a 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java @@ -4,7 +4,8 @@ public enum FlashMode { off, auto, - always; + always, + torch; public static FlashMode getValueForString(String modeStr) { try { diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java index 0549e4fc750e..d2674e8c7e06 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java @@ -16,6 +16,10 @@ public void getValueForString_returns_correct_values() { "Returns FlashMode.always for 'always'", FlashMode.getValueForString("always"), FlashMode.always); + assertEquals( + "Returns FlashMode.torch for 'torch'", + FlashMode.getValueForString("torch"), + FlashMode.torch); } @Test diff --git a/packages/camera/camera/example/lib/main.dart b/packages/camera/camera/example/lib/main.dart index 049141d3935e..ee8e2c259b3d 100644 --- a/packages/camera/camera/example/lib/main.dart +++ b/packages/camera/camera/example/lib/main.dart @@ -256,6 +256,15 @@ class _CameraExampleHomeState extends State ? () => onFlashModeButtonPressed(FlashMode.always) : null, ), + IconButton( + icon: const Icon(Icons.highlight), + color: controller?.value?.flashMode == FlashMode.torch + ? Colors.orange + : Colors.blue, + onPressed: controller != null + ? () => onFlashModeButtonPressed(FlashMode.torch) + : null, + ), ], ); } diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index c13ff60abd0a..d54695233bdb 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -134,13 +134,23 @@ - (UIImageOrientation)getImageRotation { } @end -static AVCaptureFlashMode getFlashModeForString(NSString *mode) { +// Mirrors FlashMode in flash_mode.dart +typedef enum { + FlashModeOff, + FlashModeAuto, + FlashModeAlways, + FlashModeTorch, +} FlashMode; + +static FlashMode getFlashModeForString(NSString *mode) { if ([mode isEqualToString:@"off"]) { - return AVCaptureFlashModeOff; + return FlashModeOff; } else if ([mode isEqualToString:@"auto"]) { - return AVCaptureFlashModeAuto; + return FlashModeAuto; } else if ([mode isEqualToString:@"always"]) { - return AVCaptureFlashModeOn; + return FlashModeAlways; + } else if ([mode isEqualToString:@"torch"]) { + return FlashModeTorch; } else { NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSURLErrorUnknown @@ -152,6 +162,20 @@ static AVCaptureFlashMode getFlashModeForString(NSString *mode) { } } +static AVCaptureFlashMode getAVCaptureFlashModeForFlashMode(FlashMode mode) { + switch (mode) { + case FlashModeOff: + return AVCaptureFlashModeOff; + case FlashModeAuto: + return AVCaptureFlashModeAuto; + case FlashModeAlways: + return AVCaptureFlashModeOn; + case FlashModeTorch: + default: + return -1; + } +} + // Mirrors ResolutionPreset in camera.dart typedef enum { veryLow, @@ -219,7 +243,7 @@ @interface FLTCam : NSObject [ + isMethodCall('setFlashMode', + arguments: {'cameraId': cameraId, 'mode': 'torch'}), isMethodCall('setFlashMode', arguments: {'cameraId': cameraId, 'mode': 'always'}), isMethodCall('setFlashMode', From a9513d592101555eaab8f26315d161ac84f3d066 Mon Sep 17 00:00:00 2001 From: Bodhi Mulders Date: Thu, 24 Dec 2020 17:20:43 +0100 Subject: [PATCH 0007/1565] [camera] Fix flash/torch not working on some Android devices. (#3367) * Wait pre capture to finish * Add autofocus stage to capture * Fixed autofocus stage * Make sure torch is turned off * Format & structure improvements * Update changelog and pubspec * Update packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java Co-authored-by: Maurits van Beusekom * Update packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java Co-authored-by: Maurits van Beusekom * Update packages/camera/camera/CHANGELOG.md Co-authored-by: Maurits van Beusekom * Update packages/camera/camera/pubspec.yaml Co-authored-by: Maurits van Beusekom * Remove unnecessary import. * Updated unit tests Co-authored-by: Maurits van Beusekom Co-authored-by: Maurits van Beusekom --- packages/camera/camera/CHANGELOG.md | 4 + .../io/flutter/plugins/camera/Camera.java | 176 ++++++++++++++++-- .../plugins/camera/PictureCaptureRequest.java | 4 +- .../camera/PictureCaptureRequestTest.java | 12 +- packages/camera/camera/pubspec.yaml | 2 +- 5 files changed, 173 insertions(+), 25 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index b407b83e35db..225601054fb9 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.3+1 + +* Fixes flash & torch modes not working on some Android devices. + ## 0.6.3 * Adds torch mode as a flash mode for Android and iOS implementations. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index cae666d6742a..0116ce3c0e4d 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -12,6 +12,7 @@ import android.graphics.SurfaceTexture; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCaptureSession; +import android.hardware.camera2.CameraCaptureSession.CaptureCallback; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraDevice; import android.hardware.camera2.CameraManager; @@ -29,12 +30,15 @@ import android.os.Build; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; +import android.os.Handler; +import android.os.Looper; import android.util.Size; import android.view.OrientationEventListener; import android.view.Surface; import androidx.annotation.NonNull; import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.MethodChannel.Result; +import io.flutter.plugins.camera.PictureCaptureRequest.State; import io.flutter.plugins.camera.media.MediaRecorderBuilder; import io.flutter.plugins.camera.types.FlashMode; import io.flutter.plugins.camera.types.ResolutionPreset; @@ -246,7 +250,7 @@ public void takePicture(@NonNull final Result result) { }, null); - runPicturePreCapture(); + runPictureAutoFocus(); } private final CameraCaptureSession.CaptureCallback pictureCaptureCallback = @@ -256,18 +260,15 @@ public void onCaptureCompleted( @NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) { - assert (pictureCaptureRequest != null); - switch (pictureCaptureRequest.getState()) { - case awaitingPreCapture: - Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); - // Some devices might return null here, in which case we will also continue. - if (aeState == null - || aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED - || aeState == CaptureRequest.CONTROL_AE_STATE_CONVERGED) { - runPictureCapture(); - } - break; - } + processCapture(result); + } + + @Override + public void onCaptureProgressed( + @NonNull CameraCaptureSession session, + @NonNull CaptureRequest request, + @NonNull CaptureResult partialResult) { + processCapture(partialResult); } @Override @@ -289,11 +290,54 @@ public void onCaptureFailed( } pictureCaptureRequest.error("captureFailure", reason, null); } + + private void processCapture(CaptureResult result) { + if (pictureCaptureRequest == null) { + return; + } + + Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); + Integer afState = result.get(CaptureResult.CONTROL_AF_STATE); + switch (pictureCaptureRequest.getState()) { + case focusing: + if (afState == null) { + return; + } else if (afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED + || afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) { + // Some devices might return null here, in which case we will also continue. + if (aeState == null || aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) { + runPictureCapture(); + } else { + runPicturePreCapture(); + } + } + break; + case preCapture: + // Some devices might return null here, in which case we will also continue. + if (aeState == null + || aeState == CaptureRequest.CONTROL_AE_STATE_PRECAPTURE + || aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED + || aeState == CaptureRequest.CONTROL_AE_STATE_CONVERGED) { + pictureCaptureRequest.setState(State.waitingPreCaptureReady); + } + break; + case waitingPreCaptureReady: + if (aeState == null || aeState != CaptureRequest.CONTROL_AE_STATE_PRECAPTURE) { + runPictureCapture(); + } + } + } }; + private void runPictureAutoFocus() { + assert (pictureCaptureRequest != null); + pictureCaptureRequest.setState(PictureCaptureRequest.State.focusing); + lockAutoFocus(); + } + private void runPicturePreCapture() { assert (pictureCaptureRequest != null); - pictureCaptureRequest.setState(PictureCaptureRequest.State.awaitingPreCapture); + pictureCaptureRequest.setState(PictureCaptureRequest.State.preCapture); captureRequestBuilder.set( CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, @@ -331,7 +375,47 @@ private void runPictureCapture() { CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH); break; } - cameraCaptureSession.capture(captureBuilder.build(), pictureCaptureCallback, null); + cameraCaptureSession.stopRepeating(); + cameraCaptureSession.capture( + captureBuilder.build(), + new CameraCaptureSession.CaptureCallback() { + @Override + public void onCaptureCompleted( + @NonNull CameraCaptureSession session, + @NonNull CaptureRequest request, + @NonNull TotalCaptureResult result) { + unlockAutoFocus(); + } + }, + null); + } catch (CameraAccessException e) { + pictureCaptureRequest.error("cameraAccess", e.getMessage(), null); + } + } + + private void lockAutoFocus() { + captureRequestBuilder.set( + CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START); + try { + cameraCaptureSession.capture(captureRequestBuilder.build(), pictureCaptureCallback, null); + } catch (CameraAccessException e) { + pictureCaptureRequest.error("cameraAccess", e.getMessage(), null); + } + } + + private void unlockAutoFocus() { + captureRequestBuilder.set( + CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL); + initPreviewCaptureBuilder(); + try { + cameraCaptureSession.capture(captureRequestBuilder.build(), null, null); + } catch (CameraAccessException ignored) { + } + captureRequestBuilder.set( + CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_IDLE); + try { + cameraCaptureSession.setRepeatingRequest( + captureRequestBuilder.build(), pictureCaptureCallback, null); } catch (CameraAccessException e) { pictureCaptureRequest.error("cameraAccess", e.getMessage(), null); } @@ -377,7 +461,10 @@ public void onConfigured(@NonNull CameraCaptureSession session) { } cameraCaptureSession = session; initPreviewCaptureBuilder(); - cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); + cameraCaptureSession.setRepeatingRequest( + captureRequestBuilder.build(), + pictureCaptureCallback, + new Handler(Looper.getMainLooper())); if (onSuccessCallback != null) { onSuccessCallback.run(); } @@ -531,11 +618,60 @@ public void setFlashMode(@NonNull final Result result, FlashMode mode) result.error("setFlashModeFailed", "Device does not have flash capabilities", null); return; } + + // If switching directly from torch to auto or on, make sure we turn off the torch. + if (flashMode == FlashMode.torch && mode != FlashMode.torch && mode != FlashMode.off) { + this.flashMode = FlashMode.off; + initPreviewCaptureBuilder(); + this.cameraCaptureSession.setRepeatingRequest( + captureRequestBuilder.build(), + new CaptureCallback() { + private boolean isFinished = false; + + @Override + public void onCaptureCompleted( + @NonNull CameraCaptureSession session, + @NonNull CaptureRequest request, + @NonNull TotalCaptureResult captureResult) { + if (isFinished) { + return; + } + + updateFlash(mode); + result.success(null); + isFinished = true; + } + + @Override + public void onCaptureFailed( + @NonNull CameraCaptureSession session, + @NonNull CaptureRequest request, + @NonNull CaptureFailure failure) { + if (isFinished) { + return; + } + + result.error("setFlashModeFailed", "Could not set flash mode.", null); + isFinished = true; + } + }, + null); + } else { + updateFlash(mode); + result.success(null); + } + } + + private void updateFlash(FlashMode mode) { // Get flash - this.flashMode = mode; + flashMode = mode; initPreviewCaptureBuilder(); - this.cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); - result.success(null); + try { + cameraCaptureSession.setRepeatingRequest( + captureRequestBuilder.build(), pictureCaptureCallback, null); + } catch (CameraAccessException e) { + pictureCaptureRequest.error("cameraAccess", e.getMessage(), null); + } } private void initPreviewCaptureBuilder() { @@ -563,6 +699,8 @@ private void initPreviewCaptureBuilder() { captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH); break; } + captureRequestBuilder.set( + CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); } public void startPreview() throws CameraAccessException { diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java index e365f071d9a8..1103b8583ad6 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java @@ -7,7 +7,9 @@ class PictureCaptureRequest { enum State { idle, - awaitingPreCapture, + focusing, + preCapture, + waitingPreCaptureReady, capturing, finished, error, diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java index 2b6aa0f25fcf..2356b306c6c4 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java @@ -20,11 +20,15 @@ public void state_is_idle_by_default() { @Test public void setState_sets_state() { PictureCaptureRequest req = new PictureCaptureRequest(null); - req.setState(PictureCaptureRequest.State.awaitingPreCapture); + req.setState(PictureCaptureRequest.State.focusing); + assertEquals("State is focusing", req.getState(), PictureCaptureRequest.State.focusing); + req.setState(PictureCaptureRequest.State.preCapture); + assertEquals("State is preCapture", req.getState(), PictureCaptureRequest.State.preCapture); + req.setState(PictureCaptureRequest.State.waitingPreCaptureReady); assertEquals( - "State is awaitingPreCapture", + "State is waitingPreCaptureReady", req.getState(), - PictureCaptureRequest.State.awaitingPreCapture); + PictureCaptureRequest.State.waitingPreCaptureReady); req.setState(PictureCaptureRequest.State.capturing); assertEquals( "State is awaitingPreCapture", req.getState(), PictureCaptureRequest.State.capturing); @@ -49,7 +53,7 @@ public void isFinished_is_true_When_state_is_finished_or_error() { // Test false states req.setState(PictureCaptureRequest.State.idle); assertFalse(req.isFinished()); - req.setState(PictureCaptureRequest.State.awaitingPreCapture); + req.setState(PictureCaptureRequest.State.preCapture); assertFalse(req.isFinished()); req.setState(PictureCaptureRequest.State.capturing); assertFalse(req.isFinished()); diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 1bccbd4d45df..43a5fca3da21 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.6.3 +version: 0.6.3+1 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From 7eff06206d5ff76097656b9b0f9b148a748c649e Mon Sep 17 00:00:00 2001 From: Bodhi Mulders Date: Sun, 27 Dec 2020 16:02:53 +0100 Subject: [PATCH 0008/1565] [camera] Fix video recording exception on Android (#3375) * Fixed video recording * Update changelog and pubspec version * Update packages/camera/camera/CHANGELOG.md Co-authored-by: Maurits van Beusekom Co-authored-by: Maurits van Beusekom --- packages/camera/camera/CHANGELOG.md | 4 ++++ .../src/main/java/io/flutter/plugins/camera/Camera.java | 4 +++- packages/camera/camera/pubspec.yaml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 225601054fb9..461b2d927eda 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.3+2 + +* Fixes crash on Android which occurs after video recording has stopped just before taking a picture. + ## 0.6.3+1 * Fixes flash & torch modes not working on some Android devices. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 0116ce3c0e4d..3c28d6655e48 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -276,7 +276,9 @@ public void onCaptureFailed( @NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure) { - assert (pictureCaptureRequest != null); + if (pictureCaptureRequest == null || pictureCaptureRequest.isFinished()) { + return; + } String reason; switch (failure.getReason()) { case CaptureFailure.REASON_ERROR: diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 43a5fca3da21..1f5d06eecbe3 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.6.3+1 +version: 0.6.3+2 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From 3ec0d64a5b65b9a27863c553fff1ca54687f5431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl?= <32639467+danielroek@users.noreply.github.com> Date: Mon, 28 Dec 2020 11:14:26 +0100 Subject: [PATCH 0009/1565] [camera] Added maxVideoDuration to startVideoRecording (#3365) * Added maxVideoDuration to startVideoRecording * updated documentation Co-authored-by: Maurits van Beusekom * updated documentation Co-authored-by: Maurits van Beusekom * Fixed long line in docs * Formatting Co-authored-by: Maurits van Beusekom --- .../camera_platform_interface/CHANGELOG.md | 4 ++++ .../method_channel/method_channel_camera.dart | 8 +++++-- .../platform_interface/camera_platform.dart | 5 ++++- .../camera_platform_interface/pubspec.yaml | 2 +- .../method_channel_camera_test.dart | 22 +++++++++++++++++++ 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/packages/camera/camera_platform_interface/CHANGELOG.md b/packages/camera/camera_platform_interface/CHANGELOG.md index ea9821e841f9..d117e1c0eba4 100644 --- a/packages/camera/camera_platform_interface/CHANGELOG.md +++ b/packages/camera/camera_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.0 + +- Added an optional `maxVideoDuration` parameter to the `startVideoRecording` method, which allows implementations to limit the duration of a video recording. + ## 1.0.4 - Added the torch option to the FlashMode enum, which when implemented indicates the flash light should be turned on continuously. diff --git a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart index 3bf996fedb19..bf2b3d3bd70a 100644 --- a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart +++ b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart @@ -146,10 +146,14 @@ class MethodChannelCamera extends CameraPlatform { _channel.invokeMethod('prepareForVideoRecording'); @override - Future startVideoRecording(int cameraId) async { + Future startVideoRecording(int cameraId, + {Duration maxVideoDuration}) async { await _channel.invokeMethod( 'startVideoRecording', - {'cameraId': cameraId}, + { + 'cameraId': cameraId, + 'maxVideoDuration': maxVideoDuration?.inMilliseconds, + }, ); } diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart index 6f96079dc55c..6c8e200c75c2 100644 --- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart +++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart @@ -88,8 +88,11 @@ abstract class CameraPlatform extends PlatformInterface { /// Starts a video recording. /// + /// The length of the recording can be limited by specifying the [maxVideoDuration]. + /// By default no maximum duration is specified, + /// meaning the recording will continue until manually stopped. /// The video is returned as a [XFile] after calling [stopVideoRecording]. - Future startVideoRecording(int cameraId) { + Future startVideoRecording(int cameraId, {Duration maxVideoDuration}) { throw UnimplementedError('startVideoRecording() is not implemented.'); } diff --git a/packages/camera/camera_platform_interface/pubspec.yaml b/packages/camera/camera_platform_interface/pubspec.yaml index 8cb643e84ca6..b6933314d41d 100644 --- a/packages/camera/camera_platform_interface/pubspec.yaml +++ b/packages/camera/camera_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the camera plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.0.4 +version: 1.1.0 dependencies: flutter: diff --git a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart index 82b01015e4f4..12f5d6e8ecf8 100644 --- a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart +++ b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart @@ -411,10 +411,32 @@ void main() { expect(channel.log, [ isMethodCall('startVideoRecording', arguments: { 'cameraId': cameraId, + 'maxVideoDuration': null, }), ]); }); + test('Should pass maxVideoDuration when starting recording a video', + () async { + // Arrange + MethodChannelMock channel = MethodChannelMock( + channelName: 'plugins.flutter.io/camera', + methods: {'startVideoRecording': null}, + ); + + // Act + await camera.startVideoRecording( + cameraId, + maxVideoDuration: Duration(seconds: 10), + ); + + // Assert + expect(channel.log, [ + isMethodCall('startVideoRecording', + arguments: {'cameraId': cameraId, 'maxVideoDuration': 10000}), + ]); + }); + test('Should stop a video recording and return the file', () async { // Arrange MethodChannelMock channel = MethodChannelMock( From 1c0090511fc84c2a64b275d7c3aea70e9222f220 Mon Sep 17 00:00:00 2001 From: Bodhi Mulders Date: Mon, 28 Dec 2020 20:00:47 +0100 Subject: [PATCH 0010/1565] [camera_platform_interface] Add platform interface methods for setting auto exposure. (#3345) * Added platform interface methods for setting auto exposure. * Added platform interface methods for setting auto exposure. * Remove workspace files --- .../camera_platform_interface/CHANGELOG.md | 4 + .../lib/src/events/camera_event.dart | 24 ++- .../method_channel/method_channel_camera.dart | 59 ++++++ .../platform_interface/camera_platform.dart | 46 ++++- .../lib/src/types/exposure_mode.dart | 36 ++++ .../lib/src/types/types.dart | 1 + .../camera_platform_interface/pubspec.yaml | 2 +- .../test/camera_platform_interface_test.dart | 78 ++++++++ .../test/events/camera_event_test.dart | 67 +++++-- .../method_channel_camera_test.dart | 172 +++++++++++++++++- .../test/types/exposure_mode_test.dart | 32 ++++ 11 files changed, 494 insertions(+), 27 deletions(-) create mode 100644 packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart create mode 100644 packages/camera/camera_platform_interface/test/types/exposure_mode_test.dart diff --git a/packages/camera/camera_platform_interface/CHANGELOG.md b/packages/camera/camera_platform_interface/CHANGELOG.md index d117e1c0eba4..8e316054f2b1 100644 --- a/packages/camera/camera_platform_interface/CHANGELOG.md +++ b/packages/camera/camera_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.2.0 + +- Added interface to support automatic exposure. + ## 1.1.0 - Added an optional `maxVideoDuration` parameter to the `startVideoRecording` method, which allows implementations to limit the duration of a video recording. diff --git a/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart b/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart index ab3d45545f23..590713d04e8b 100644 --- a/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart +++ b/packages/camera/camera_platform_interface/lib/src/events/camera_event.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 '../../camera_platform_interface.dart'; + /// Generic Event coming from the native side of Camera. /// /// All [CameraEvent]s contain the `cameraId` that originated the event. This @@ -45,6 +47,12 @@ class CameraInitializedEvent extends CameraEvent { /// The height of the preview in pixels. final double previewHeight; + /// The default exposure mode + final ExposureMode exposureMode; + + /// Whether setting exposure points is supported. + final bool exposurePointSupported; + /// Build a CameraInitialized event triggered from the camera represented by /// `cameraId`. /// @@ -54,6 +62,8 @@ class CameraInitializedEvent extends CameraEvent { int cameraId, this.previewWidth, this.previewHeight, + this.exposureMode, + this.exposurePointSupported, ) : super(cameraId); /// Converts the supplied [Map] to an instance of the [CameraInitializedEvent] @@ -61,6 +71,8 @@ class CameraInitializedEvent extends CameraEvent { CameraInitializedEvent.fromJson(Map json) : previewWidth = json['previewWidth'], previewHeight = json['previewHeight'], + exposureMode = deserializeExposureMode(json['exposureMode']), + exposurePointSupported = json['exposurePointSupported'], super(json['cameraId']); /// Converts the [CameraInitializedEvent] instance into a [Map] instance that @@ -69,6 +81,8 @@ class CameraInitializedEvent extends CameraEvent { 'cameraId': cameraId, 'previewWidth': previewWidth, 'previewHeight': previewHeight, + 'exposureMode': serializeExposureMode(exposureMode), + 'exposurePointSupported': exposurePointSupported, }; @override @@ -78,11 +92,17 @@ class CameraInitializedEvent extends CameraEvent { other is CameraInitializedEvent && runtimeType == other.runtimeType && previewWidth == other.previewWidth && - previewHeight == other.previewHeight; + previewHeight == other.previewHeight && + exposureMode == other.exposureMode && + exposurePointSupported == other.exposurePointSupported; @override int get hashCode => - super.hashCode ^ previewWidth.hashCode ^ previewHeight.hashCode; + super.hashCode ^ + previewWidth.hashCode ^ + previewHeight.hashCode ^ + exposureMode.hashCode ^ + exposurePointSupported.hashCode; } /// An event fired when the resolution preset of the camera has changed. diff --git a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart index bf2b3d3bd70a..6a73031111df 100644 --- a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart +++ b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:math'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:camera_platform_interface/src/utils/utils.dart'; @@ -189,6 +190,62 @@ class MethodChannelCamera extends CameraPlatform { }, ); + @override + Future setExposureMode(int cameraId, ExposureMode mode) => + _channel.invokeMethod( + 'setExposureMode', + { + 'cameraId': cameraId, + 'mode': serializeExposureMode(mode), + }, + ); + + @override + Future setExposurePoint(int cameraId, Point point) { + assert(point == null || point.x >= 0 && point.x <= 1); + assert(point == null || point.y >= 0 && point.y <= 1); + return _channel.invokeMethod( + 'setExposurePoint', + { + 'cameraId': cameraId, + 'reset': point == null, + 'x': point?.x, + 'y': point?.y, + }, + ); + } + + @override + Future getMinExposureOffset(int cameraId) => + _channel.invokeMethod( + 'getMinExposureOffset', + {'cameraId': cameraId}, + ); + + @override + Future getMaxExposureOffset(int cameraId) => + _channel.invokeMethod( + 'getMaxExposureOffset', + {'cameraId': cameraId}, + ); + + @override + Future getExposureOffsetStepSize(int cameraId) => + _channel.invokeMethod( + 'getExposureOffsetStepSize', + {'cameraId': cameraId}, + ); + + @override + Future setExposureOffset(int cameraId, double offset) => + _channel.invokeMethod( + 'setExposureOffset', + { + 'cameraId': cameraId, + 'offset': offset, + }, + ); + @override Future getMaxZoomLevel(int cameraId) => _channel.invokeMethod( 'getMaxZoomLevel', @@ -269,6 +326,8 @@ class MethodChannelCamera extends CameraPlatform { cameraId, call.arguments['previewWidth'], call.arguments['previewHeight'], + deserializeExposureMode(call.arguments['exposureMode']), + call.arguments['exposurePointSupported'], )); break; case 'resolution_changed': diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart index 6c8e200c75c2..c7a603228ce2 100644 --- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart +++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart @@ -3,9 +3,11 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:math'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:camera_platform_interface/src/method_channel/method_channel_camera.dart'; +import 'package:camera_platform_interface/src/types/exposure_mode.dart'; import 'package:cross_file/cross_file.dart'; import 'package:flutter/widgets.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; @@ -116,6 +118,48 @@ abstract class CameraPlatform extends PlatformInterface { throw UnimplementedError('setFlashMode() is not implemented.'); } + /// Sets the exposure mode for taking pictures. + Future setExposureMode(int cameraId, ExposureMode mode) { + throw UnimplementedError('setExposureMode() is not implemented.'); + } + + /// Sets the exposure point for automatically determining the exposure value. + Future setExposurePoint(int cameraId, Point point) { + throw UnimplementedError('setExposurePoint() is not implemented.'); + } + + /// Gets the minimum supported exposure offset for the selected camera in EV units. + Future getMinExposureOffset(int cameraId) { + throw UnimplementedError('getMinExposureOffset() is not implemented.'); + } + + /// Gets the maximum supported exposure offset for the selected camera in EV units. + Future getMaxExposureOffset(int cameraId) { + throw UnimplementedError('getMaxExposureOffset() is not implemented.'); + } + + /// Gets the supported step size for exposure offset for the selected camera in EV units. + /// + /// Returns 0 when the camera supports using a free value without stepping. + Future getExposureOffsetStepSize(int cameraId) { + throw UnimplementedError('getMinExposureOffset() is not implemented.'); + } + + /// Sets the exposure offset for the selected camera. + /// + /// The supplied [offset] value should be in EV units. 1 EV unit represents a + /// doubling in brightness. It should be between the minimum and maximum offsets + /// obtained through `getMinExposureOffset` and `getMaxExposureOffset` respectively. + /// Throws a `CameraException` when an illegal offset is supplied. + /// + /// When the supplied [offset] value does not align with the step size obtained + /// through `getExposureStepSize`, it will automatically be rounded to the nearest step. + /// + /// Returns the (rounded) offset value that was set. + Future setExposureOffset(int cameraId, double offset) { + throw UnimplementedError('setExposureOffset() is not implemented.'); + } + /// Gets the maximum supported zoom level for the selected camera. Future getMaxZoomLevel(int cameraId) { throw UnimplementedError('getMaxZoomLevel() is not implemented.'); @@ -129,7 +173,7 @@ abstract class CameraPlatform extends PlatformInterface { /// Set the zoom level for the selected camera. /// /// The supplied [zoom] value should be between 1.0 and the maximum supported - /// zoom level returned by the `getMaxZoomLevel`. Throws an `CameraException` + /// zoom level returned by the `getMaxZoomLevel`. Throws a `CameraException` /// when an illegal zoom level is supplied. Future setZoomLevel(int cameraId, double zoom) { throw UnimplementedError('setZoomLevel() is not implemented.'); diff --git a/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart b/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart new file mode 100644 index 000000000000..836f53826479 --- /dev/null +++ b/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart @@ -0,0 +1,36 @@ +// Copyright 2019 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. + +/// The possible exposure modes that can be set for a camera. +enum ExposureMode { + /// Automatically determine exposure settings. + auto, + + /// Lock the currently determined exposure settings. + locked, +} + +/// Returns the exposure mode as a String. +String serializeExposureMode(ExposureMode exposureMode) { + switch (exposureMode) { + case ExposureMode.locked: + return 'locked'; + case ExposureMode.auto: + return 'auto'; + default: + throw ArgumentError('Unknown ExposureMode value'); + } +} + +/// Returns the exposure mode for a given String. +ExposureMode deserializeExposureMode(String str) { + switch (str) { + case "locked": + return ExposureMode.locked; + case "auto": + return ExposureMode.auto; + default: + throw ArgumentError('"$str" is not a valid ExposureMode value'); + } +} diff --git a/packages/camera/camera_platform_interface/lib/src/types/types.dart b/packages/camera/camera_platform_interface/lib/src/types/types.dart index 3a89a1021e95..bab430eb5a69 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/types.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/types.dart @@ -6,3 +6,4 @@ export 'camera_description.dart'; export 'resolution_preset.dart'; export 'camera_exception.dart'; export 'flash_mode.dart'; +export 'exposure_mode.dart'; diff --git a/packages/camera/camera_platform_interface/pubspec.yaml b/packages/camera/camera_platform_interface/pubspec.yaml index b6933314d41d..b8301d289cc6 100644 --- a/packages/camera/camera_platform_interface/pubspec.yaml +++ b/packages/camera/camera_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the camera plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.1.0 +version: 1.2.0 dependencies: flutter: diff --git a/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart b/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart index 7a6fc344503f..574fa45e7b81 100644 --- a/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart +++ b/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart @@ -186,6 +186,84 @@ void main() { ); }); + test( + 'Default implementation of setExposureMode() should throw unimplemented error', + () { + // Arrange + final cameraPlatform = ExtendsCameraPlatform(); + + // Act & Assert + expect( + () => cameraPlatform.setExposureMode(1, null), + throwsUnimplementedError, + ); + }); + + test( + 'Default implementation of setExposurePoint() should throw unimplemented error', + () { + // Arrange + final cameraPlatform = ExtendsCameraPlatform(); + + // Act & Assert + expect( + () => cameraPlatform.setExposurePoint(1, null), + throwsUnimplementedError, + ); + }); + + test( + 'Default implementation of getMinExposureOffset() should throw unimplemented error', + () { + // Arrange + final cameraPlatform = ExtendsCameraPlatform(); + + // Act & Assert + expect( + () => cameraPlatform.getMinExposureOffset(1), + throwsUnimplementedError, + ); + }); + + test( + 'Default implementation of getMaxExposureOffset() should throw unimplemented error', + () { + // Arrange + final cameraPlatform = ExtendsCameraPlatform(); + + // Act & Assert + expect( + () => cameraPlatform.getMaxExposureOffset(1), + throwsUnimplementedError, + ); + }); + + test( + 'Default implementation of getExposureOffsetStepSize() should throw unimplemented error', + () { + // Arrange + final cameraPlatform = ExtendsCameraPlatform(); + + // Act & Assert + expect( + () => cameraPlatform.getExposureOffsetStepSize(1), + throwsUnimplementedError, + ); + }); + + test( + 'Default implementation of setExposureOffset() should throw unimplemented error', + () { + // Arrange + final cameraPlatform = ExtendsCameraPlatform(); + + // Act & Assert + expect( + () => cameraPlatform.setExposureOffset(1, null), + throwsUnimplementedError, + ); + }); + test( 'Default implementation of startVideoRecording() should throw unimplemented error', () { diff --git a/packages/camera/camera_platform_interface/test/events/camera_event_test.dart b/packages/camera/camera_platform_interface/test/events/camera_event_test.dart index 01b03b8e93a0..1e28fa689383 100644 --- a/packages/camera/camera_platform_interface/test/events/camera_event_test.dart +++ b/packages/camera/camera_platform_interface/test/events/camera_event_test.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:camera_platform_interface/camera_platform_interface.dart'; +import 'package:camera_platform_interface/src/types/exposure_mode.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { @@ -10,11 +11,14 @@ void main() { group('CameraInitializedEvent tests', () { test('Constructor should initialize all properties', () { - final event = CameraInitializedEvent(1, 1024, 640); + final event = + CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); expect(event.cameraId, 1); expect(event.previewWidth, 1024); expect(event.previewHeight, 640); + expect(event.exposureMode, ExposureMode.auto); + expect(event.exposurePointSupported, true); }); test('fromJson should initialize all properties', () { @@ -22,57 +26,92 @@ void main() { 'cameraId': 1, 'previewWidth': 1024.0, 'previewHeight': 640.0, + 'exposureMode': 'auto' }); expect(event.cameraId, 1); expect(event.previewWidth, 1024); expect(event.previewHeight, 640); + expect(event.exposureMode, ExposureMode.auto); }); test('toJson should return a map with all fields', () { - final event = CameraInitializedEvent(1, 1024, 640); + final event = + CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); final jsonMap = event.toJson(); - expect(jsonMap.length, 3); + expect(jsonMap.length, 5); expect(jsonMap['cameraId'], 1); expect(jsonMap['previewWidth'], 1024); expect(jsonMap['previewHeight'], 640); + expect(jsonMap['exposureMode'], 'auto'); + expect(jsonMap['exposurePointSupported'], true); }); test('equals should return true if objects are the same', () { - final firstEvent = CameraInitializedEvent(1, 1024, 640); - final secondEvent = CameraInitializedEvent(1, 1024, 640); + final firstEvent = + CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); + final secondEvent = + CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); expect(firstEvent == secondEvent, true); }); test('equals should return false if cameraId is different', () { - final firstEvent = CameraInitializedEvent(1, 1024, 640); - final secondEvent = CameraInitializedEvent(2, 1024, 640); + final firstEvent = + CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); + final secondEvent = + CameraInitializedEvent(2, 1024, 640, ExposureMode.auto, true); expect(firstEvent == secondEvent, false); }); test('equals should return false if previewWidth is different', () { - final firstEvent = CameraInitializedEvent(1, 1024, 640); - final secondEvent = CameraInitializedEvent(1, 2048, 640); + final firstEvent = + CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); + final secondEvent = + CameraInitializedEvent(1, 2048, 640, ExposureMode.auto, true); expect(firstEvent == secondEvent, false); }); test('equals should return false if previewHeight is different', () { - final firstEvent = CameraInitializedEvent(1, 1024, 640); - final secondEvent = CameraInitializedEvent(1, 1024, 980); + final firstEvent = + CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); + final secondEvent = + CameraInitializedEvent(1, 1024, 980, ExposureMode.auto, true); + + expect(firstEvent == secondEvent, false); + }); + + test('equals should return false if exposureMode is different', () { + final firstEvent = + CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); + final secondEvent = + CameraInitializedEvent(1, 1024, 640, ExposureMode.locked, true); + + expect(firstEvent == secondEvent, false); + }); + + test('equals should return false if exposurePointSupported is different', + () { + final firstEvent = + CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); + final secondEvent = + CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, false); expect(firstEvent == secondEvent, false); }); test('hashCode should match hashCode of all properties', () { - final event = CameraInitializedEvent(1, 1024, 640); - final expectedHashCode = event.cameraId.hashCode ^ + final event = + CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); + final expectedHashCode = event.cameraId ^ event.previewWidth.hashCode ^ - event.previewHeight.hashCode; + event.previewHeight.hashCode ^ + event.exposureMode.hashCode ^ + event.exposurePointSupported.hashCode; expect(event.hashCode, expectedHashCode); }); diff --git a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart index 12f5d6e8ecf8..b916513ef0de 100644 --- a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart +++ b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:math'; import 'package:async/async.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; @@ -118,8 +119,13 @@ void main() { // Act Future initializeFuture = camera.initializeCamera(cameraId); - camera.cameraEventStreamController - .add(CameraInitializedEvent(cameraId, 1920, 1080)); + camera.cameraEventStreamController.add(CameraInitializedEvent( + cameraId, + 1920, + 1080, + ExposureMode.auto, + true, + )); await initializeFuture; // Assert @@ -151,8 +157,13 @@ void main() { ResolutionPreset.high, ); Future initializeFuture = camera.initializeCamera(cameraId); - camera.cameraEventStreamController - .add(CameraInitializedEvent(cameraId, 1920, 1080)); + camera.cameraEventStreamController.add(CameraInitializedEvent( + cameraId, + 1920, + 1080, + ExposureMode.auto, + true, + )); await initializeFuture; // Act @@ -188,8 +199,13 @@ void main() { ResolutionPreset.high, ); Future initializeFuture = camera.initializeCamera(cameraId); - camera.cameraEventStreamController - .add(CameraInitializedEvent(cameraId, 1920, 1080)); + camera.cameraEventStreamController.add(CameraInitializedEvent( + cameraId, + 1920, + 1080, + ExposureMode.auto, + true, + )); await initializeFuture; }); @@ -200,7 +216,13 @@ void main() { final streamQueue = StreamQueue(eventStream); // Emit test events - final event = CameraInitializedEvent(cameraId, 3840, 2160); + final event = CameraInitializedEvent( + cameraId, + 3840, + 2160, + ExposureMode.auto, + true, + ); await camera.handleMethodCall( MethodCall('initialized', event.toJson()), cameraId); @@ -304,8 +326,15 @@ void main() { ResolutionPreset.high, ); Future initializeFuture = camera.initializeCamera(cameraId); - camera.cameraEventStreamController - .add(CameraInitializedEvent(cameraId, 1920, 1080)); + camera.cameraEventStreamController.add( + CameraInitializedEvent( + cameraId, + 1920, + 1080, + ExposureMode.auto, + true, + ), + ); await initializeFuture; }); @@ -518,6 +547,131 @@ void main() { ]); }); + test('Should set the exposure mode', () async { + // Arrange + MethodChannelMock channel = MethodChannelMock( + channelName: 'plugins.flutter.io/camera', + methods: {'setExposureMode': null}, + ); + + // Act + await camera.setExposureMode(cameraId, ExposureMode.auto); + await camera.setExposureMode(cameraId, ExposureMode.locked); + + // Assert + expect(channel.log, [ + isMethodCall('setExposureMode', + arguments: {'cameraId': cameraId, 'mode': 'auto'}), + isMethodCall('setExposureMode', + arguments: {'cameraId': cameraId, 'mode': 'locked'}), + ]); + }); + + test('Should set the exposure point', () async { + // Arrange + MethodChannelMock channel = MethodChannelMock( + channelName: 'plugins.flutter.io/camera', + methods: {'setExposurePoint': null}, + ); + + // Act + await camera.setExposurePoint(cameraId, Point(0.5, 0.5)); + await camera.setExposurePoint(cameraId, null); + + // Assert + expect(channel.log, [ + isMethodCall('setExposurePoint', arguments: { + 'cameraId': cameraId, + 'x': 0.5, + 'y': 0.5, + 'reset': false + }), + isMethodCall('setExposurePoint', arguments: { + 'cameraId': cameraId, + 'x': null, + 'y': null, + 'reset': true + }), + ]); + }); + + test('Should get the min exposure offset', () async { + // Arrange + MethodChannelMock channel = MethodChannelMock( + channelName: 'plugins.flutter.io/camera', + methods: {'getMinExposureOffset': 2.0}, + ); + + // Act + final minExposureOffset = await camera.getMinExposureOffset(cameraId); + + // Assert + expect(minExposureOffset, 2.0); + expect(channel.log, [ + isMethodCall('getMinExposureOffset', arguments: { + 'cameraId': cameraId, + }), + ]); + }); + + test('Should get the max exposure offset', () async { + // Arrange + MethodChannelMock channel = MethodChannelMock( + channelName: 'plugins.flutter.io/camera', + methods: {'getMaxExposureOffset': 2.0}, + ); + + // Act + final maxExposureOffset = await camera.getMaxExposureOffset(cameraId); + + // Assert + expect(maxExposureOffset, 2.0); + expect(channel.log, [ + isMethodCall('getMaxExposureOffset', arguments: { + 'cameraId': cameraId, + }), + ]); + }); + + test('Should get the exposure offset step size', () async { + // Arrange + MethodChannelMock channel = MethodChannelMock( + channelName: 'plugins.flutter.io/camera', + methods: {'getExposureOffsetStepSize': 0.25}, + ); + + // Act + final stepSize = await camera.getExposureOffsetStepSize(cameraId); + + // Assert + expect(stepSize, 0.25); + expect(channel.log, [ + isMethodCall('getExposureOffsetStepSize', arguments: { + 'cameraId': cameraId, + }), + ]); + }); + + test('Should set the exposure offset', () async { + // Arrange + MethodChannelMock channel = MethodChannelMock( + channelName: 'plugins.flutter.io/camera', + methods: {'setExposureOffset': 0.6}, + ); + + // Act + final actualOffset = await camera.setExposureOffset(cameraId, 0.5); + + // Assert + expect(actualOffset, 0.6); + expect(channel.log, [ + isMethodCall('setExposureOffset', arguments: { + 'cameraId': cameraId, + 'offset': 0.5, + }), + ]); + }); + test('Should build a texture widget as preview widget', () async { // Act Widget widget = camera.buildPreview(cameraId); diff --git a/packages/camera/camera_platform_interface/test/types/exposure_mode_test.dart b/packages/camera/camera_platform_interface/test/types/exposure_mode_test.dart new file mode 100644 index 000000000000..c34c1d7b4157 --- /dev/null +++ b/packages/camera/camera_platform_interface/test/types/exposure_mode_test.dart @@ -0,0 +1,32 @@ +// Copyright 2019 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. + +import 'package:camera_platform_interface/camera_platform_interface.dart'; +import 'package:camera_platform_interface/src/types/exposure_mode.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + test('ExposureMode should contain 2 options', () { + final values = ExposureMode.values; + + expect(values.length, 2); + }); + + test("ExposureMode enum should have items in correct index", () { + final values = ExposureMode.values; + + expect(values[0], ExposureMode.auto); + expect(values[1], ExposureMode.locked); + }); + + test("serializeExposureMode() should serialize correctly", () { + expect(serializeExposureMode(ExposureMode.auto), "auto"); + expect(serializeExposureMode(ExposureMode.locked), "locked"); + }); + + test("deserializeExposureMode() should deserialize correctly", () { + expect(deserializeExposureMode('auto'), ExposureMode.auto); + expect(deserializeExposureMode('locked'), ExposureMode.locked); + }); +} From 65d041fd9adce6d350e7c063fd6a8a2e13d478f0 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Tue, 29 Dec 2020 02:29:03 +0100 Subject: [PATCH 0011/1565] Update camera_platform_interface to 1.2.0 (#3376) --- packages/camera/camera/CHANGELOG.md | 4 ++++ packages/camera/camera/pubspec.yaml | 4 ++-- packages/camera/camera/test/camera_test.dart | 6 ++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 461b2d927eda..9a5fe7c209af 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.3+3 + +* Updated dependency on camera_platform_interface to ^1.2.0. + ## 0.6.3+2 * Fixes crash on Android which occurs after video recording has stopped just before taking a picture. diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 1f5d06eecbe3..2a32734485d4 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,13 +2,13 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.6.3+2 +version: 0.6.3+3 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: flutter: sdk: flutter - camera_platform_interface: ^1.0.4 + camera_platform_interface: ^1.2.0 dev_dependencies: path_provider: ^0.5.0 diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index 43dec7374901..0029e56bf566 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -26,7 +26,8 @@ get mockAvailableCameras => [ get mockInitializeCamera => 13; -get mockOnCameraInitializedEvent => CameraInitializedEvent(13, 75, 75); +get mockOnCameraInitializedEvent => + CameraInitializedEvent(13, 75, 75, ExposureMode.auto, false); get mockOnCameraClosingEvent => null; @@ -641,7 +642,8 @@ class MockCameraPlatform extends Mock : Future.value(mockTakePicture); @override - Future startVideoRecording(int cameraId) => + Future startVideoRecording(int cameraId, + {Duration maxVideoDuration}) => Future.value(mockVideoRecordingXFile); } From 72cc8e2197733c73c9974205b2c473982f4e0b78 Mon Sep 17 00:00:00 2001 From: Bodhi Mulders Date: Tue, 29 Dec 2020 15:04:03 +0100 Subject: [PATCH 0012/1565] Change platform interface dependency (#3377) --- packages/camera/camera/CHANGELOG.md | 4 ++++ packages/camera/camera/pubspec.yaml | 4 ++-- packages/camera/camera/test/camera_test.dart | 6 ++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 9a5fe7c209af..df543c74efcf 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.3+4 + +* Revert previous dependency update: Changed dependency on camera_platform_interface to >=1.04 <1.1.0. + ## 0.6.3+3 * Updated dependency on camera_platform_interface to ^1.2.0. diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 2a32734485d4..fa40ad03ae89 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,13 +2,13 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.6.3+3 +version: 0.6.3+4 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: flutter: sdk: flutter - camera_platform_interface: ^1.2.0 + camera_platform_interface: ">=1.0.4 <1.1.0" dev_dependencies: path_provider: ^0.5.0 diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index 0029e56bf566..43dec7374901 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -26,8 +26,7 @@ get mockAvailableCameras => [ get mockInitializeCamera => 13; -get mockOnCameraInitializedEvent => - CameraInitializedEvent(13, 75, 75, ExposureMode.auto, false); +get mockOnCameraInitializedEvent => CameraInitializedEvent(13, 75, 75); get mockOnCameraClosingEvent => null; @@ -642,8 +641,7 @@ class MockCameraPlatform extends Mock : Future.value(mockTakePicture); @override - Future startVideoRecording(int cameraId, - {Duration maxVideoDuration}) => + Future startVideoRecording(int cameraId) => Future.value(mockVideoRecordingXFile); } From 96e2328fe6338f429da4dec18998dce42e837d8b Mon Sep 17 00:00:00 2001 From: Bodhi Mulders Date: Wed, 30 Dec 2020 20:35:55 +0100 Subject: [PATCH 0013/1565] [camera] Add iOS and Android implementations for managing auto exposure. (#3346) * Added platform interface methods for setting auto exposure. * Added platform interface methods for setting auto exposure. * Remove workspace files * Added auto exposure implementations for Android and iOS * iOS fix for setting the exposure point * Removed unnecessary check * Update platform interface dependency * Implement PR feedback * Restore test * Small improvements for exposure point resetting --- packages/camera/camera/CHANGELOG.md | 4 + .../io/flutter/plugins/camera/Camera.java | 175 +++++++- .../flutter/plugins/camera/CameraRegions.java | 59 +++ .../flutter/plugins/camera/DartMessenger.java | 17 +- .../plugins/camera/MethodCallHandlerImpl.java | 68 +++ .../plugins/camera/types/ExposureMode.java | 25 ++ .../plugins/camera/types/FlashMode.java | 26 +- .../plugins/camera/CameraRegionsTest.java | 105 +++++ .../plugins/camera/DartMessengerTest.java | 5 +- .../camera/types/ExposureModeTest.java | 33 ++ .../plugins/camera/types/FlashModeTest.java | 8 + packages/camera/camera/example/lib/main.dart | 316 +++++++++++--- .../camera/camera/ios/Classes/CameraPlugin.m | 121 +++++- packages/camera/camera/lib/camera.dart | 1 + .../camera/lib/src/camera_controller.dart | 176 +++++++- packages/camera/camera/pubspec.yaml | 6 +- packages/camera/camera/test/camera_test.dart | 399 +++++++++++++++++- .../camera/camera/test/camera_value_test.dart | 30 +- 18 files changed, 1453 insertions(+), 121 deletions(-) create mode 100644 packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegions.java create mode 100644 packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ExposureMode.java create mode 100644 packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionsTest.java create mode 100644 packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/ExposureModeTest.java diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index df543c74efcf..f576ee524ca1 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.4 + +* Adds auto exposure support for Android and iOS implementations. + ## 0.6.3+4 * Revert previous dependency update: Changed dependency on camera_platform_interface to >=1.04 <1.1.0. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 3c28d6655e48..d57a737c09f6 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -21,6 +21,7 @@ import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.CaptureResult; import android.hardware.camera2.TotalCaptureResult; +import android.hardware.camera2.params.MeteringRectangle; import android.hardware.camera2.params.OutputConfiguration; import android.hardware.camera2.params.SessionConfiguration; import android.media.CamcorderProfile; @@ -32,6 +33,8 @@ import android.os.Build.VERSION_CODES; import android.os.Handler; import android.os.Looper; +import android.util.Range; +import android.util.Rational; import android.util.Size; import android.view.OrientationEventListener; import android.view.Surface; @@ -40,6 +43,7 @@ import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugins.camera.PictureCaptureRequest.State; import io.flutter.plugins.camera.media.MediaRecorderBuilder; +import io.flutter.plugins.camera.types.ExposureMode; import io.flutter.plugins.camera.types.FlashMode; import io.flutter.plugins.camera.types.ResolutionPreset; import io.flutter.view.TextureRegistry.SurfaceTextureEntry; @@ -80,7 +84,10 @@ public class Camera { private File videoRecordingFile; private int currentOrientation = ORIENTATION_UNKNOWN; private FlashMode flashMode; + private ExposureMode exposureMode; private PictureCaptureRequest pictureCaptureRequest; + private CameraRegions cameraRegions; + private int exposureOffset; public Camera( final Activity activity, @@ -100,6 +107,8 @@ public Camera( this.cameraManager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE); this.applicationContext = activity.getApplicationContext(); this.flashMode = FlashMode.auto; + this.exposureMode = ExposureMode.auto; + this.exposureOffset = 0; orientationEventListener = new OrientationEventListener(activity.getApplicationContext()) { @Override @@ -158,15 +167,17 @@ public void open() throws CameraAccessException { public void onOpened(@NonNull CameraDevice device) { cameraDevice = device; try { + cameraRegions = new CameraRegions(getRegionBoundaries()); startPreview(); + dartMessenger.sendCameraInitializedEvent( + previewSize.getWidth(), + previewSize.getHeight(), + exposureMode, + isExposurePointSupported()); } catch (CameraAccessException e) { dartMessenger.sendCameraErrorEvent(e.getMessage()); close(); - return; } - - dartMessenger.sendCameraInitializedEvent( - previewSize.getWidth(), previewSize.getHeight()); } @Override @@ -605,16 +616,11 @@ public void resumeVideoRecording(@NonNull final Result result) { public void setFlashMode(@NonNull final Result result, FlashMode mode) throws CameraAccessException { // Get the flash availability - Boolean flashAvailable; - try { - flashAvailable = - cameraManager - .getCameraCharacteristics(cameraDevice.getId()) - .get(CameraCharacteristics.FLASH_INFO_AVAILABLE); - } catch (CameraAccessException e) { - result.error("setFlashModeFailed", e.getMessage(), null); - return; - } + Boolean flashAvailable = + cameraManager + .getCameraCharacteristics(cameraDevice.getId()) + .get(CameraCharacteristics.FLASH_INFO_AVAILABLE); + // Check if flash is available. if (flashAvailable == null || !flashAvailable) { result.error("setFlashModeFailed", "Device does not have flash capabilities", null); @@ -676,8 +682,133 @@ private void updateFlash(FlashMode mode) { } } + public void setExposureMode(@NonNull final Result result, ExposureMode mode) + throws CameraAccessException { + this.exposureMode = mode; + initPreviewCaptureBuilder(); + cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); + result.success(null); + } + + public void setExposurePoint(@NonNull final Result result, Double x, Double y) + throws CameraAccessException { + // Check if exposure point functionality is available. + if (!isExposurePointSupported()) { + result.error( + "setExposurePointFailed", "Device does not have exposure point capabilities", null); + return; + } + // Check if we are doing a reset or not + if (x == null || y == null) { + x = 0.5; + y = 0.5; + } + // Get the current region boundaries. + Size maxBoundaries = getRegionBoundaries(); + if (maxBoundaries == null) { + result.error("setExposurePointFailed", "Could not determine max region boundaries", null); + return; + } + // Set the metering rectangle + cameraRegions.setAutoExposureMeteringRectangleFromPoint(x, y); + // Apply it + initPreviewCaptureBuilder(); + this.cameraCaptureSession.setRepeatingRequest( + captureRequestBuilder.build(), pictureCaptureCallback, null); + result.success(null); + } + + @TargetApi(VERSION_CODES.P) + private boolean supportsDistortionCorrection() throws CameraAccessException { + int[] availableDistortionCorrectionModes = + cameraManager + .getCameraCharacteristics(cameraDevice.getId()) + .get(CameraCharacteristics.DISTORTION_CORRECTION_AVAILABLE_MODES); + if (availableDistortionCorrectionModes == null) availableDistortionCorrectionModes = new int[0]; + long nonOffModesSupported = + Arrays.stream(availableDistortionCorrectionModes) + .filter((value) -> value != CaptureRequest.DISTORTION_CORRECTION_MODE_OFF) + .count(); + return nonOffModesSupported > 0; + } + + private Size getRegionBoundaries() throws CameraAccessException { + // No distortion correction support + if (android.os.Build.VERSION.SDK_INT < VERSION_CODES.P || !supportsDistortionCorrection()) { + return cameraManager + .getCameraCharacteristics(cameraDevice.getId()) + .get(CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE); + } + // Get the current distortion correction mode + Integer distortionCorrectionMode = + captureRequestBuilder.get(CaptureRequest.DISTORTION_CORRECTION_MODE); + // Return the correct boundaries depending on the mode + android.graphics.Rect rect; + if (distortionCorrectionMode == null + || distortionCorrectionMode == CaptureRequest.DISTORTION_CORRECTION_MODE_OFF) { + rect = + cameraManager + .getCameraCharacteristics(cameraDevice.getId()) + .get(CameraCharacteristics.SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE); + } else { + rect = + cameraManager + .getCameraCharacteristics(cameraDevice.getId()) + .get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE); + } + return rect == null ? null : new Size(rect.width(), rect.height()); + } + + private boolean isExposurePointSupported() throws CameraAccessException { + Integer supportedRegions = + cameraManager + .getCameraCharacteristics(cameraDevice.getId()) + .get(CameraCharacteristics.CONTROL_MAX_REGIONS_AE); + return supportedRegions != null && supportedRegions > 0; + } + + public double getMinExposureOffset() throws CameraAccessException { + Range range = + cameraManager + .getCameraCharacteristics(cameraDevice.getId()) + .get(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE); + double minStepped = range == null ? 0 : range.getLower(); + double stepSize = getExposureOffsetStepSize(); + return minStepped * stepSize; + } + + public double getMaxExposureOffset() throws CameraAccessException { + Range range = + cameraManager + .getCameraCharacteristics(cameraDevice.getId()) + .get(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE); + double maxStepped = range == null ? 0 : range.getUpper(); + double stepSize = getExposureOffsetStepSize(); + return maxStepped * stepSize; + } + + public double getExposureOffsetStepSize() throws CameraAccessException { + Rational stepSize = + cameraManager + .getCameraCharacteristics(cameraDevice.getId()) + .get(CameraCharacteristics.CONTROL_AE_COMPENSATION_STEP); + return stepSize == null ? 0.0 : stepSize.doubleValue(); + } + + public void setExposureOffset(@NonNull final Result result, double offset) + throws CameraAccessException { + // Set the exposure offset + double stepSize = getExposureOffsetStepSize(); + exposureOffset = (int) (offset / stepSize); + // Apply it + initPreviewCaptureBuilder(); + this.cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); + result.success(offset); + } + private void initPreviewCaptureBuilder() { captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO); + // Applying flash modes switch (flashMode) { case off: captureRequestBuilder.set( @@ -701,6 +832,22 @@ private void initPreviewCaptureBuilder() { captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH); break; } + // Applying auto exposure + MeteringRectangle aeRect = cameraRegions.getAEMeteringRectangle(); + captureRequestBuilder.set( + CaptureRequest.CONTROL_AE_REGIONS, + aeRect == null ? null : new MeteringRectangle[] {cameraRegions.getAEMeteringRectangle()}); + switch (exposureMode) { + case locked: + captureRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true); + break; + case auto: + default: + captureRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false); + break; + } + captureRequestBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, exposureOffset); + // Applying auto focus captureRequestBuilder.set( CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); } diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegions.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegions.java new file mode 100644 index 000000000000..2285f67ad25c --- /dev/null +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegions.java @@ -0,0 +1,59 @@ +package io.flutter.plugins.camera; + +import android.hardware.camera2.params.MeteringRectangle; +import android.util.Size; + +public final class CameraRegions { + private MeteringRectangle aeMeteringRectangle; + private Size maxBoundaries; + + public CameraRegions(Size maxBoundaries) { + assert (maxBoundaries == null || maxBoundaries.getWidth() > 0); + assert (maxBoundaries == null || maxBoundaries.getHeight() > 0); + this.maxBoundaries = maxBoundaries; + } + + public MeteringRectangle getAEMeteringRectangle() { + return aeMeteringRectangle; + } + + public Size getMaxBoundaries() { + return this.maxBoundaries; + } + + public void resetAutoExposureMeteringRectangle() { + this.aeMeteringRectangle = null; + } + + public void setAutoExposureMeteringRectangleFromPoint(double x, double y) { + this.aeMeteringRectangle = getMeteringRectangleForPoint(maxBoundaries, x, y); + } + + public MeteringRectangle getMeteringRectangleForPoint(Size maxBoundaries, double x, double y) { + assert (x >= 0 && x <= 1); + assert (y >= 0 && y <= 1); + if (maxBoundaries == null) + throw new IllegalStateException( + "Functionality for managing metering rectangles is unavailable as this CameraRegions instance was initialized with null boundaries."); + + // Interpolate the target coordinate + int targetX = (int) Math.round(x * ((double) (maxBoundaries.getWidth() - 1))); + int targetY = (int) Math.round(y * ((double) (maxBoundaries.getHeight() - 1))); + // Determine the dimensions of the metering triangle (10th of the viewport) + int targetWidth = (int) Math.round(((double) maxBoundaries.getWidth()) / 10d); + int targetHeight = (int) Math.round(((double) maxBoundaries.getHeight()) / 10d); + // Adjust target coordinate to represent top-left corner of metering rectangle + targetX -= targetWidth / 2; + targetY -= targetHeight / 2; + // Adjust target coordinate as to not fall out of bounds + if (targetX < 0) targetX = 0; + if (targetY < 0) targetY = 0; + int maxTargetX = maxBoundaries.getWidth() - 1 - targetWidth; + int maxTargetY = maxBoundaries.getHeight() - 1 - targetHeight; + if (targetX > maxTargetX) targetX = maxTargetX; + if (targetY > maxTargetY) targetY = maxTargetY; + + // Build the metering rectangle + return new MeteringRectangle(targetX, targetY, targetWidth, targetHeight, 1); + } +} diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java index 49f9d9a76de0..2fee13816b51 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java @@ -4,6 +4,7 @@ import androidx.annotation.Nullable; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugins.camera.types.ExposureMode; import java.util.HashMap; import java.util.Map; @@ -20,13 +21,23 @@ enum EventType { channel = new MethodChannel(messenger, "flutter.io/cameraPlugin/camera" + cameraId); } - void sendCameraInitializedEvent(Integer previewWidth, Integer previewHeight) { + void sendCameraInitializedEvent( + Integer previewWidth, + Integer previewHeight, + ExposureMode exposureMode, + Boolean exposurePointSupported) { + assert (previewWidth != null); + assert (previewHeight != null); + assert (exposureMode != null); + assert (exposurePointSupported != null); this.send( EventType.INITIALIZED, new HashMap() { { - if (previewWidth != null) put("previewWidth", previewWidth.doubleValue()); - if (previewHeight != null) put("previewHeight", previewHeight.doubleValue()); + put("previewWidth", previewWidth.doubleValue()); + put("previewHeight", previewHeight.doubleValue()); + put("exposureMode", exposureMode.toString()); + put("exposurePointSupported", exposurePointSupported); } }); } diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java index 704504176518..78a10010f90b 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java @@ -10,6 +10,7 @@ import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugins.camera.CameraPermissions.PermissionsRegistry; +import io.flutter.plugins.camera.types.ExposureMode; import io.flutter.plugins.camera.types.FlashMode; import io.flutter.view.TextureRegistry; import java.util.HashMap; @@ -138,6 +139,73 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) } break; } + case "setExposureMode": + { + String modeStr = call.argument("mode"); + ExposureMode mode = ExposureMode.getValueForString(modeStr); + if (mode == null) { + result.error("setExposureModeFailed", "Unknown exposure mode " + modeStr, null); + return; + } + try { + camera.setExposureMode(result, mode); + } catch (Exception e) { + handleException(e, result); + } + break; + } + case "setExposurePoint": + { + Boolean reset = call.argument("reset"); + Double x = null; + Double y = null; + if (reset == null || !reset) { + x = call.argument("x"); + y = call.argument("y"); + } + try { + camera.setExposurePoint(result, x, y); + } catch (Exception e) { + handleException(e, result); + } + break; + } + case "getMinExposureOffset": + { + try { + result.success(camera.getMinExposureOffset()); + } catch (Exception e) { + handleException(e, result); + } + break; + } + case "getMaxExposureOffset": + { + try { + result.success(camera.getMaxExposureOffset()); + } catch (Exception e) { + handleException(e, result); + } + break; + } + case "getExposureOffsetStepSize": + { + try { + result.success(camera.getExposureOffsetStepSize()); + } catch (Exception e) { + handleException(e, result); + } + break; + } + case "setExposureOffset": + { + try { + camera.setExposureOffset(result, call.argument("offset")); + } catch (Exception e) { + handleException(e, result); + } + break; + } case "startImageStream": { try { diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ExposureMode.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ExposureMode.java new file mode 100644 index 000000000000..8066f59d2b14 --- /dev/null +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ExposureMode.java @@ -0,0 +1,25 @@ +package io.flutter.plugins.camera.types; + +// Mirrors exposure_mode.dart +public enum ExposureMode { + auto("auto"), + locked("locked"); + + private final String strValue; + + ExposureMode(String strValue) { + this.strValue = strValue; + } + + public static ExposureMode getValueForString(String modeStr) { + for (ExposureMode value : values()) { + if (value.strValue.equals(modeStr)) return value; + } + return null; + } + + @Override + public String toString() { + return strValue; + } +} diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java index 99d4915b3a6a..ee6fe489511f 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java @@ -2,16 +2,26 @@ // Mirrors flash_mode.dart public enum FlashMode { - off, - auto, - always, - torch; + off("off"), + auto("auto"), + always("always"), + torch("torch"); + + private final String strValue; + + FlashMode(String strValue) { + this.strValue = strValue; + } public static FlashMode getValueForString(String modeStr) { - try { - return valueOf(modeStr); - } catch (IllegalArgumentException | NullPointerException e) { - return null; + for (FlashMode value : values()) { + if (value.strValue.equals(modeStr)) return value; } + return null; + } + + @Override + public String toString() { + return strValue; } } diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionsTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionsTest.java new file mode 100644 index 000000000000..ca66918e2493 --- /dev/null +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionsTest.java @@ -0,0 +1,105 @@ +package io.flutter.plugins.camera; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import android.hardware.camera2.params.MeteringRectangle; +import android.util.Size; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +@RunWith(RobolectricTestRunner.class) +public class CameraRegionsTest { + + CameraRegions cameraRegions; + + @Before + public void setUp() { + this.cameraRegions = new CameraRegions(new Size(100, 50)); + } + + @Test(expected = AssertionError.class) + public void getMeteringRectangleForPoint_should_throw_for_x_upper_bound() { + cameraRegions.getMeteringRectangleForPoint(new Size(10, 10), 1.5, 0); + } + + @Test(expected = AssertionError.class) + public void getMeteringRectangleForPoint_should_throw_for_x_lower_bound() { + cameraRegions.getMeteringRectangleForPoint(new Size(10, 10), -0.5, 0); + } + + @Test(expected = AssertionError.class) + public void getMeteringRectangleForPoint_should_throw_for_y_upper_bound() { + cameraRegions.getMeteringRectangleForPoint(new Size(10, 10), 0, 1.5); + } + + @Test(expected = AssertionError.class) + public void getMeteringRectangleForPoint_should_throw_for_y_lower_bound() { + cameraRegions.getMeteringRectangleForPoint(new Size(10, 10), 0, -0.5); + } + + @Test(expected = IllegalStateException.class) + public void getMeteringRectangleForPoint_should_throw_for_null_boundaries() { + cameraRegions.getMeteringRectangleForPoint(null, 0, -0); + } + + @Test + public void getMeteringRectangleForPoint_should_return_valid_MeteringRectangle() { + MeteringRectangle r; + // Center + r = cameraRegions.getMeteringRectangleForPoint(cameraRegions.getMaxBoundaries(), 0.5, 0.5); + assertEquals(new MeteringRectangle(45, 23, 10, 5, 1), r); + + // Top left + r = cameraRegions.getMeteringRectangleForPoint(cameraRegions.getMaxBoundaries(), 0.0, 0.0); + assertEquals(new MeteringRectangle(0, 0, 10, 5, 1), r); + + // Bottom right + r = cameraRegions.getMeteringRectangleForPoint(cameraRegions.getMaxBoundaries(), 1.0, 1.0); + assertEquals(new MeteringRectangle(89, 44, 10, 5, 1), r); + + // Top left + r = cameraRegions.getMeteringRectangleForPoint(cameraRegions.getMaxBoundaries(), 0.0, 1.0); + assertEquals(new MeteringRectangle(0, 44, 10, 5, 1), r); + + // Top right + r = cameraRegions.getMeteringRectangleForPoint(cameraRegions.getMaxBoundaries(), 1.0, 0.0); + assertEquals(new MeteringRectangle(89, 0, 10, 5, 1), r); + } + + @Test(expected = AssertionError.class) + public void constructor_should_throw_for_0_width_boundary() { + new CameraRegions(new Size(0, 50)); + } + + @Test(expected = AssertionError.class) + public void constructor_should_throw_for_0_height_boundary() { + new CameraRegions(new Size(100, 0)); + } + + @Test + public void constructor_should_initialize() { + CameraRegions cr = new CameraRegions(new Size(100, 50)); + assertEquals(new Size(100, 50), cr.getMaxBoundaries()); + assertNull(cr.getAEMeteringRectangle()); + } + + @Test + public void setAutoExposureMeteringRectangleFromPoint_should_set_aeMeteringRectangle_for_point() { + CameraRegions cr = new CameraRegions(new Size(100, 50)); + cr.setAutoExposureMeteringRectangleFromPoint(0, 0); + assertEquals(new MeteringRectangle(0, 0, 10, 5, 1), cr.getAEMeteringRectangle()); + } + + @Test + public void resetAutoExposureMeteringRectangle_should_reset_aeMeteringRectangle() { + CameraRegions cr = new CameraRegions(new Size(100, 50)); + cr.setAutoExposureMeteringRectangleFromPoint(0, 0); + assertNotNull(cr.getAEMeteringRectangle()); + cr.resetAutoExposureMeteringRectangle(); + assertNull(cr.getAEMeteringRectangle()); + } +} diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java index a689f2b6128f..f91bf82c7063 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java @@ -7,6 +7,7 @@ import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.StandardMethodCodec; +import io.flutter.plugins.camera.types.ExposureMode; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; @@ -58,7 +59,7 @@ public void sendCameraErrorEvent_includesErrorDescriptions() { @Test public void sendCameraInitializedEvent_includesPreviewSize() { - dartMessenger.sendCameraInitializedEvent(0, 0); + dartMessenger.sendCameraInitializedEvent(0, 0, ExposureMode.auto, true); List sentMessages = fakeBinaryMessenger.getMessages(); assertEquals(1, sentMessages.size()); @@ -66,6 +67,8 @@ public void sendCameraInitializedEvent_includesPreviewSize() { assertEquals("initialized", call.method); assertEquals(0, (double) call.argument("previewWidth"), 0); assertEquals(0, (double) call.argument("previewHeight"), 0); + assertEquals("ExposureMode auto", call.argument("exposureMode"), "auto"); + assertEquals("exposurePointSupported", call.argument("exposurePointSupported"), true); } @Test diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/ExposureModeTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/ExposureModeTest.java new file mode 100644 index 000000000000..28d2343cedcd --- /dev/null +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/ExposureModeTest.java @@ -0,0 +1,33 @@ +package io.flutter.plugins.camera.types; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class ExposureModeTest { + + @Test + public void getValueForString_returns_correct_values() { + assertEquals( + "Returns ExposureMode.auto for 'auto'", + ExposureMode.getValueForString("auto"), + ExposureMode.auto); + assertEquals( + "Returns ExposureMode.locked for 'locked'", + ExposureMode.getValueForString("locked"), + ExposureMode.locked); + } + + @Test + public void getValueForString_returns_null_for_nonexistant_value() { + assertEquals( + "Returns null for 'nonexistant'", ExposureMode.getValueForString("nonexistant"), null); + } + + @Test + public void toString_returns_correct_value() { + assertEquals("Returns 'auto' for ExposureMode.auto", ExposureMode.auto.toString(), "auto"); + assertEquals( + "Returns 'locked' for ExposureMode.locked", ExposureMode.locked.toString(), "locked"); + } +} diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java index d2674e8c7e06..bba01836545a 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java @@ -27,4 +27,12 @@ public void getValueForString_returns_null_for_nonexistant_value() { assertEquals( "Returns null for 'nonexistant'", FlashMode.getValueForString("nonexistant"), null); } + + @Test + public void toString_returns_correct_value() { + assertEquals("Returns 'off' for FlashMode.off", FlashMode.off.toString(), "off"); + assertEquals("Returns 'auto' for FlashMode.auto", FlashMode.auto.toString(), "auto"); + assertEquals("Returns 'always' for FlashMode.always", FlashMode.always.toString(), "always"); + assertEquals("Returns 'torch' for FlashMode.torch", FlashMode.torch.toString(), "torch"); + } } diff --git a/packages/camera/camera/example/lib/main.dart b/packages/camera/camera/example/lib/main.dart index ee8e2c259b3d..c4fa1c5ed01e 100644 --- a/packages/camera/camera/example/lib/main.dart +++ b/packages/camera/camera/example/lib/main.dart @@ -35,13 +35,20 @@ void logError(String code, String message) => print('Error: $code\nError Message: $message'); class _CameraExampleHomeState extends State - with WidgetsBindingObserver { + with WidgetsBindingObserver, TickerProviderStateMixin { CameraController controller; XFile imageFile; XFile videoFile; VideoPlayerController videoController; VoidCallback videoPlayerListener; bool enableAudio = true; + double _minAvailableExposureOffset = 0.0; + double _maxAvailableExposureOffset = 0.0; + double _currentExposureOffset = 0.0; + AnimationController _flashModeControlRowAnimationController; + Animation _flashModeControlRowAnimation; + AnimationController _exposureModeControlRowAnimationController; + Animation _exposureModeControlRowAnimation; double _minAvailableZoom; double _maxAvailableZoom; double _currentScale = 1.0; @@ -54,11 +61,29 @@ class _CameraExampleHomeState extends State void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); + _flashModeControlRowAnimationController = AnimationController( + duration: const Duration(milliseconds: 300), + vsync: this, + ); + _flashModeControlRowAnimation = CurvedAnimation( + parent: _flashModeControlRowAnimationController, + curve: Curves.easeInCubic, + ); + _exposureModeControlRowAnimationController = AnimationController( + duration: const Duration(milliseconds: 300), + vsync: this, + ); + _exposureModeControlRowAnimation = CurvedAnimation( + parent: _exposureModeControlRowAnimationController, + curve: Curves.easeInCubic, + ); } @override void dispose() { WidgetsBinding.instance.removeObserver(this); + _flashModeControlRowAnimationController.dispose(); + _exposureModeControlRowAnimationController.dispose(); super.dispose(); } @@ -108,8 +133,7 @@ class _CameraExampleHomeState extends State ), ), _captureControlRowWidget(), - _flashModeRowWidget(), - _toggleAudioWidget(), + _modeControlRowWidget(), Padding( padding: const EdgeInsets.all(5.0), child: Row( @@ -142,11 +166,15 @@ class _CameraExampleHomeState extends State child: Listener( onPointerDown: (_) => _pointers++, onPointerUp: (_) => _pointers--, - child: GestureDetector( - onScaleStart: _handleScaleStart, - onScaleUpdate: _handleScaleUpdate, - child: CameraPreview(controller), - ), + child: LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { + return GestureDetector( + onScaleStart: _handleScaleStart, + onScaleUpdate: _handleScaleUpdate, + onTapDown: (details) => onViewFinderTap(details, constraints), + child: CameraPreview(controller), + ); + }), ), ); } @@ -168,27 +196,6 @@ class _CameraExampleHomeState extends State await controller.setZoomLevel(_currentScale); } - /// Toggle recording audio - Widget _toggleAudioWidget() { - return Padding( - padding: const EdgeInsets.only(left: 25), - child: Row( - children: [ - const Text('Enable Audio:'), - Switch( - value: enableAudio, - onChanged: (bool value) { - enableAudio = value; - if (controller != null) { - onNewCameraSelected(controller.description); - } - }, - ), - ], - ), - ); - } - /// Display the thumbnail of the captured image or video. Widget _thumbnailWidget() { return Expanded( @@ -223,49 +230,156 @@ class _CameraExampleHomeState extends State ); } - /// Display a bar with buttons to change the flash mode - Widget _flashModeRowWidget() { - return Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - mainAxisSize: MainAxisSize.max, - children: [ - IconButton( - icon: const Icon(Icons.flash_off), - color: controller?.value?.flashMode == FlashMode.off - ? Colors.orange - : Colors.blue, - onPressed: controller != null - ? () => onFlashModeButtonPressed(FlashMode.off) - : null, - ), - IconButton( - icon: const Icon(Icons.flash_auto), - color: controller?.value?.flashMode == FlashMode.auto - ? Colors.orange - : Colors.blue, - onPressed: controller != null - ? () => onFlashModeButtonPressed(FlashMode.auto) - : null, + /// Display a bar with buttons to change the flash and exposure modes + Widget _modeControlRowWidget() { + return Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisSize: MainAxisSize.max, + children: [ + IconButton( + icon: Icon(Icons.flash_on), + color: Colors.blue, + onPressed: controller != null ? onFlashModeButtonPressed : null, + ), + IconButton( + icon: Icon(Icons.exposure), + color: Colors.blue, + onPressed: + controller != null ? onExposureModeButtonPressed : null, + ), + IconButton( + icon: Icon(enableAudio ? Icons.volume_up : Icons.volume_mute), + color: Colors.blue, + onPressed: controller != null ? onAudioModeButtonPressed : null, + ), + ], ), - IconButton( - icon: const Icon(Icons.flash_on), - color: controller?.value?.flashMode == FlashMode.always - ? Colors.orange - : Colors.blue, - onPressed: controller != null - ? () => onFlashModeButtonPressed(FlashMode.always) - : null, + _flashModeControlRowWidget(), + _exposureModeControlRowWidget(), + ], + ); + } + + Widget _flashModeControlRowWidget() { + return SizeTransition( + sizeFactor: _flashModeControlRowAnimation, + child: ClipRect( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisSize: MainAxisSize.max, + children: [ + IconButton( + icon: Icon(Icons.flash_off), + color: controller?.value?.flashMode == FlashMode.off + ? Colors.orange + : Colors.blue, + onPressed: controller != null + ? () => onSetFlashModeButtonPressed(FlashMode.off) + : null, + ), + IconButton( + icon: Icon(Icons.flash_auto), + color: controller?.value?.flashMode == FlashMode.auto + ? Colors.orange + : Colors.blue, + onPressed: controller != null + ? () => onSetFlashModeButtonPressed(FlashMode.auto) + : null, + ), + IconButton( + icon: Icon(Icons.flash_on), + color: controller?.value?.flashMode == FlashMode.always + ? Colors.orange + : Colors.blue, + onPressed: controller != null + ? () => onSetFlashModeButtonPressed(FlashMode.always) + : null, + ), + IconButton( + icon: Icon(Icons.highlight), + color: controller?.value?.flashMode == FlashMode.torch + ? Colors.orange + : Colors.blue, + onPressed: controller != null + ? () => onSetFlashModeButtonPressed(FlashMode.torch) + : null, + ), + ], ), - IconButton( - icon: const Icon(Icons.highlight), - color: controller?.value?.flashMode == FlashMode.torch - ? Colors.orange - : Colors.blue, - onPressed: controller != null - ? () => onFlashModeButtonPressed(FlashMode.torch) - : null, + ), + ); + } + + Widget _exposureModeControlRowWidget() { + return SizeTransition( + sizeFactor: _exposureModeControlRowAnimation, + child: ClipRect( + child: Container( + color: Colors.grey.shade50, + child: Column( + children: [ + Center( + child: Text("Exposure Mode"), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisSize: MainAxisSize.max, + children: [ + FlatButton( + child: Text('AUTO'), + textColor: + controller?.value?.exposureMode == ExposureMode.auto + ? Colors.orange + : Colors.blue, + onPressed: controller != null + ? () => + onSetExposureModeButtonPressed(ExposureMode.auto) + : null, + onLongPress: () { + if (controller != null) controller.setExposurePoint(null); + showInSnackBar('Resetting exposure point'); + }, + ), + FlatButton( + child: Text('LOCKED'), + textColor: + controller?.value?.exposureMode == ExposureMode.locked + ? Colors.orange + : Colors.blue, + onPressed: controller != null + ? () => + onSetExposureModeButtonPressed(ExposureMode.locked) + : null, + ), + ], + ), + Center( + child: Text("Exposure Offset"), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisSize: MainAxisSize.max, + children: [ + Text(_minAvailableExposureOffset.toString()), + Slider( + value: _currentExposureOffset, + min: _minAvailableExposureOffset, + max: _maxAvailableExposureOffset, + label: _currentExposureOffset.toString(), + onChanged: _minAvailableExposureOffset == + _maxAvailableExposureOffset + ? null + : setExposureOffset, + ), + Text(_maxAvailableExposureOffset.toString()), + ], + ), + ], + ), ), - ], + ), ); } @@ -353,6 +467,13 @@ class _CameraExampleHomeState extends State _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text(message))); } + void onViewFinderTap(TapDownDetails details, BoxConstraints constraints) { + controller.setExposurePoint(Offset( + details.localPosition.dx / constraints.maxWidth, + details.localPosition.dy / constraints.maxHeight, + )); + } + void onNewCameraSelected(CameraDescription cameraDescription) async { if (controller != null) { await controller.dispose(); @@ -373,6 +494,8 @@ class _CameraExampleHomeState extends State try { await controller.initialize(); + _minAvailableExposureOffset = await controller.getMinExposureOffset(); + _maxAvailableExposureOffset = await controller.getMaxExposureOffset(); _maxAvailableZoom = await controller.getMaxZoomLevel(); _minAvailableZoom = await controller.getMinZoomLevel(); } on CameraException catch (e) { @@ -397,13 +520,45 @@ class _CameraExampleHomeState extends State }); } - void onFlashModeButtonPressed(FlashMode mode) { + void onFlashModeButtonPressed() { + if (_flashModeControlRowAnimationController.value == 1) { + _flashModeControlRowAnimationController.reverse(); + } else { + _flashModeControlRowAnimationController.forward(); + _exposureModeControlRowAnimationController.reverse(); + } + } + + void onExposureModeButtonPressed() { + if (_exposureModeControlRowAnimationController.value == 1) { + _exposureModeControlRowAnimationController.reverse(); + } else { + _exposureModeControlRowAnimationController.forward(); + _flashModeControlRowAnimationController.reverse(); + } + } + + void onAudioModeButtonPressed() { + enableAudio = !enableAudio; + if (controller != null) { + onNewCameraSelected(controller.description); + } + } + + void onSetFlashModeButtonPressed(FlashMode mode) { setFlashMode(mode).then((_) { if (mounted) setState(() {}); showInSnackBar('Flash mode set to ${mode.toString().split('.').last}'); }); } + void onSetExposureModeButtonPressed(ExposureMode mode) { + setExposureMode(mode).then((_) { + if (mounted) setState(() {}); + showInSnackBar('Exposure mode set to ${mode.toString().split('.').last}'); + }); + } + void onVideoRecordButtonPressed() { startVideoRecording().then((_) { if (mounted) setState(() {}); @@ -502,6 +657,27 @@ class _CameraExampleHomeState extends State } } + Future setExposureMode(ExposureMode mode) async { + try { + await controller.setExposureMode(mode); + } on CameraException catch (e) { + _showCameraException(e); + rethrow; + } + } + + Future setExposureOffset(double offset) async { + setState(() { + _currentExposureOffset = offset; + }); + try { + offset = await controller.setExposureOffset(offset); + } on CameraException catch (e) { + _showCameraException(e); + rethrow; + } + } + Future _startVideoPlayer() async { final VideoPlayerController vController = VideoPlayerController.file(File(videoFile.path)); diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index d54695233bdb..816792e2fc1d 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -176,6 +176,45 @@ static AVCaptureFlashMode getAVCaptureFlashModeForFlashMode(FlashMode mode) { } } +// Mirrors ExposureMode in camera.dart +typedef enum { + ExposureModeAuto, + ExposureModeLocked, + +} ExposureMode; + +static NSString *getStringForExposureMode(ExposureMode mode) { + switch (mode) { + case ExposureModeAuto: + return @"auto"; + case ExposureModeLocked: + return @"locked"; + } + NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain + code:NSURLErrorUnknown + userInfo:@{ + NSLocalizedDescriptionKey : [NSString + stringWithFormat:@"Unknown string for exposure mode"] + }]; + @throw error; +} + +static ExposureMode getExposureModeForString(NSString *mode) { + if ([mode isEqualToString:@"auto"]) { + return ExposureModeAuto; + } else if ([mode isEqualToString:@"locked"]) { + return ExposureModeLocked; + } else { + NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain + code:NSURLErrorUnknown + userInfo:@{ + NSLocalizedDescriptionKey : [NSString + stringWithFormat:@"Unknown exposure mode %@", mode] + }]; + @throw error; + } +} + // Mirrors ResolutionPreset in camera.dart typedef enum { veryLow, @@ -243,6 +282,7 @@ @interface FLTCam : NSObject *)messenger { if (!_isStreamingImages) { FlutterEventChannel *eventChannel = @@ -1063,7 +1159,10 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re [methodChannel invokeMethod:@"initialized" arguments:@{ @"previewWidth" : @(_camera.previewSize.width), - @"previewHeight" : @(_camera.previewSize.height) + @"previewHeight" : @(_camera.previewSize.height), + @"exposureMode" : getStringForExposureMode([_camera exposureMode]), + @"exposurePointSupported" : + @([_camera.captureDevice isExposurePointOfInterestSupported]), }]; [_camera start]; result(nil); @@ -1098,6 +1197,26 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re [_camera setZoomLevel:zoom Result:result]; } else if ([@"setFlashMode" isEqualToString:call.method]) { [_camera setFlashModeWithResult:result mode:call.arguments[@"mode"]]; + } else if ([@"setExposureMode" isEqualToString:call.method]) { + [_camera setExposureModeWithResult:result mode:call.arguments[@"mode"]]; + } else if ([@"setExposurePoint" isEqualToString:call.method]) { + BOOL reset = ((NSNumber *)call.arguments[@"reset"]).boolValue; + double x = 0.5; + double y = 0.5; + if (!reset) { + x = ((NSNumber *)call.arguments[@"x"]).doubleValue; + y = ((NSNumber *)call.arguments[@"y"]).doubleValue; + } + [_camera setExposurePointWithResult:result x:x y:y]; + } else if ([@"getMinExposureOffset" isEqualToString:call.method]) { + result(@(_camera.captureDevice.minExposureTargetBias)); + } else if ([@"getMaxExposureOffset" isEqualToString:call.method]) { + result(@(_camera.captureDevice.maxExposureTargetBias)); + } else if ([@"getExposureOffsetStepSize" isEqualToString:call.method]) { + result(@(0.0)); + } else if ([@"setExposureOffset" isEqualToString:call.method]) { + [_camera setExposureOffsetWithResult:result + offset:((NSNumber *)call.arguments[@"offset"]).doubleValue]; } else { result(FlutterMethodNotImplemented); } diff --git a/packages/camera/camera/lib/camera.dart b/packages/camera/camera/lib/camera.dart index 6c6214e96951..55e7aa9444aa 100644 --- a/packages/camera/camera/lib/camera.dart +++ b/packages/camera/camera/lib/camera.dart @@ -12,5 +12,6 @@ export 'package:camera_platform_interface/camera_platform_interface.dart' CameraException, CameraLensDirection, FlashMode, + ExposureMode, ResolutionPreset, XFile; diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index 1d7aed755f42..c1f44bc9630a 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -3,12 +3,14 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:math'; import 'package:camera/camera.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:pedantic/pedantic.dart'; final MethodChannel _channel = const MethodChannel('plugins.flutter.io/camera'); @@ -37,6 +39,8 @@ class CameraValue { this.isStreamingImages, bool isRecordingPaused, this.flashMode, + this.exposureMode, + this.exposurePointSupported, }) : _isRecordingPaused = isRecordingPaused; /// Creates a new camera controller state for an uninitialized controller. @@ -48,6 +52,7 @@ class CameraValue { isStreamingImages: false, isRecordingPaused: false, flashMode: FlashMode.auto, + exposurePointSupported: false, ); /// True after [CameraController.initialize] has completed successfully. @@ -91,6 +96,12 @@ class CameraValue { /// The flash mode the camera is currently set to. final FlashMode flashMode; + /// The exposure mode the camera is currently set to. + final ExposureMode exposureMode; + + /// Whether setting the exposure point is supported. + final bool exposurePointSupported; + /// Creates a modified copy of the object. /// /// Explicitly specified fields get the specified value, all other fields get @@ -104,6 +115,8 @@ class CameraValue { Size previewSize, bool isRecordingPaused, FlashMode flashMode, + ExposureMode exposureMode, + bool exposurePointSupported, }) { return CameraValue( isInitialized: isInitialized ?? this.isInitialized, @@ -114,6 +127,9 @@ class CameraValue { isStreamingImages: isStreamingImages ?? this.isStreamingImages, isRecordingPaused: isRecordingPaused ?? _isRecordingPaused, flashMode: flashMode ?? this.flashMode, + exposureMode: exposureMode ?? this.exposureMode, + exposurePointSupported: + exposurePointSupported ?? this.exposurePointSupported, ); } @@ -125,7 +141,9 @@ class CameraValue { 'errorDescription: $errorDescription, ' 'previewSize: $previewSize, ' 'isStreamingImages: $isStreamingImages, ' - 'flashMode: $flashMode)'; + 'flashMode: $flashMode, ' + 'exposureMode: $exposureMode, ' + 'exposurePointSupported: $exposurePointSupported)'; } } @@ -184,25 +202,34 @@ class CameraController extends ValueNotifier { ); } try { + Completer _initializeCompleter = Completer(); + _cameraId = await CameraPlatform.instance.createCamera( description, resolutionPreset, enableAudio: enableAudio, ); - final previewSize = - CameraPlatform.instance.onCameraInitialized(_cameraId).map((event) { - return Size( - event.previewWidth, - event.previewHeight, - ); - }).first; + unawaited(CameraPlatform.instance + .onCameraInitialized(_cameraId) + .first + .then((event) { + _initializeCompleter.complete(event); + })); await CameraPlatform.instance.initializeCamera(_cameraId); value = value.copyWith( isInitialized: true, - previewSize: await previewSize, + previewSize: await _initializeCompleter.future + .then((CameraInitializedEvent event) => Size( + event.previewWidth, + event.previewHeight, + )), + exposureMode: await _initializeCompleter.future + .then((event) => event.exposureMode), + exposurePointSupported: await _initializeCompleter.future + .then((event) => event.exposurePointSupported), ); } on PlatformException catch (e) { throw CameraException(e.code, e.message); @@ -532,6 +559,137 @@ class CameraController extends ValueNotifier { } } + /// Sets the exposure mode for taking pictures. + Future setExposureMode(ExposureMode mode) async { + try { + await CameraPlatform.instance.setExposureMode(_cameraId, mode); + value = value.copyWith(exposureMode: mode); + } on PlatformException catch (e) { + throw CameraException(e.code, e.message); + } + } + + /// Sets the exposure point for automatically determining the exposure value. + Future setExposurePoint(Offset point) async { + if (point != null && + (point.dx < 0 || point.dx > 1 || point.dy < 0 || point.dy > 1)) { + throw ArgumentError( + 'The values of point should be anywhere between (0,0) and (1,1).'); + } + try { + await CameraPlatform.instance.setExposurePoint( + _cameraId, + point == null + ? null + : Point( + point.dx, + point.dy, + ), + ); + } on PlatformException catch (e) { + throw CameraException(e.code, e.message); + } + } + + /// Gets the minimum supported exposure offset for the selected camera in EV units. + Future getMinExposureOffset() async { + if (!value.isInitialized || _isDisposed) { + throw CameraException( + 'Uninitialized CameraController', + 'getMinExposureOffset was called on uninitialized CameraController', + ); + } + + try { + return CameraPlatform.instance.getMinExposureOffset(_cameraId); + } on PlatformException catch (e) { + throw CameraException(e.code, e.message); + } + } + + /// Gets the maximum supported exposure offset for the selected camera in EV units. + Future getMaxExposureOffset() async { + if (!value.isInitialized || _isDisposed) { + throw CameraException( + 'Uninitialized CameraController', + 'getMaxExposureOffset was called on uninitialized CameraController', + ); + } + + try { + return CameraPlatform.instance.getMaxExposureOffset(_cameraId); + } on PlatformException catch (e) { + throw CameraException(e.code, e.message); + } + } + + /// Gets the supported step size for exposure offset for the selected camera in EV units. + /// + /// Returns 0 when the camera supports using a free value without stepping. + Future getExposureOffsetStepSize() async { + if (!value.isInitialized || _isDisposed) { + throw CameraException( + 'Uninitialized CameraController', + 'getExposureOffsetStepSize was called on uninitialized CameraController', + ); + } + + try { + return CameraPlatform.instance.getExposureOffsetStepSize(_cameraId); + } on PlatformException catch (e) { + throw CameraException(e.code, e.message); + } + } + + /// Sets the exposure offset for the selected camera. + /// + /// The supplied [offset] value should be in EV units. 1 EV unit represents a + /// doubling in brightness. It should be between the minimum and maximum offsets + /// obtained through `getMinExposureOffset` and `getMaxExposureOffset` respectively. + /// Throws a `CameraException` when an illegal offset is supplied. + /// + /// When the supplied [offset] value does not align with the step size obtained + /// through `getExposureStepSize`, it will automatically be rounded to the nearest step. + /// + /// Returns the (rounded) offset value that was set. + Future setExposureOffset(double offset) async { + if (!value.isInitialized || _isDisposed) { + throw CameraException( + 'Uninitialized CameraController', + 'setExposureOffset was called on uninitialized CameraController', + ); + } + + // Check if offset is in range + List range = + await Future.wait([getMinExposureOffset(), getMaxExposureOffset()]); + if (offset < range[0] || offset > range[1]) { + throw CameraException( + "exposureOffsetOutOfBounds", + "The provided exposure offset was outside the supported range for this device.", + ); + } + + // Round to the closest step if needed + double stepSize = await getExposureOffsetStepSize(); + if (stepSize > 0) { + double inv = 1.0 / stepSize; + double roundedOffset = (offset * inv).roundToDouble() / inv; + if (roundedOffset > range[1]) { + roundedOffset = (offset * inv).floorToDouble() / inv; + } else if (roundedOffset < range[0]) { + roundedOffset = (offset * inv).ceilToDouble() / inv; + } + offset = roundedOffset; + } + + try { + return CameraPlatform.instance.setExposureOffset(_cameraId, offset); + } on PlatformException catch (e) { + throw CameraException(e.code, e.message); + } + } + /// Releases the resources of this camera. @override Future dispose() async { diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index fa40ad03ae89..0811ac442852 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,13 +2,14 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.6.3+4 +version: 0.6.4 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: flutter: sdk: flutter - camera_platform_interface: ">=1.0.4 <1.1.0" + camera_platform_interface: ^1.2.0 + pedantic: ^1.8.0 dev_dependencies: path_provider: ^0.5.0 @@ -17,7 +18,6 @@ dev_dependencies: sdk: flutter flutter_driver: sdk: flutter - pedantic: ^1.8.0 mockito: ^4.1.3 plugin_platform_interface: ^1.0.3 diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index 43dec7374901..5a4a7fc8771b 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:math'; import 'dart:ui'; import 'package:camera/camera.dart'; @@ -26,7 +27,8 @@ get mockAvailableCameras => [ get mockInitializeCamera => 13; -get mockOnCameraInitializedEvent => CameraInitializedEvent(13, 75, 75); +get mockOnCameraInitializedEvent => + CameraInitializedEvent(13, 75, 75, ExposureMode.auto, true); get mockOnCameraClosingEvent => null; @@ -603,6 +605,398 @@ void main() { 'This is a test error message', ))); }); + + test('setExposureMode() calls $CameraPlatform', () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max); + await cameraController.initialize(); + + await cameraController.setExposureMode(ExposureMode.auto); + + verify(CameraPlatform.instance + .setExposureMode(cameraController.cameraId, ExposureMode.auto)) + .called(1); + }); + + test('setExposureMode() throws $CameraException on $PlatformException', + () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max); + await cameraController.initialize(); + + when(CameraPlatform.instance + .setExposureMode(cameraController.cameraId, ExposureMode.auto)) + .thenThrow( + PlatformException( + code: 'TEST_ERROR', + message: 'This is a test error message', + details: null, + ), + ); + + expect( + cameraController.setExposureMode(ExposureMode.auto), + throwsA(isA().having( + (error) => error.description, + 'TEST_ERROR', + 'This is a test error message', + ))); + }); + + test('setExposurePoint() calls $CameraPlatform', () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max); + await cameraController.initialize(); + + await cameraController.setExposurePoint(Offset(0.5, 0.5)); + + verify(CameraPlatform.instance.setExposurePoint( + cameraController.cameraId, Point(0.5, 0.5))) + .called(1); + }); + + test('setExposurePoint() throws $CameraException on $PlatformException', + () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max); + await cameraController.initialize(); + + when(CameraPlatform.instance.setExposurePoint( + cameraController.cameraId, Point(0.5, 0.5))) + .thenThrow( + PlatformException( + code: 'TEST_ERROR', + message: 'This is a test error message', + details: null, + ), + ); + + expect( + cameraController.setExposurePoint(Offset(0.5, 0.5)), + throwsA(isA().having( + (error) => error.description, + 'TEST_ERROR', + 'This is a test error message', + ))); + }); + + test('getMinExposureOffset() calls $CameraPlatform', () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max); + await cameraController.initialize(); + + await cameraController.getMinExposureOffset(); + + verify(CameraPlatform.instance + .getMinExposureOffset(cameraController.cameraId)) + .called(1); + }); + + test('getMinExposureOffset() throws $CameraException on $PlatformException', + () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max); + await cameraController.initialize(); + + when(CameraPlatform.instance + .getMinExposureOffset(cameraController.cameraId)) + .thenThrow( + PlatformException( + code: 'TEST_ERROR', + message: 'This is a test error message', + details: null, + ), + ); + + expect( + cameraController.getMinExposureOffset(), + throwsA(isA().having( + (error) => error.description, + 'TEST_ERROR', + 'This is a test error message', + ))); + }); + + test('getMaxExposureOffset() calls $CameraPlatform', () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max); + await cameraController.initialize(); + + await cameraController.getMaxExposureOffset(); + + verify(CameraPlatform.instance + .getMaxExposureOffset(cameraController.cameraId)) + .called(1); + }); + + test('getMaxExposureOffset() throws $CameraException on $PlatformException', + () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max); + await cameraController.initialize(); + + when(CameraPlatform.instance + .getMaxExposureOffset(cameraController.cameraId)) + .thenThrow( + PlatformException( + code: 'TEST_ERROR', + message: 'This is a test error message', + details: null, + ), + ); + + expect( + cameraController.getMaxExposureOffset(), + throwsA(isA().having( + (error) => error.description, + 'TEST_ERROR', + 'This is a test error message', + ))); + }); + + test('getExposureOffsetStepSize() calls $CameraPlatform', () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max); + await cameraController.initialize(); + + await cameraController.getExposureOffsetStepSize(); + + verify(CameraPlatform.instance + .getMinExposureOffset(cameraController.cameraId)) + .called(1); + }); + + test( + 'getExposureOffsetStepSize() throws $CameraException on $PlatformException', + () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max); + await cameraController.initialize(); + + when(CameraPlatform.instance + .getExposureOffsetStepSize(cameraController.cameraId)) + .thenThrow( + PlatformException( + code: 'TEST_ERROR', + message: 'This is a test error message', + details: null, + ), + ); + + expect( + cameraController.getExposureOffsetStepSize(), + throwsA(isA().having( + (error) => error.description, + 'TEST_ERROR', + 'This is a test error message', + ))); + }); + + test('setExposureOffset() calls $CameraPlatform', () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max); + await cameraController.initialize(); + when(CameraPlatform.instance + .getMinExposureOffset(cameraController.cameraId)) + .thenAnswer((_) async => -1.0); + when(CameraPlatform.instance + .getMaxExposureOffset(cameraController.cameraId)) + .thenAnswer((_) async => 2.0); + when(CameraPlatform.instance + .getExposureOffsetStepSize(cameraController.cameraId)) + .thenAnswer((_) async => 1.0); + + await cameraController.setExposureOffset(1.0); + + verify(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, 1.0)) + .called(1); + }); + + test('setExposureOffset() throws $CameraException on $PlatformException', + () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max); + await cameraController.initialize(); + when(CameraPlatform.instance + .getMinExposureOffset(cameraController.cameraId)) + .thenAnswer((_) async => -1.0); + when(CameraPlatform.instance + .getMaxExposureOffset(cameraController.cameraId)) + .thenAnswer((_) async => 2.0); + when(CameraPlatform.instance + .getExposureOffsetStepSize(cameraController.cameraId)) + .thenAnswer((_) async => 1.0); + when(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, 1.0)) + .thenThrow( + PlatformException( + code: 'TEST_ERROR', + message: 'This is a test error message', + details: null, + ), + ); + + expect( + cameraController.setExposureOffset(1.0), + throwsA(isA().having( + (error) => error.description, + 'TEST_ERROR', + 'This is a test error message', + ))); + }); + + test( + 'setExposureOffset() throws $CameraException when offset is out of bounds', + () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max); + await cameraController.initialize(); + when(CameraPlatform.instance + .getMinExposureOffset(cameraController.cameraId)) + .thenAnswer((_) async => -1.0); + when(CameraPlatform.instance + .getMaxExposureOffset(cameraController.cameraId)) + .thenAnswer((_) async => 2.0); + when(CameraPlatform.instance + .getExposureOffsetStepSize(cameraController.cameraId)) + .thenAnswer((_) async => 1.0); + + expect( + cameraController.setExposureOffset(3.0), + throwsA(isA().having( + (error) => error.description, + 'exposureOffsetOutOfBounds', + 'The provided exposure offset was outside the supported range for this device.', + ))); + expect( + cameraController.setExposureOffset(-2.0), + throwsA(isA().having( + (error) => error.description, + 'exposureOffsetOutOfBounds', + 'The provided exposure offset was outside the supported range for this device.', + ))); + + await cameraController.setExposureOffset(2.0); + await cameraController.setExposureOffset(-1.0); + await cameraController.setExposureOffset(-0.0); + verify(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, 2.0)) + .called(1); + verify(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, -1.0)) + .called(1); + verify(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, 0.0)) + .called(1); + }); + + test('setExposureOffset() rounds offset to nearest step', () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max); + await cameraController.initialize(); + when(CameraPlatform.instance + .getMinExposureOffset(cameraController.cameraId)) + .thenAnswer((_) async => -1.0); + when(CameraPlatform.instance + .getMaxExposureOffset(cameraController.cameraId)) + .thenAnswer((_) async => 1.0); + when(CameraPlatform.instance + .getExposureOffsetStepSize(cameraController.cameraId)) + .thenAnswer((_) async => 0.4); + when(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, 1.0)) + .thenAnswer((_) async => 1.0); + + await cameraController.setExposureOffset(1.0); + await cameraController.setExposureOffset(-1.0); + await cameraController.setExposureOffset(0.1); + await cameraController.setExposureOffset(0.2); + await cameraController.setExposureOffset(0.3); + await cameraController.setExposureOffset(0.4); + await cameraController.setExposureOffset(0.5); + await cameraController.setExposureOffset(0.6); + await cameraController.setExposureOffset(0.7); + await cameraController.setExposureOffset(-0.1); + await cameraController.setExposureOffset(-0.2); + await cameraController.setExposureOffset(-0.3); + await cameraController.setExposureOffset(-0.4); + await cameraController.setExposureOffset(-0.5); + await cameraController.setExposureOffset(-0.6); + await cameraController.setExposureOffset(-0.7); + + verify(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, 0.8)) + .called(3); + verify(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, -0.8)) + .called(3); + verify(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, 0.0)) + .called(2); + verify(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, 0.4)) + .called(4); + verify(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, -0.4)) + .called(4); + }); }); } @@ -641,7 +1035,8 @@ class MockCameraPlatform extends Mock : Future.value(mockTakePicture); @override - Future startVideoRecording(int cameraId) => + Future startVideoRecording(int cameraId, + {Duration maxVideoDuration}) => Future.value(mockVideoRecordingXFile); } diff --git a/packages/camera/camera/test/camera_value_test.dart b/packages/camera/camera/test/camera_value_test.dart index 06b327cb1c29..d9193e212ea9 100644 --- a/packages/camera/camera/test/camera_value_test.dart +++ b/packages/camera/camera/test/camera_value_test.dart @@ -13,15 +13,16 @@ void main() { group('camera_value', () { test('Can be created', () { var cameraValue = const CameraValue( - isInitialized: false, - errorDescription: null, - previewSize: Size(10, 10), - isRecordingPaused: false, - isRecordingVideo: false, - isTakingPicture: false, - isStreamingImages: false, - flashMode: FlashMode.auto, - ); + isInitialized: false, + errorDescription: null, + previewSize: Size(10, 10), + isRecordingPaused: false, + isRecordingVideo: false, + isTakingPicture: false, + isStreamingImages: false, + flashMode: FlashMode.auto, + exposureMode: ExposureMode.auto, + exposurePointSupported: true); expect(cameraValue, isA()); expect(cameraValue.isInitialized, isFalse); @@ -31,6 +32,9 @@ void main() { expect(cameraValue.isRecordingVideo, isFalse); expect(cameraValue.isTakingPicture, isFalse); expect(cameraValue.isStreamingImages, isFalse); + expect(cameraValue.flashMode, FlashMode.auto); + expect(cameraValue.exposureMode, ExposureMode.auto); + expect(cameraValue.exposurePointSupported, true); }); test('Can be created as uninitialized', () { @@ -44,6 +48,9 @@ void main() { expect(cameraValue.isRecordingVideo, isFalse); expect(cameraValue.isTakingPicture, isFalse); expect(cameraValue.isStreamingImages, isFalse); + expect(cameraValue.flashMode, FlashMode.auto); + expect(cameraValue.exposureMode, null); + expect(cameraValue.exposurePointSupported, false); }); test('Can be copied with isInitialized', () { @@ -59,6 +66,8 @@ void main() { expect(cameraValue.isTakingPicture, isFalse); expect(cameraValue.isStreamingImages, isFalse); expect(cameraValue.flashMode, FlashMode.auto); + expect(cameraValue.exposureMode, null); + expect(cameraValue.exposurePointSupported, false); }); test('Has aspectRatio after setting size', () { @@ -97,10 +106,11 @@ void main() { isTakingPicture: false, isStreamingImages: false, flashMode: FlashMode.auto, + exposurePointSupported: true, ); expect(cameraValue.toString(), - 'CameraValue(isRecordingVideo: false, isInitialized: false, errorDescription: null, previewSize: Size(10.0, 10.0), isStreamingImages: false, flashMode: FlashMode.auto)'); + 'CameraValue(isRecordingVideo: false, isInitialized: false, errorDescription: null, previewSize: Size(10.0, 10.0), isStreamingImages: false, flashMode: FlashMode.auto, exposureMode: null, exposurePointSupported: true)'); }); }); } From cfa709835ab85702ee8a9ed24bbe7a3fe736c3f5 Mon Sep 17 00:00:00 2001 From: Anniek Date: Thu, 31 Dec 2020 13:27:56 +0100 Subject: [PATCH 0014/1565] Added closeCaptureSession() to stopVideoRecording in Camera.java to fix an Android 6 crash (#3336) Co-authored-by: Maurits van Beusekom --- packages/camera/camera/CHANGELOG.md | 4 ++++ .../src/main/java/io/flutter/plugins/camera/Camera.java | 1 + packages/camera/camera/pubspec.yaml | 2 +- .../example/android/gradle/wrapper/gradle-wrapper.properties | 5 +++++ 4 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 packages/camera/example/android/gradle/wrapper/gradle-wrapper.properties diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index f576ee524ca1..3bb1b0639c97 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.4+1 + +* Added closeCaptureSession() to stopVideoRecording in Camera.java to fix an Android 6 crash + ## 0.6.4 * Adds auto exposure support for Android and iOS implementations. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index d57a737c09f6..a3ae3f275213 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -560,6 +560,7 @@ public void stopVideoRecording(@NonNull final Result result) { try { recordingVideo = false; + closeCaptureSession(); mediaRecorder.stop(); mediaRecorder.reset(); startPreview(); diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 0811ac442852..2b392f17bf82 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.6.4 +version: 0.6.4+1 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: diff --git a/packages/camera/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/camera/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000000..be52383ef49c --- /dev/null +++ b/packages/camera/example/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists From 16f37e9a814e3f84927dcc8c3f991b5c7203f1bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl?= <32639467+danielroek@users.noreply.github.com> Date: Tue, 5 Jan 2021 09:00:53 +0100 Subject: [PATCH 0015/1565] [camera_platform_interface] Added imageFormatGroup to initialize (#3364) * Added imageFormatGroup to initialize * Apply suggestions from code review Co-authored-by: Maurits van Beusekom * Added period to sentence * Moved ImageFormatGroup to platform_interface; Added extension to convert ImageFormatGroup to name; Changed int to ImageFormatGroup for initializeCamera * Fixed test * Separated Android and iOS in name extension * Clarified returns on name extension * Export image_format_group.dart in types.dart * Changed enum values to lowercase * Added ImageFormatGroup test * Fixed formatting * Removed target platform switch. * Fixed formatting Co-authored-by: Maurits van Beusekom --- .../camera_platform_interface/CHANGELOG.md | 4 ++ .../method_channel/method_channel_camera.dart | 5 +- .../platform_interface/camera_platform.dart | 8 ++- .../lib/src/types/image_format_group.dart | 50 +++++++++++++++++++ .../lib/src/types/types.dart | 1 + .../camera_platform_interface/pubspec.yaml | 4 +- .../method_channel_camera_test.dart | 11 +++- .../test/types/image_group_test.dart | 13 +++++ 8 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart create mode 100644 packages/camera/camera_platform_interface/test/types/image_group_test.dart diff --git a/packages/camera/camera_platform_interface/CHANGELOG.md b/packages/camera/camera_platform_interface/CHANGELOG.md index 8e316054f2b1..d264d6c6f9ce 100644 --- a/packages/camera/camera_platform_interface/CHANGELOG.md +++ b/packages/camera/camera_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.0 + +- Introduces an option to set the image format when initializing. + ## 1.2.0 - Added interface to support automatic exposure. diff --git a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart index 6a73031111df..0ccc59939610 100644 --- a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart +++ b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart @@ -6,6 +6,7 @@ import 'dart:async'; import 'dart:math'; import 'package:camera_platform_interface/camera_platform_interface.dart'; +import 'package:camera_platform_interface/src/types/image_format_group.dart'; import 'package:camera_platform_interface/src/utils/utils.dart'; import 'package:cross_file/cross_file.dart'; import 'package:flutter/services.dart'; @@ -76,7 +77,8 @@ class MethodChannelCamera extends CameraPlatform { } @override - Future initializeCamera(int cameraId) { + Future initializeCamera(int cameraId, + {ImageFormatGroup imageFormatGroup}) { _channels.putIfAbsent(cameraId, () { final channel = MethodChannel('flutter.io/cameraPlugin/camera$cameraId'); channel.setMethodCallHandler( @@ -94,6 +96,7 @@ class MethodChannelCamera extends CameraPlatform { 'initialize', { 'cameraId': cameraId, + 'imageFormatGroup': imageFormatGroup.name(), }, ); diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart index c7a603228ce2..d95d957e4862 100644 --- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart +++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart @@ -8,6 +8,7 @@ import 'dart:math'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:camera_platform_interface/src/method_channel/method_channel_camera.dart'; import 'package:camera_platform_interface/src/types/exposure_mode.dart'; +import 'package:camera_platform_interface/src/types/image_format_group.dart'; import 'package:cross_file/cross_file.dart'; import 'package:flutter/widgets.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; @@ -54,7 +55,12 @@ abstract class CameraPlatform extends PlatformInterface { } /// Initializes the camera on the device. - Future initializeCamera(int cameraId) { + /// + /// [imageFormatGroup] is used to specify the image formatting used. + /// On Android this defaults to ImageFormat.YUV_420_888 and applies only to the imageStream. + /// On iOS this defaults to kCVPixelFormatType_32BGRA. + Future initializeCamera(int cameraId, + {ImageFormatGroup imageFormatGroup}) { throw UnimplementedError('initializeCamera() is not implemented.'); } diff --git a/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart new file mode 100644 index 000000000000..3d2c0180fe65 --- /dev/null +++ b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart @@ -0,0 +1,50 @@ +/// Group of image formats that are comparable across Android and iOS platforms. +enum ImageFormatGroup { + /// The image format does not fit into any specific group. + unknown, + + /// Multi-plane YUV 420 format. + /// + /// This format is a generic YCbCr format, capable of describing any 4:2:0 + /// chroma-subsampled planar or semiplanar buffer (but not fully interleaved), + /// with 8 bits per color sample. + /// + /// On Android, this is `android.graphics.ImageFormat.YUV_420_888`. See + /// https://developer.android.com/reference/android/graphics/ImageFormat.html#YUV_420_888 + /// + /// On iOS, this is `kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange`. See + /// https://developer.apple.com/documentation/corevideo/1563591-pixel_format_identifiers/kcvpixelformattype_420ypcbcr8biplanarvideorange?language=objc + yuv420, + + /// 32-bit BGRA. + /// + /// On iOS, this is `kCVPixelFormatType_32BGRA`. See + /// https://developer.apple.com/documentation/corevideo/1563591-pixel_format_identifiers/kcvpixelformattype_32bgra?language=objc + bgra8888, + + /// 32-big RGB image encoded into JPEG bytes. + /// + /// On Android, this is `android.graphics.ImageFormat.JPEG`. See + /// https://developer.android.com/reference/android/graphics/ImageFormat#JPEG + jpeg, +} + +/// Extension on [ImageFormatGroup] to stringify the enum +extension ImageFormatGroupName on ImageFormatGroup { + /// returns a String value for [ImageFormatGroup] + /// returns 'unknown' if platform is not supported + /// or if [ImageFormatGroup] is not supported for the platform + String name() { + switch (this) { + case ImageFormatGroup.bgra8888: + return 'bgra8888'; + case ImageFormatGroup.yuv420: + return 'yuv420'; + case ImageFormatGroup.jpeg: + return 'jpeg'; + case ImageFormatGroup.unknown: + default: + return 'unknown'; + } + } +} diff --git a/packages/camera/camera_platform_interface/lib/src/types/types.dart b/packages/camera/camera_platform_interface/lib/src/types/types.dart index bab430eb5a69..eaadc5c14061 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/types.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/types.dart @@ -6,4 +6,5 @@ export 'camera_description.dart'; export 'resolution_preset.dart'; export 'camera_exception.dart'; export 'flash_mode.dart'; +export 'image_format_group.dart'; export 'exposure_mode.dart'; diff --git a/packages/camera/camera_platform_interface/pubspec.yaml b/packages/camera/camera_platform_interface/pubspec.yaml index b8301d289cc6..7a4fa49ce052 100644 --- a/packages/camera/camera_platform_interface/pubspec.yaml +++ b/packages/camera/camera_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the camera plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.2.0 +version: 1.3.0 dependencies: flutter: @@ -21,5 +21,5 @@ dev_dependencies: pedantic: ^1.8.0 environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.7.0 <3.0.0" flutter: ">=1.22.0" diff --git a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart index b916513ef0de..e8136fb051ad 100644 --- a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart +++ b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart @@ -25,7 +25,10 @@ void main() { MethodChannelMock cameraMockChannel = MethodChannelMock( channelName: 'plugins.flutter.io/camera', methods: { - 'create': {'cameraId': 1} + 'create': { + 'cameraId': 1, + 'imageFormatGroup': 'unknown', + } }); final camera = MethodChannelCamera(); @@ -108,7 +111,10 @@ void main() { MethodChannelMock cameraMockChannel = MethodChannelMock( channelName: 'plugins.flutter.io/camera', methods: { - 'create': {'cameraId': 1}, + 'create': { + 'cameraId': 1, + 'imageFormatGroup': 'unknown', + }, 'initialize': null }); final camera = MethodChannelCamera(); @@ -136,6 +142,7 @@ void main() { 'initialize', arguments: { 'cameraId': 1, + 'imageFormatGroup': 'unknown', }, ), ]); diff --git a/packages/camera/camera_platform_interface/test/types/image_group_test.dart b/packages/camera/camera_platform_interface/test/types/image_group_test.dart new file mode 100644 index 000000000000..c49b2f03a7a0 --- /dev/null +++ b/packages/camera/camera_platform_interface/test/types/image_group_test.dart @@ -0,0 +1,13 @@ +import 'package:camera_platform_interface/src/types/types.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('$ImageFormatGroup tests', () { + test('ImageFormatGroupName extension returns correct values', () { + expect(ImageFormatGroup.bgra8888.name(), 'bgra8888'); + expect(ImageFormatGroup.yuv420.name(), 'yuv420'); + expect(ImageFormatGroup.jpeg.name(), 'jpeg'); + expect(ImageFormatGroup.unknown.name(), 'unknown'); + }); + }); +} From 03941830fea4281ef90c878e99073da323bbed4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl?= <32639467+danielroek@users.noreply.github.com> Date: Tue, 5 Jan 2021 11:46:06 +0100 Subject: [PATCH 0016/1565] [camera] Fixed stale images in imageStream subscriptions (#3344) * Fixed stale images in imageStream subscriptions * Implemented feedback * Fixed format exception * added null-check for imageStreamReader * Removed setOnImageAvailableListener from onCancel * fixed formatting --- packages/camera/camera/CHANGELOG.md | 4 ++++ .../src/main/java/io/flutter/plugins/camera/Camera.java | 7 +++++++ .../io/flutter/plugins/camera/MethodCallHandlerImpl.java | 2 +- packages/camera/camera/pubspec.yaml | 2 +- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 3bb1b0639c97..d38016a471e6 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.4+2 + +* Set ImageStreamReader listener to null to prevent stale images when streaming images. + ## 0.6.4+1 * Added closeCaptureSession() to stopVideoRecording in Camera.java to fix an Android 6 crash diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index a3ae3f275213..b7da94a613ba 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -943,6 +943,13 @@ public void setZoomLevel(@NonNull final Result result, float zoom) throws Camera result.success(null); } + public void stopImageStream() throws CameraAccessException { + if (imageStreamReader != null) { + imageStreamReader.setOnImageAvailableListener(null, null); + } + startPreview(); + } + private void closeCaptureSession() { if (cameraCaptureSession != null) { cameraCaptureSession.close(); diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java index 78a10010f90b..2ceff845ed4b 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java @@ -219,7 +219,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) case "stopImageStream": { try { - camera.startPreview(); + camera.stopImageStream(); result.success(null); } catch (Exception e) { handleException(e, result); diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 2b392f17bf82..02f874bf9ea3 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.6.4+1 +version: 0.6.4+2 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From b64bebff9743589a75d31b613b0d0af9040604df Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Tue, 5 Jan 2021 20:13:44 +0100 Subject: [PATCH 0017/1565] [camera] disable auto focus when using front facing camera on Android (#3383) * Refactured Camera and fix issue front facing camera * Update FPS range on Android to have correct brightness * Formatted files * Fix version conflict --- packages/camera/camera/CHANGELOG.md | 4 + .../io/flutter/plugins/camera/Camera.java | 480 ++++++++++-------- packages/camera/camera/pubspec.yaml | 2 +- 3 files changed, 286 insertions(+), 200 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index d38016a471e6..55c7eb1fcfd2 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.4+3 + +* Detect if selected camera supports auto focus and act accordingly on Android. This solves a problem where front facing cameras are not capturing the picture because auto focus is not supported. + ## 0.6.4+2 * Set ImageStreamReader listener to null to prevent stale images when streaming images. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index b7da94a613ba..2db097ceadf7 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -33,12 +33,14 @@ import android.os.Build.VERSION_CODES; import android.os.Handler; import android.os.Looper; +import android.util.Log; import android.util.Range; import android.util.Rational; import android.util.Size; import android.view.OrientationEventListener; import android.view.Surface; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugins.camera.PictureCaptureRequest.State; @@ -59,6 +61,11 @@ import java.util.Map; import java.util.concurrent.Executors; +@FunctionalInterface +interface ErrorCallback { + void onError(String errorCode, String errorMessage); +} + public class Camera { private final SurfaceTextureEntry flutterTexture; private final CameraManager cameraManager; @@ -73,6 +80,7 @@ public class Camera { private final CamcorderProfile recordingProfile; private final DartMessenger dartMessenger; private final CameraZoom cameraZoom; + private final CameraCharacteristics cameraCharacteristics; private CameraDevice cameraDevice; private CameraCaptureSession cameraCaptureSession; @@ -88,6 +96,8 @@ public class Camera { private PictureCaptureRequest pictureCaptureRequest; private CameraRegions cameraRegions; private int exposureOffset; + private boolean useAutoFocus; + private Range fpsRange; public Camera( final Activity activity, @@ -122,10 +132,12 @@ public void onOrientationChanged(int i) { }; orientationEventListener.enable(); - CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraName); - sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION); + cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraName); + initFps(cameraCharacteristics); + sensorOrientation = cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION); isFrontFacing = - characteristics.get(CameraCharacteristics.LENS_FACING) == CameraMetadata.LENS_FACING_FRONT; + cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) + == CameraMetadata.LENS_FACING_FRONT; ResolutionPreset preset = ResolutionPreset.valueOf(resolutionPreset); recordingProfile = CameraUtils.getBestAvailableCamcorderProfileForResolutionPreset(cameraName, preset); @@ -133,8 +145,29 @@ public void onOrientationChanged(int i) { previewSize = computeBestPreviewSize(cameraName, preset); cameraZoom = new CameraZoom( - characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE), - characteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM)); + cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE), + cameraCharacteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM)); + } + + private void initFps(CameraCharacteristics cameraCharacteristics) { + try { + Range[] ranges = + cameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES); + if (ranges != null) { + for (Range range : ranges) { + int upper = range.getUpper(); + Log.i("Camera", "[FPS Range Available] is:" + range); + if (upper >= 10) { + if (fpsRange == null || upper < fpsRange.getUpper()) { + fpsRange = range; + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + Log.i("Camera", "[FPS Range] is:" + fpsRange); } private void prepareMediaRecorder(String outputFilePath) throws IOException { @@ -221,6 +254,118 @@ public void onError(@NonNull CameraDevice cameraDevice, int errorCode) { null); } + private void createCaptureSession(int templateType, Surface... surfaces) + throws CameraAccessException { + createCaptureSession(templateType, null, surfaces); + } + + private void createCaptureSession( + int templateType, Runnable onSuccessCallback, Surface... surfaces) + throws CameraAccessException { + // Close any existing capture session. + closeCaptureSession(); + + // Create a new capture builder. + captureRequestBuilder = cameraDevice.createCaptureRequest(templateType); + + // Build Flutter surface to render to + SurfaceTexture surfaceTexture = flutterTexture.surfaceTexture(); + surfaceTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight()); + Surface flutterSurface = new Surface(surfaceTexture); + captureRequestBuilder.addTarget(flutterSurface); + + List remainingSurfaces = Arrays.asList(surfaces); + if (templateType != CameraDevice.TEMPLATE_PREVIEW) { + // If it is not preview mode, add all surfaces as targets. + for (Surface surface : remainingSurfaces) { + captureRequestBuilder.addTarget(surface); + } + } + + // Prepare the callback + CameraCaptureSession.StateCallback callback = + new CameraCaptureSession.StateCallback() { + @Override + public void onConfigured(@NonNull CameraCaptureSession session) { + if (cameraDevice == null) { + dartMessenger.sendCameraErrorEvent("The camera was closed during configuration."); + return; + } + cameraCaptureSession = session; + + updateFpsRange(); + updateAutoFocus(); + updateFlash(flashMode); + updateExposure(exposureMode); + + refreshPreviewCaptureSession( + onSuccessCallback, (code, message) -> dartMessenger.sendCameraErrorEvent(message)); + } + + @Override + public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) { + dartMessenger.sendCameraErrorEvent("Failed to configure camera session."); + } + }; + + // Start the session + if (VERSION.SDK_INT >= VERSION_CODES.P) { + // Collect all surfaces we want to render to. + List configs = new ArrayList<>(); + configs.add(new OutputConfiguration(flutterSurface)); + for (Surface surface : remainingSurfaces) { + configs.add(new OutputConfiguration(surface)); + } + createCaptureSessionWithSessionConfig(configs, callback); + } else { + // Collect all surfaces we want to render to. + List surfaceList = new ArrayList<>(); + surfaceList.add(flutterSurface); + surfaceList.addAll(remainingSurfaces); + createCaptureSession(surfaceList, callback); + } + } + + @TargetApi(VERSION_CODES.P) + private void createCaptureSessionWithSessionConfig( + List outputConfigs, CameraCaptureSession.StateCallback callback) + throws CameraAccessException { + cameraDevice.createCaptureSession( + new SessionConfiguration( + SessionConfiguration.SESSION_REGULAR, + outputConfigs, + Executors.newSingleThreadExecutor(), + callback)); + } + + @TargetApi(VERSION_CODES.LOLLIPOP) + @SuppressWarnings("deprecation") + private void createCaptureSession( + List surfaces, CameraCaptureSession.StateCallback callback) + throws CameraAccessException { + cameraDevice.createCaptureSession(surfaces, callback, null); + } + + private void refreshPreviewCaptureSession( + @Nullable Runnable onSuccessCallback, @NonNull ErrorCallback onErrorCallback) { + if (cameraCaptureSession == null) { + return; + } + + try { + cameraCaptureSession.setRepeatingRequest( + captureRequestBuilder.build(), + pictureCaptureCallback, + new Handler(Looper.getMainLooper())); + + if (onSuccessCallback != null) { + onSuccessCallback.run(); + } + } catch (CameraAccessException | IllegalStateException | IllegalArgumentException e) { + onErrorCallback.onError("cameraAccess", e.getMessage()); + } + } + private void writeToFile(ByteBuffer buffer, File file) throws IOException { try (FileOutputStream outputStream = new FileOutputStream(file)) { while (0 < buffer.remaining()) { @@ -261,7 +406,11 @@ public void takePicture(@NonNull final Result result) { }, null); - runPictureAutoFocus(); + if (useAutoFocus) { + runPictureAutoFocus(); + } else { + runPicturePreCapture(); + } } private final CameraCaptureSession.CaptureCallback pictureCaptureCallback = @@ -344,6 +493,7 @@ private void processCapture(CaptureResult result) { private void runPictureAutoFocus() { assert (pictureCaptureRequest != null); + pictureCaptureRequest.setState(PictureCaptureRequest.State.focusing); lockAutoFocus(); } @@ -355,14 +505,13 @@ private void runPicturePreCapture() { captureRequestBuilder.set( CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START); - try { - cameraCaptureSession.capture(captureRequestBuilder.build(), pictureCaptureCallback, null); - captureRequestBuilder.set( - CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, - CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE); - } catch (CameraAccessException e) { - pictureCaptureRequest.error("cameraAccess", e.getMessage(), null); - } + + refreshPreviewCaptureSession( + () -> + captureRequestBuilder.set( + CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, + CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE), + (code, message) -> pictureCaptureRequest.error(code, message, null)); } private void runPictureCapture() { @@ -409,125 +558,25 @@ public void onCaptureCompleted( private void lockAutoFocus() { captureRequestBuilder.set( CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START); - try { - cameraCaptureSession.capture(captureRequestBuilder.build(), pictureCaptureCallback, null); - } catch (CameraAccessException e) { - pictureCaptureRequest.error("cameraAccess", e.getMessage(), null); - } + + refreshPreviewCaptureSession( + null, (code, message) -> pictureCaptureRequest.error(code, message, null)); } private void unlockAutoFocus() { captureRequestBuilder.set( CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL); - initPreviewCaptureBuilder(); + updateAutoFocus(); try { cameraCaptureSession.capture(captureRequestBuilder.build(), null, null); } catch (CameraAccessException ignored) { } captureRequestBuilder.set( CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_IDLE); - try { - cameraCaptureSession.setRepeatingRequest( - captureRequestBuilder.build(), pictureCaptureCallback, null); - } catch (CameraAccessException e) { - pictureCaptureRequest.error("cameraAccess", e.getMessage(), null); - } - } - private void createCaptureSession(int templateType, Surface... surfaces) - throws CameraAccessException { - createCaptureSession(templateType, null, surfaces); - } - - private void createCaptureSession( - int templateType, Runnable onSuccessCallback, Surface... surfaces) - throws CameraAccessException { - // Close any existing capture session. - closeCaptureSession(); - - // Create a new capture builder. - captureRequestBuilder = cameraDevice.createCaptureRequest(templateType); - - // Build Flutter surface to render to - SurfaceTexture surfaceTexture = flutterTexture.surfaceTexture(); - surfaceTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight()); - Surface flutterSurface = new Surface(surfaceTexture); - captureRequestBuilder.addTarget(flutterSurface); - - List remainingSurfaces = Arrays.asList(surfaces); - if (templateType != CameraDevice.TEMPLATE_PREVIEW) { - // If it is not preview mode, add all surfaces as targets. - for (Surface surface : remainingSurfaces) { - captureRequestBuilder.addTarget(surface); - } - } - - // Prepare the callback - CameraCaptureSession.StateCallback callback = - new CameraCaptureSession.StateCallback() { - @Override - public void onConfigured(@NonNull CameraCaptureSession session) { - try { - if (cameraDevice == null) { - dartMessenger.sendCameraErrorEvent("The camera was closed during configuration."); - return; - } - cameraCaptureSession = session; - initPreviewCaptureBuilder(); - cameraCaptureSession.setRepeatingRequest( - captureRequestBuilder.build(), - pictureCaptureCallback, - new Handler(Looper.getMainLooper())); - if (onSuccessCallback != null) { - onSuccessCallback.run(); - } - } catch (CameraAccessException | IllegalStateException | IllegalArgumentException e) { - dartMessenger.sendCameraErrorEvent(e.getMessage()); - } - } - - @Override - public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) { - dartMessenger.sendCameraErrorEvent("Failed to configure camera session."); - } - }; - - // Start the session - if (VERSION.SDK_INT >= VERSION_CODES.P) { - // Collect all surfaces we want to render to. - List configs = new ArrayList<>(); - configs.add(new OutputConfiguration(flutterSurface)); - for (Surface surface : remainingSurfaces) { - configs.add(new OutputConfiguration(surface)); - } - createCaptureSessionWithSessionConfig(configs, callback); - } else { - // Collect all surfaces we want to render to. - List surfaceList = new ArrayList<>(); - surfaceList.add(flutterSurface); - surfaceList.addAll(remainingSurfaces); - createCaptureSession(surfaceList, callback); - } - } - - @TargetApi(VERSION_CODES.P) - private void createCaptureSessionWithSessionConfig( - List outputConfigs, CameraCaptureSession.StateCallback callback) - throws CameraAccessException { - cameraDevice.createCaptureSession( - new SessionConfiguration( - SessionConfiguration.SESSION_REGULAR, - outputConfigs, - Executors.newSingleThreadExecutor(), - callback)); - } - - @TargetApi(VERSION_CODES.LOLLIPOP) - @SuppressWarnings("deprecation") - private void createCaptureSession( - List surfaces, CameraCaptureSession.StateCallback callback) - throws CameraAccessException { - cameraDevice.createCaptureSession(surfaces, callback, null); + refreshPreviewCaptureSession( + null, + (errorCode, errorMessage) -> pictureCaptureRequest.error(errorCode, errorMessage, null)); } public void startVideoRecording(Result result) { @@ -560,8 +609,14 @@ public void stopVideoRecording(@NonNull final Result result) { try { recordingVideo = false; - closeCaptureSession(); - mediaRecorder.stop(); + + try { + cameraCaptureSession.abortCaptures(); + mediaRecorder.stop(); + } catch (CameraAccessException | IllegalStateException e) { + // Ignore exceptions and try to continue (changes are camera session already aborted capture) + } + mediaRecorder.reset(); startPreview(); result.success(videoRecordingFile.getAbsolutePath()); @@ -630,8 +685,8 @@ public void setFlashMode(@NonNull final Result result, FlashMode mode) // If switching directly from torch to auto or on, make sure we turn off the torch. if (flashMode == FlashMode.torch && mode != FlashMode.torch && mode != FlashMode.off) { - this.flashMode = FlashMode.off; - initPreviewCaptureBuilder(); + updateFlash(FlashMode.off); + this.cameraCaptureSession.setRepeatingRequest( captureRequestBuilder.build(), new CaptureCallback() { @@ -647,8 +702,13 @@ public void onCaptureCompleted( } updateFlash(mode); - result.success(null); - isFinished = true; + refreshPreviewCaptureSession( + () -> { + result.success(null); + isFinished = true; + }, + (code, message) -> + result.error("setFlashModeFailed", "Could not set flash mode.", null)); } @Override @@ -667,26 +727,16 @@ public void onCaptureFailed( null); } else { updateFlash(mode); - result.success(null); - } - } - private void updateFlash(FlashMode mode) { - // Get flash - flashMode = mode; - initPreviewCaptureBuilder(); - try { - cameraCaptureSession.setRepeatingRequest( - captureRequestBuilder.build(), pictureCaptureCallback, null); - } catch (CameraAccessException e) { - pictureCaptureRequest.error("cameraAccess", e.getMessage(), null); + refreshPreviewCaptureSession( + () -> result.success(null), + (code, message) -> result.error("setFlashModeFailed", "Could not set flash mode.", null)); } } public void setExposureMode(@NonNull final Result result, ExposureMode mode) throws CameraAccessException { - this.exposureMode = mode; - initPreviewCaptureBuilder(); + updateExposure(mode); cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); result.success(null); } @@ -713,10 +763,9 @@ public void setExposurePoint(@NonNull final Result result, Double x, Double y) // Set the metering rectangle cameraRegions.setAutoExposureMeteringRectangleFromPoint(x, y); // Apply it - initPreviewCaptureBuilder(); - this.cameraCaptureSession.setRepeatingRequest( - captureRequestBuilder.build(), pictureCaptureCallback, null); - result.success(null); + updateExposure(exposureMode); + refreshPreviewCaptureSession( + () -> result.success(null), (code, message) -> result.error("CameraAccess", message, null)); } @TargetApi(VERSION_CODES.P) @@ -802,13 +851,97 @@ public void setExposureOffset(@NonNull final Result result, double offset) double stepSize = getExposureOffsetStepSize(); exposureOffset = (int) (offset / stepSize); // Apply it - initPreviewCaptureBuilder(); + updateExposure(exposureMode); this.cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); result.success(offset); } - private void initPreviewCaptureBuilder() { - captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO); + public float getMaxZoomLevel() { + return cameraZoom.maxZoom; + } + + public float getMinZoomLevel() { + return CameraZoom.DEFAULT_ZOOM_FACTOR; + } + + public void setZoomLevel(@NonNull final Result result, float zoom) throws CameraAccessException { + float maxZoom = cameraZoom.maxZoom; + float minZoom = CameraZoom.DEFAULT_ZOOM_FACTOR; + + if (zoom > maxZoom || zoom < minZoom) { + String errorMessage = + String.format( + Locale.ENGLISH, + "Zoom level out of bounds (zoom level should be between %f and %f).", + minZoom, + maxZoom); + result.error("ZOOM_ERROR", errorMessage, null); + return; + } + + //Zoom area is calculated relative to sensor area (activeRect) + if (captureRequestBuilder != null) { + final Rect computedZoom = cameraZoom.computeZoom(zoom); + captureRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, computedZoom); + cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); + } + + result.success(null); + } + + private void updateFpsRange() { + if (fpsRange == null) { + return; + } + + captureRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange); + } + + private void updateAutoFocus() { + if (useAutoFocus) { + int[] modes = cameraCharacteristics.get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES); + // Auto focus is not supported + if (modes == null + || modes.length == 0 + || (modes.length == 1 && modes[0] == CameraCharacteristics.CONTROL_AF_MODE_OFF)) { + useAutoFocus = false; + captureRequestBuilder.set( + CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF); + } else { + captureRequestBuilder.set( + CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); + } + } else { + captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF); + } + } + + private void updateExposure(ExposureMode mode) { + exposureMode = mode; + + // Applying auto exposure + MeteringRectangle aeRect = cameraRegions.getAEMeteringRectangle(); + captureRequestBuilder.set( + CaptureRequest.CONTROL_AE_REGIONS, + aeRect == null ? null : new MeteringRectangle[] {cameraRegions.getAEMeteringRectangle()}); + + switch (mode) { + case locked: + captureRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true); + break; + case auto: + default: + captureRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false); + break; + } + + captureRequestBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, exposureOffset); + } + + private void updateFlash(FlashMode mode) { + // Get flash + flashMode = mode; + // Applying flash modes switch (flashMode) { case off: @@ -833,24 +966,6 @@ private void initPreviewCaptureBuilder() { captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH); break; } - // Applying auto exposure - MeteringRectangle aeRect = cameraRegions.getAEMeteringRectangle(); - captureRequestBuilder.set( - CaptureRequest.CONTROL_AE_REGIONS, - aeRect == null ? null : new MeteringRectangle[] {cameraRegions.getAEMeteringRectangle()}); - switch (exposureMode) { - case locked: - captureRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true); - break; - case auto: - default: - captureRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false); - break; - } - captureRequestBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, exposureOffset); - // Applying auto focus - captureRequestBuilder.set( - CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); } public void startPreview() throws CameraAccessException { @@ -910,39 +1025,6 @@ private void setImageStreamImageAvailableListener(final EventChannel.EventSink i null); } - public float getMaxZoomLevel() { - return cameraZoom.maxZoom; - } - - public float getMinZoomLevel() { - return CameraZoom.DEFAULT_ZOOM_FACTOR; - } - - public void setZoomLevel(@NonNull final Result result, float zoom) throws CameraAccessException { - float maxZoom = cameraZoom.maxZoom; - float minZoom = CameraZoom.DEFAULT_ZOOM_FACTOR; - - if (zoom > maxZoom || zoom < minZoom) { - String errorMessage = - String.format( - Locale.ENGLISH, - "Zoom level out of bounds (zoom level should be between %f and %f).", - minZoom, - maxZoom); - result.error("ZOOM_ERROR", errorMessage, null); - return; - } - - //Zoom area is calculated relative to sensor area (activeRect) - if (captureRequestBuilder != null) { - final Rect computedZoom = cameraZoom.computeZoom(zoom); - captureRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, computedZoom); - cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null); - } - - result.success(null); - } - public void stopImageStream() throws CameraAccessException { if (imageStreamReader != null) { imageStreamReader.setOnImageAvailableListener(null, null); diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 02f874bf9ea3..99f41fb165a5 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.6.4+2 +version: 0.6.4+3 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From dac4b6f3c692cc4aabe0e0430106e6ec2c061afe Mon Sep 17 00:00:00 2001 From: Bodhi Mulders Date: Wed, 6 Jan 2021 23:48:03 +0100 Subject: [PATCH 0018/1565] [camera_platform_interface] Add platform interface methods for setting auto focus. (#3369) * Added platform interface methods for setting auto exposure. * Added platform interface methods for setting auto exposure. * Remove workspace files * Added auto exposure implementations for Android and iOS * Added platform interface methods for managing auto focus. * Formatted code * Export focus mode * Update platform interface for changes to autofocus methods * Revert "Update platform interface for changes to autofocus methods" This reverts commit bdeed1d213a9f106d0bd80b8905c0ae3af29886e. * iOS fix for setting the exposure point * Removed unnecessary check * Updated changelog and pubspec.yaml * Update platform interface dependency * Implement PR feedback * Restore test * Revert test change * Update camera pubspec * Update platform interface to prevent breaking changes with current master Co-authored-by: Maurits van Beusekom --- .../camera_platform_interface/CHANGELOG.md | 4 + .../lib/src/events/camera_event.dart | 30 ++++-- .../method_channel/method_channel_camera.dart | 28 ++++++ .../platform_interface/camera_platform.dart | 13 ++- .../lib/src/types/exposure_mode.dart | 2 + .../lib/src/types/focus_mode.dart | 38 +++++++ .../lib/src/types/types.dart | 1 + .../camera_platform_interface/pubspec.yaml | 2 +- .../test/camera_platform_interface_test.dart | 26 +++++ .../test/events/camera_event_test.dart | 99 ++++++++++++------- .../method_channel_camera_test.dart | 59 +++++++++++ .../test/types/focus_mode_test.dart | 31 ++++++ 12 files changed, 291 insertions(+), 42 deletions(-) create mode 100644 packages/camera/camera_platform_interface/lib/src/types/focus_mode.dart create mode 100644 packages/camera/camera_platform_interface/test/types/focus_mode_test.dart diff --git a/packages/camera/camera_platform_interface/CHANGELOG.md b/packages/camera/camera_platform_interface/CHANGELOG.md index d264d6c6f9ce..ae22f8a5f6a4 100644 --- a/packages/camera/camera_platform_interface/CHANGELOG.md +++ b/packages/camera/camera_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.4.0 + +- Added interface methods to support auto focus. + ## 1.3.0 - Introduces an option to set the image format when initializing. diff --git a/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart b/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart index 590713d04e8b..8ca445a2e06e 100644 --- a/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart +++ b/packages/camera/camera_platform_interface/lib/src/events/camera_event.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 'package:camera_platform_interface/src/types/focus_mode.dart'; + import '../../camera_platform_interface.dart'; /// Generic Event coming from the native side of Camera. @@ -50,9 +52,15 @@ class CameraInitializedEvent extends CameraEvent { /// The default exposure mode final ExposureMode exposureMode; + /// The default focus mode + final FocusMode focusMode; + /// Whether setting exposure points is supported. final bool exposurePointSupported; + /// Whether setting focus points is supported. + final bool focusPointSupported; + /// Build a CameraInitialized event triggered from the camera represented by /// `cameraId`. /// @@ -61,10 +69,12 @@ class CameraInitializedEvent extends CameraEvent { CameraInitializedEvent( int cameraId, this.previewWidth, - this.previewHeight, + this.previewHeight, [ this.exposureMode, - this.exposurePointSupported, - ) : super(cameraId); + this.exposurePointSupported = false, + this.focusMode, + this.focusPointSupported = false, + ]) : super(cameraId); /// Converts the supplied [Map] to an instance of the [CameraInitializedEvent] /// class. @@ -72,7 +82,9 @@ class CameraInitializedEvent extends CameraEvent { : previewWidth = json['previewWidth'], previewHeight = json['previewHeight'], exposureMode = deserializeExposureMode(json['exposureMode']), - exposurePointSupported = json['exposurePointSupported'], + exposurePointSupported = json['exposurePointSupported'] ?? false, + focusMode = deserializeFocusMode(json['focusMode']), + focusPointSupported = json['focusPointSupported'] ?? false, super(json['cameraId']); /// Converts the [CameraInitializedEvent] instance into a [Map] instance that @@ -83,6 +95,8 @@ class CameraInitializedEvent extends CameraEvent { 'previewHeight': previewHeight, 'exposureMode': serializeExposureMode(exposureMode), 'exposurePointSupported': exposurePointSupported, + 'focusMode': serializeFocusMode(focusMode), + 'focusPointSupported': focusPointSupported, }; @override @@ -94,7 +108,9 @@ class CameraInitializedEvent extends CameraEvent { previewWidth == other.previewWidth && previewHeight == other.previewHeight && exposureMode == other.exposureMode && - exposurePointSupported == other.exposurePointSupported; + exposurePointSupported == other.exposurePointSupported && + focusMode == other.focusMode && + focusPointSupported == other.focusPointSupported; @override int get hashCode => @@ -102,7 +118,9 @@ class CameraInitializedEvent extends CameraEvent { previewWidth.hashCode ^ previewHeight.hashCode ^ exposureMode.hashCode ^ - exposurePointSupported.hashCode; + exposurePointSupported.hashCode ^ + focusMode.hashCode ^ + focusPointSupported.hashCode; } /// An event fired when the resolution preset of the camera has changed. diff --git a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart index 0ccc59939610..d23271e59844 100644 --- a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart +++ b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart @@ -6,6 +6,7 @@ import 'dart:async'; import 'dart:math'; import 'package:camera_platform_interface/camera_platform_interface.dart'; +import 'package:camera_platform_interface/src/types/focus_mode.dart'; import 'package:camera_platform_interface/src/types/image_format_group.dart'; import 'package:camera_platform_interface/src/utils/utils.dart'; import 'package:cross_file/cross_file.dart'; @@ -249,6 +250,31 @@ class MethodChannelCamera extends CameraPlatform { }, ); + @override + Future setFocusMode(int cameraId, FocusMode mode) => + _channel.invokeMethod( + 'setFocusMode', + { + 'cameraId': cameraId, + 'mode': serializeFocusMode(mode), + }, + ); + + @override + Future setFocusPoint(int cameraId, Point point) { + assert(point == null || point.x >= 0 && point.x <= 1); + assert(point == null || point.y >= 0 && point.y <= 1); + return _channel.invokeMethod( + 'setFocusPoint', + { + 'cameraId': cameraId, + 'reset': point == null, + 'x': point?.x, + 'y': point?.y, + }, + ); + } + @override Future getMaxZoomLevel(int cameraId) => _channel.invokeMethod( 'getMaxZoomLevel', @@ -331,6 +357,8 @@ class MethodChannelCamera extends CameraPlatform { call.arguments['previewHeight'], deserializeExposureMode(call.arguments['exposureMode']), call.arguments['exposurePointSupported'], + deserializeFocusMode(call.arguments['focusMode']), + call.arguments['focusPointSupported'], )); break; case 'resolution_changed': diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart index d95d957e4862..fcd85436c365 100644 --- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart +++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart @@ -8,6 +8,7 @@ import 'dart:math'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:camera_platform_interface/src/method_channel/method_channel_camera.dart'; import 'package:camera_platform_interface/src/types/exposure_mode.dart'; +import 'package:camera_platform_interface/src/types/focus_mode.dart'; import 'package:camera_platform_interface/src/types/image_format_group.dart'; import 'package:cross_file/cross_file.dart'; import 'package:flutter/widgets.dart'; @@ -129,7 +130,7 @@ abstract class CameraPlatform extends PlatformInterface { throw UnimplementedError('setExposureMode() is not implemented.'); } - /// Sets the exposure point for automatically determining the exposure value. + /// Sets the exposure point for automatically determining the exposure values. Future setExposurePoint(int cameraId, Point point) { throw UnimplementedError('setExposurePoint() is not implemented.'); } @@ -166,6 +167,16 @@ abstract class CameraPlatform extends PlatformInterface { throw UnimplementedError('setExposureOffset() is not implemented.'); } + /// Sets the focus mode for taking pictures. + Future setFocusMode(int cameraId, FocusMode mode) { + throw UnimplementedError('setFocusMode() is not implemented.'); + } + + /// Sets the focus point for automatically determining the focus values. + Future setFocusPoint(int cameraId, Point point) { + throw UnimplementedError('setFocusPoint() is not implemented.'); + } + /// Gets the maximum supported zoom level for the selected camera. Future getMaxZoomLevel(int cameraId) { throw UnimplementedError('getMaxZoomLevel() is not implemented.'); diff --git a/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart b/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart index 836f53826479..7fbfbaf5f4a9 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart @@ -13,6 +13,7 @@ enum ExposureMode { /// Returns the exposure mode as a String. String serializeExposureMode(ExposureMode exposureMode) { + if (exposureMode == null) return null; switch (exposureMode) { case ExposureMode.locked: return 'locked'; @@ -25,6 +26,7 @@ String serializeExposureMode(ExposureMode exposureMode) { /// Returns the exposure mode for a given String. ExposureMode deserializeExposureMode(String str) { + if (str == null) return null; switch (str) { case "locked": return ExposureMode.locked; diff --git a/packages/camera/camera_platform_interface/lib/src/types/focus_mode.dart b/packages/camera/camera_platform_interface/lib/src/types/focus_mode.dart new file mode 100644 index 000000000000..ad5e9a2d46f1 --- /dev/null +++ b/packages/camera/camera_platform_interface/lib/src/types/focus_mode.dart @@ -0,0 +1,38 @@ +// Copyright 2019 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. + +/// The possible focus modes that can be set for a camera. +enum FocusMode { + /// Automatically determine focus settings. + auto, + + /// Lock the currently determined focus settings. + locked, +} + +/// Returns the focus mode as a String. +String serializeFocusMode(FocusMode focusMode) { + if (focusMode == null) return null; + switch (focusMode) { + case FocusMode.locked: + return 'locked'; + case FocusMode.auto: + return 'auto'; + default: + throw ArgumentError('Unknown FocusMode value'); + } +} + +/// Returns the focus mode for a given String. +FocusMode deserializeFocusMode(String str) { + if (str == null) return null; + switch (str) { + case "locked": + return FocusMode.locked; + case "auto": + return FocusMode.auto; + default: + throw ArgumentError('"$str" is not a valid FocusMode value'); + } +} diff --git a/packages/camera/camera_platform_interface/lib/src/types/types.dart b/packages/camera/camera_platform_interface/lib/src/types/types.dart index eaadc5c14061..256558dff3e7 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/types.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/types.dart @@ -8,3 +8,4 @@ export 'camera_exception.dart'; export 'flash_mode.dart'; export 'image_format_group.dart'; export 'exposure_mode.dart'; +export 'focus_mode.dart'; diff --git a/packages/camera/camera_platform_interface/pubspec.yaml b/packages/camera/camera_platform_interface/pubspec.yaml index 7a4fa49ce052..a6d0b815e660 100644 --- a/packages/camera/camera_platform_interface/pubspec.yaml +++ b/packages/camera/camera_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the camera plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.3.0 +version: 1.4.0 dependencies: flutter: diff --git a/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart b/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart index 574fa45e7b81..80316317e698 100644 --- a/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart +++ b/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart @@ -264,6 +264,32 @@ void main() { ); }); + test( + 'Default implementation of setFocusMode() should throw unimplemented error', + () { + // Arrange + final cameraPlatform = ExtendsCameraPlatform(); + + // Act & Assert + expect( + () => cameraPlatform.setFocusMode(1, null), + throwsUnimplementedError, + ); + }); + + test( + 'Default implementation of setFocusPoint() should throw unimplemented error', + () { + // Arrange + final cameraPlatform = ExtendsCameraPlatform(); + + // Act & Assert + expect( + () => cameraPlatform.setFocusPoint(1, null), + throwsUnimplementedError, + ); + }); + test( 'Default implementation of startVideoRecording() should throw unimplemented error', () { diff --git a/packages/camera/camera_platform_interface/test/events/camera_event_test.dart b/packages/camera/camera_platform_interface/test/events/camera_event_test.dart index 1e28fa689383..f146b7e7e7bc 100644 --- a/packages/camera/camera_platform_interface/test/events/camera_event_test.dart +++ b/packages/camera/camera_platform_interface/test/events/camera_event_test.dart @@ -4,6 +4,7 @@ import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:camera_platform_interface/src/types/exposure_mode.dart'; +import 'package:camera_platform_interface/src/types/focus_mode.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { @@ -11,14 +12,16 @@ void main() { group('CameraInitializedEvent tests', () { test('Constructor should initialize all properties', () { - final event = - CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); + final event = CameraInitializedEvent( + 1, 1024, 640, ExposureMode.auto, true, FocusMode.auto, true); expect(event.cameraId, 1); expect(event.previewWidth, 1024); expect(event.previewHeight, 640); expect(event.exposureMode, ExposureMode.auto); + expect(event.focusMode, FocusMode.auto); expect(event.exposurePointSupported, true); + expect(event.focusPointSupported, true); }); test('fromJson should initialize all properties', () { @@ -26,92 +29,120 @@ void main() { 'cameraId': 1, 'previewWidth': 1024.0, 'previewHeight': 640.0, - 'exposureMode': 'auto' + 'exposureMode': 'auto', + 'exposurePointSupported': true, + 'focusMode': 'auto', + 'focusPointSupported': true }); expect(event.cameraId, 1); expect(event.previewWidth, 1024); expect(event.previewHeight, 640); expect(event.exposureMode, ExposureMode.auto); + expect(event.exposurePointSupported, true); + expect(event.focusMode, FocusMode.auto); + expect(event.focusPointSupported, true); }); test('toJson should return a map with all fields', () { - final event = - CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); + final event = CameraInitializedEvent( + 1, 1024, 640, ExposureMode.auto, true, FocusMode.auto, true); final jsonMap = event.toJson(); - expect(jsonMap.length, 5); + expect(jsonMap.length, 7); expect(jsonMap['cameraId'], 1); expect(jsonMap['previewWidth'], 1024); expect(jsonMap['previewHeight'], 640); expect(jsonMap['exposureMode'], 'auto'); expect(jsonMap['exposurePointSupported'], true); + expect(jsonMap['focusMode'], 'auto'); + expect(jsonMap['focusPointSupported'], true); }); test('equals should return true if objects are the same', () { - final firstEvent = - CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); - final secondEvent = - CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); + final firstEvent = CameraInitializedEvent( + 1, 1024, 640, ExposureMode.auto, true, FocusMode.auto, true); + final secondEvent = CameraInitializedEvent( + 1, 1024, 640, ExposureMode.auto, true, FocusMode.auto, true); expect(firstEvent == secondEvent, true); }); test('equals should return false if cameraId is different', () { - final firstEvent = - CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); - final secondEvent = - CameraInitializedEvent(2, 1024, 640, ExposureMode.auto, true); + final firstEvent = CameraInitializedEvent( + 1, 1024, 640, ExposureMode.auto, true, FocusMode.auto, true); + final secondEvent = CameraInitializedEvent( + 2, 1024, 640, ExposureMode.auto, true, FocusMode.auto, true); expect(firstEvent == secondEvent, false); }); test('equals should return false if previewWidth is different', () { - final firstEvent = - CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); - final secondEvent = - CameraInitializedEvent(1, 2048, 640, ExposureMode.auto, true); + final firstEvent = CameraInitializedEvent( + 1, 1024, 640, ExposureMode.auto, true, FocusMode.auto, true); + final secondEvent = CameraInitializedEvent( + 1, 2048, 640, ExposureMode.auto, true, FocusMode.auto, true); expect(firstEvent == secondEvent, false); }); test('equals should return false if previewHeight is different', () { - final firstEvent = - CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); - final secondEvent = - CameraInitializedEvent(1, 1024, 980, ExposureMode.auto, true); + final firstEvent = CameraInitializedEvent( + 1, 1024, 640, ExposureMode.auto, true, FocusMode.auto, true); + final secondEvent = CameraInitializedEvent( + 1, 1024, 980, ExposureMode.auto, true, FocusMode.auto, true); expect(firstEvent == secondEvent, false); }); test('equals should return false if exposureMode is different', () { - final firstEvent = - CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); - final secondEvent = - CameraInitializedEvent(1, 1024, 640, ExposureMode.locked, true); + final firstEvent = CameraInitializedEvent( + 1, 1024, 640, ExposureMode.auto, true, FocusMode.auto, true); + final secondEvent = CameraInitializedEvent( + 1, 1024, 640, ExposureMode.locked, true, FocusMode.auto, true); expect(firstEvent == secondEvent, false); }); test('equals should return false if exposurePointSupported is different', () { - final firstEvent = - CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); - final secondEvent = - CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, false); + final firstEvent = CameraInitializedEvent( + 1, 1024, 640, ExposureMode.auto, true, FocusMode.auto, true); + final secondEvent = CameraInitializedEvent( + 1, 1024, 640, ExposureMode.auto, false, FocusMode.auto, true); + + expect(firstEvent == secondEvent, false); + }); + + test('equals should return false if focusMode is different', () { + final firstEvent = CameraInitializedEvent( + 1, 1024, 640, ExposureMode.auto, true, FocusMode.auto, true); + final secondEvent = CameraInitializedEvent( + 1, 1024, 640, ExposureMode.auto, true, FocusMode.locked, true); + + expect(firstEvent == secondEvent, false); + }); + + test('equals should return false if focusPointSupported is different', () { + final firstEvent = CameraInitializedEvent( + 1, 1024, 640, ExposureMode.auto, true, FocusMode.auto, true); + final secondEvent = CameraInitializedEvent( + 1, 1024, 640, ExposureMode.auto, true, FocusMode.auto, false); expect(firstEvent == secondEvent, false); }); test('hashCode should match hashCode of all properties', () { - final event = - CameraInitializedEvent(1, 1024, 640, ExposureMode.auto, true); - final expectedHashCode = event.cameraId ^ + final event = CameraInitializedEvent( + 1, 1024, 640, ExposureMode.auto, true, FocusMode.auto, true); + final expectedHashCode = event.cameraId.hashCode ^ event.previewWidth.hashCode ^ event.previewHeight.hashCode ^ event.exposureMode.hashCode ^ - event.exposurePointSupported.hashCode; + event.exposurePointSupported.hashCode ^ + event.focusMode.hashCode ^ + event.focusPointSupported.hashCode; expect(event.hashCode, expectedHashCode); }); diff --git a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart index e8136fb051ad..550be358f7c9 100644 --- a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart +++ b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart @@ -8,6 +8,7 @@ import 'dart:math'; import 'package:async/async.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:camera_platform_interface/src/method_channel/method_channel_camera.dart'; +import 'package:camera_platform_interface/src/types/focus_mode.dart'; import 'package:camera_platform_interface/src/utils/utils.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; @@ -131,6 +132,8 @@ void main() { 1080, ExposureMode.auto, true, + FocusMode.auto, + true, )); await initializeFuture; @@ -170,6 +173,8 @@ void main() { 1080, ExposureMode.auto, true, + FocusMode.auto, + true, )); await initializeFuture; @@ -212,6 +217,8 @@ void main() { 1080, ExposureMode.auto, true, + FocusMode.auto, + true, )); await initializeFuture; }); @@ -229,6 +236,8 @@ void main() { 2160, ExposureMode.auto, true, + FocusMode.auto, + true, ); await camera.handleMethodCall( MethodCall('initialized', event.toJson()), cameraId); @@ -340,6 +349,8 @@ void main() { 1080, ExposureMode.auto, true, + FocusMode.auto, + true, ), ); await initializeFuture; @@ -679,6 +690,54 @@ void main() { ]); }); + test('Should set the focus mode', () async { + // Arrange + MethodChannelMock channel = MethodChannelMock( + channelName: 'plugins.flutter.io/camera', + methods: {'setFocusMode': null}, + ); + + // Act + await camera.setFocusMode(cameraId, FocusMode.auto); + await camera.setFocusMode(cameraId, FocusMode.locked); + + // Assert + expect(channel.log, [ + isMethodCall('setFocusMode', + arguments: {'cameraId': cameraId, 'mode': 'auto'}), + isMethodCall('setFocusMode', + arguments: {'cameraId': cameraId, 'mode': 'locked'}), + ]); + }); + + test('Should set the exposure point', () async { + // Arrange + MethodChannelMock channel = MethodChannelMock( + channelName: 'plugins.flutter.io/camera', + methods: {'setFocusPoint': null}, + ); + + // Act + await camera.setFocusPoint(cameraId, Point(0.5, 0.5)); + await camera.setFocusPoint(cameraId, null); + + // Assert + expect(channel.log, [ + isMethodCall('setFocusPoint', arguments: { + 'cameraId': cameraId, + 'x': 0.5, + 'y': 0.5, + 'reset': false + }), + isMethodCall('setFocusPoint', arguments: { + 'cameraId': cameraId, + 'x': null, + 'y': null, + 'reset': true + }), + ]); + }); + test('Should build a texture widget as preview widget', () async { // Act Widget widget = camera.buildPreview(cameraId); diff --git a/packages/camera/camera_platform_interface/test/types/focus_mode_test.dart b/packages/camera/camera_platform_interface/test/types/focus_mode_test.dart new file mode 100644 index 000000000000..ca7ad902820a --- /dev/null +++ b/packages/camera/camera_platform_interface/test/types/focus_mode_test.dart @@ -0,0 +1,31 @@ +// Copyright 2019 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. + +import 'package:camera_platform_interface/src/types/focus_mode.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + test('FocusMode should contain 2 options', () { + final values = FocusMode.values; + + expect(values.length, 2); + }); + + test("FocusMode enum should have items in correct index", () { + final values = FocusMode.values; + + expect(values[0], FocusMode.auto); + expect(values[1], FocusMode.locked); + }); + + test("serializeFocusMode() should serialize correctly", () { + expect(serializeFocusMode(FocusMode.auto), "auto"); + expect(serializeFocusMode(FocusMode.locked), "locked"); + }); + + test("deserializeFocusMode() should deserialize correctly", () { + expect(deserializeFocusMode('auto'), FocusMode.auto); + expect(deserializeFocusMode('locked'), FocusMode.locked); + }); +} From 43ee609f0262ac3c74712971b2bf73160216f520 Mon Sep 17 00:00:00 2001 From: Bodhi Mulders Date: Thu, 7 Jan 2021 10:08:19 +0100 Subject: [PATCH 0019/1565] [camera_platform_interface] Add platform interface methods for locking capture orientation. (#3389) * Expand platform interface to support reporting device orientation * Switch to flutter DeviceOrientation enum * Add interface methods for (un)locking the capture orientation. * Update capture orientation interfaces and add unit tests. * Made device orientation mandatory for locking capture orientation in the platform interface. * Update comment * Update comment. * Update changelog and pubspec version * Update packages/camera/camera_platform_interface/lib/src/events/device_event.dart Co-authored-by: Maurits van Beusekom * Update packages/camera/camera_platform_interface/lib/src/events/device_event.dart Co-authored-by: Maurits van Beusekom * Update packages/camera/camera_platform_interface/lib/src/events/device_event.dart Co-authored-by: Maurits van Beusekom * Update packages/camera/camera_platform_interface/lib/src/events/device_event.dart Co-authored-by: Maurits van Beusekom * Update packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart Co-authored-by: Maurits van Beusekom * Update packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart Co-authored-by: Maurits van Beusekom Co-authored-by: Maurits van Beusekom Co-authored-by: Maurits van Beusekom --- .../camera_platform_interface/CHANGELOG.md | 5 ++ .../lib/camera_platform_interface.dart | 1 + .../lib/src/events/camera_event.dart | 3 +- .../lib/src/events/device_event.dart | 52 +++++++++++ .../method_channel/method_channel_camera.dart | 78 +++++++++++++++-- .../platform_interface/camera_platform.dart | 23 +++++ .../lib/src/utils/utils.dart | 33 +++++++ .../camera_platform_interface/pubspec.yaml | 2 +- .../test/camera_platform_interface_test.dart | 39 +++++++++ .../test/events/device_event_test.dart | 61 +++++++++++++ .../method_channel_camera_test.dart | 87 ++++++++++++++++--- .../test/utils/utils_test.dart | 23 +++++ 12 files changed, 384 insertions(+), 23 deletions(-) create mode 100644 packages/camera/camera_platform_interface/lib/src/events/device_event.dart create mode 100644 packages/camera/camera_platform_interface/test/events/device_event_test.dart diff --git a/packages/camera/camera_platform_interface/CHANGELOG.md b/packages/camera/camera_platform_interface/CHANGELOG.md index ae22f8a5f6a4..d7442d4ac931 100644 --- a/packages/camera/camera_platform_interface/CHANGELOG.md +++ b/packages/camera/camera_platform_interface/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.5.0 + +- Introduces interface methods for locking and unlocking the capture orientation. +- Introduces interface method for listening to the device orientation. + ## 1.4.0 - Added interface methods to support auto focus. diff --git a/packages/camera/camera_platform_interface/lib/camera_platform_interface.dart b/packages/camera/camera_platform_interface/lib/camera_platform_interface.dart index eaa14da45a5e..d7e5fcd0834c 100644 --- a/packages/camera/camera_platform_interface/lib/camera_platform_interface.dart +++ b/packages/camera/camera_platform_interface/lib/camera_platform_interface.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. export 'src/events/camera_event.dart'; +export 'src/events/device_event.dart'; export 'src/platform_interface/camera_platform.dart'; export 'src/types/types.dart'; diff --git a/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart b/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart index 8ca445a2e06e..d60a0a39f608 100644 --- a/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart +++ b/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart @@ -6,7 +6,8 @@ import 'package:camera_platform_interface/src/types/focus_mode.dart'; import '../../camera_platform_interface.dart'; -/// Generic Event coming from the native side of Camera. +/// Generic Event coming from the native side of Camera, +/// related to a specific camera module. /// /// All [CameraEvent]s contain the `cameraId` that originated the event. This /// should never be `null`. diff --git a/packages/camera/camera_platform_interface/lib/src/events/device_event.dart b/packages/camera/camera_platform_interface/lib/src/events/device_event.dart new file mode 100644 index 000000000000..82febcab2290 --- /dev/null +++ b/packages/camera/camera_platform_interface/lib/src/events/device_event.dart @@ -0,0 +1,52 @@ +// Copyright 2019 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. + +import 'package:camera_platform_interface/src/utils/utils.dart'; +import 'package:flutter/services.dart'; + +/// Generic Event coming from the native side of Camera, +/// not related to a specific camera module. +/// +/// This class is used as a base class for all the events that might be +/// triggered from a device, but it is never used directly as an event type. +/// +/// Do NOT instantiate new events like `DeviceEvent()` directly, +/// use a specific class instead: +/// +/// Do `class NewEvent extend DeviceEvent` when creating your own events. +/// See below for examples: `DeviceOrientationChangedEvent`... +/// These events are more semantic and more pleasant to use than raw generics. +/// They can be (and in fact, are) filtered by the `instanceof`-operator. +abstract class DeviceEvent {} + +/// The [DeviceOrientationChangedEvent] is fired every time the user changes the +/// physical orientation of the device. +class DeviceOrientationChangedEvent extends DeviceEvent { + /// The new orientation of the device + final DeviceOrientation orientation; + + /// Build a new orientation changed event. + DeviceOrientationChangedEvent(this.orientation); + + /// Converts the supplied [Map] to an instance of the [DeviceOrientationChangedEvent] + /// class. + DeviceOrientationChangedEvent.fromJson(Map json) + : orientation = deserializeDeviceOrientation(json['orientation']); + + /// Converts the [DeviceOrientationChangedEvent] instance into a [Map] instance that + /// can be serialized to JSON. + Map toJson() => { + 'orientation': serializeDeviceOrientation(orientation), + }; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is DeviceOrientationChangedEvent && + runtimeType == other.runtimeType && + orientation == other.orientation; + + @override + int get hashCode => orientation.hashCode; +} diff --git a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart index d23271e59844..e6f658c45365 100644 --- a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart +++ b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart @@ -6,6 +6,7 @@ import 'dart:async'; import 'dart:math'; import 'package:camera_platform_interface/camera_platform_interface.dart'; +import 'package:camera_platform_interface/src/events/device_event.dart'; import 'package:camera_platform_interface/src/types/focus_mode.dart'; import 'package:camera_platform_interface/src/types/image_format_group.dart'; import 'package:camera_platform_interface/src/utils/utils.dart'; @@ -22,7 +23,7 @@ class MethodChannelCamera extends CameraPlatform { final Map _channels = {}; /// The controller we need to broadcast the different events coming - /// from handleMethodCall. + /// from handleMethodCall, specific to camera events. /// /// It is a `broadcast` because multiple controllers will connect to /// different stream views of this Controller. @@ -32,10 +33,28 @@ class MethodChannelCamera extends CameraPlatform { final StreamController cameraEventStreamController = StreamController.broadcast(); - Stream _events(int cameraId) => + /// The controller we need to broadcast the different events coming + /// from handleMethodCall, specific to general device events. + /// + /// It is a `broadcast` because multiple controllers will connect to + /// different stream views of this Controller. + /// This is only exposed for test purposes. It shouldn't be used by clients of + /// the plugin as it may break or change at any time. + @visibleForTesting + final StreamController deviceEventStreamController = + StreamController.broadcast(); + + Stream _cameraEvents(int cameraId) => cameraEventStreamController.stream .where((event) => event.cameraId == cameraId); + /// Construct a new method channel camera instance. + MethodChannelCamera() { + final channel = MethodChannel('flutter.io/cameraPlugin/device'); + channel.setMethodCallHandler( + (MethodCall call) => handleDeviceMethodCall(call)); + } + @override Future> availableCameras() async { try { @@ -83,7 +102,7 @@ class MethodChannelCamera extends CameraPlatform { _channels.putIfAbsent(cameraId, () { final channel = MethodChannel('flutter.io/cameraPlugin/camera$cameraId'); channel.setMethodCallHandler( - (MethodCall call) => handleMethodCall(call, cameraId)); + (MethodCall call) => handleCameraMethodCall(call, cameraId)); return channel; }); @@ -119,22 +138,48 @@ class MethodChannelCamera extends CameraPlatform { @override Stream onCameraInitialized(int cameraId) { - return _events(cameraId).whereType(); + return _cameraEvents(cameraId).whereType(); } @override Stream onCameraResolutionChanged(int cameraId) { - return _events(cameraId).whereType(); + return _cameraEvents(cameraId).whereType(); } @override Stream onCameraClosing(int cameraId) { - return _events(cameraId).whereType(); + return _cameraEvents(cameraId).whereType(); } @override Stream onCameraError(int cameraId) { - return _events(cameraId).whereType(); + return _cameraEvents(cameraId).whereType(); + } + + @override + Stream onDeviceOrientationChanged() { + return deviceEventStreamController.stream + .whereType(); + } + + @override + Future lockCaptureOrientation( + int cameraId, DeviceOrientation orientation) async { + await _channel.invokeMethod( + 'lockCaptureOrientation', + { + 'cameraId': cameraId, + 'orientation': serializeDeviceOrientation(orientation) + }, + ); + } + + @override + Future unlockCaptureOrientation(int cameraId) async { + await _channel.invokeMethod( + 'unlockCaptureOrientation', + {'cameraId': cameraId}, + ); } @override @@ -343,12 +388,27 @@ class MethodChannelCamera extends CameraPlatform { } } - /// Converts messages received from the native platform into events. + /// Converts messages received from the native platform into device events. + /// + /// This is only exposed for test purposes. It shouldn't be used by clients of + /// the plugin as it may break or change at any time. + Future handleDeviceMethodCall(MethodCall call) async { + switch (call.method) { + case 'orientation_changed': + deviceEventStreamController.add(DeviceOrientationChangedEvent( + deserializeDeviceOrientation(call.arguments['orientation']))); + break; + default: + throw MissingPluginException(); + } + } + + /// Converts messages received from the native platform into camera events. /// /// This is only exposed for test purposes. It shouldn't be used by clients of /// the plugin as it may break or change at any time. @visibleForTesting - Future handleMethodCall(MethodCall call, int cameraId) async { + Future handleCameraMethodCall(MethodCall call, int cameraId) async { switch (call.method) { case 'initialized': cameraEventStreamController.add(CameraInitializedEvent( diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart index fcd85436c365..c1d6e09c3263 100644 --- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart +++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart @@ -6,11 +6,13 @@ import 'dart:async'; import 'dart:math'; import 'package:camera_platform_interface/camera_platform_interface.dart'; +import 'package:camera_platform_interface/src/events/device_event.dart'; import 'package:camera_platform_interface/src/method_channel/method_channel_camera.dart'; import 'package:camera_platform_interface/src/types/exposure_mode.dart'; import 'package:camera_platform_interface/src/types/focus_mode.dart'; import 'package:camera_platform_interface/src/types/image_format_group.dart'; import 'package:cross_file/cross_file.dart'; +import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; @@ -85,6 +87,27 @@ abstract class CameraPlatform extends PlatformInterface { throw UnimplementedError('onCameraError() is not implemented.'); } + /// The device orientation changed. + /// + /// Implementations for this: + /// - Should support all 4 orientations. + /// - Should not emit new values when the screen orientation is locked. + Stream onDeviceOrientationChanged() { + throw UnimplementedError( + 'onDeviceOrientationChanged() is not implemented.'); + } + + /// Locks the capture orientation. + Future lockCaptureOrientation( + int cameraId, DeviceOrientation orientation) { + throw UnimplementedError('lockCaptureOrientation() is not implemented.'); + } + + /// Unlocks the capture orientation. + Future unlockCaptureOrientation(int cameraId) { + throw UnimplementedError('unlockCaptureOrientation() is not implemented.'); + } + /// Captures an image and returns the file where it was saved. Future takePicture(int cameraId) { throw UnimplementedError('takePicture() is not implemented.'); diff --git a/packages/camera/camera_platform_interface/lib/src/utils/utils.dart b/packages/camera/camera_platform_interface/lib/src/utils/utils.dart index f94d8e69c07e..5413f25bb8b7 100644 --- a/packages/camera/camera_platform_interface/lib/src/utils/utils.dart +++ b/packages/camera/camera_platform_interface/lib/src/utils/utils.dart @@ -1,4 +1,5 @@ import 'package:camera_platform_interface/camera_platform_interface.dart'; +import 'package:flutter/services.dart'; /// Parses a string into a corresponding CameraLensDirection. CameraLensDirection parseCameraLensDirection(String string) { @@ -12,3 +13,35 @@ CameraLensDirection parseCameraLensDirection(String string) { } throw ArgumentError('Unknown CameraLensDirection value'); } + +/// Returns the device orientation as a String. +String serializeDeviceOrientation(DeviceOrientation orientation) { + switch (orientation) { + case DeviceOrientation.portraitUp: + return 'portraitUp'; + case DeviceOrientation.portraitDown: + return 'portraitDown'; + case DeviceOrientation.landscapeRight: + return 'landscapeRight'; + case DeviceOrientation.landscapeLeft: + return 'landscapeLeft'; + default: + throw ArgumentError('Unknown DeviceOrientation value'); + } +} + +/// Returns the device orientation for a given String. +DeviceOrientation deserializeDeviceOrientation(String str) { + switch (str) { + case "portraitUp": + return DeviceOrientation.portraitUp; + case "portraitDown": + return DeviceOrientation.portraitDown; + case "landscapeRight": + return DeviceOrientation.landscapeRight; + case "landscapeLeft": + return DeviceOrientation.landscapeLeft; + default: + throw ArgumentError('"$str" is not a valid DeviceOrientation value'); + } +} diff --git a/packages/camera/camera_platform_interface/pubspec.yaml b/packages/camera/camera_platform_interface/pubspec.yaml index a6d0b815e660..2a8d7ce9abe1 100644 --- a/packages/camera/camera_platform_interface/pubspec.yaml +++ b/packages/camera/camera_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the camera plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.4.0 +version: 1.5.0 dependencies: flutter: diff --git a/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart b/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart index 80316317e698..8baf5da34159 100644 --- a/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart +++ b/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart @@ -96,6 +96,45 @@ void main() { ); }); + test( + 'Default implementation of onDeviceOrientationChanged() should throw unimplemented error', + () { + // Arrange + final cameraPlatform = ExtendsCameraPlatform(); + + // Act & Assert + expect( + () => cameraPlatform.onDeviceOrientationChanged(), + throwsUnimplementedError, + ); + }); + + test( + 'Default implementation of lockCaptureOrientation() should throw unimplemented error', + () { + // Arrange + final cameraPlatform = ExtendsCameraPlatform(); + + // Act & Assert + expect( + () => cameraPlatform.lockCaptureOrientation(1, null), + throwsUnimplementedError, + ); + }); + + test( + 'Default implementation of unlockCaptureOrientation() should throw unimplemented error', + () { + // Arrange + final cameraPlatform = ExtendsCameraPlatform(); + + // Act & Assert + expect( + () => cameraPlatform.unlockCaptureOrientation(1), + throwsUnimplementedError, + ); + }); + test('Default implementation of dispose() should throw unimplemented error', () { // Arrange diff --git a/packages/camera/camera_platform_interface/test/events/device_event_test.dart b/packages/camera/camera_platform_interface/test/events/device_event_test.dart new file mode 100644 index 000000000000..c2fef49be04f --- /dev/null +++ b/packages/camera/camera_platform_interface/test/events/device_event_test.dart @@ -0,0 +1,61 @@ +// Copyright 2019 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. + +import 'package:camera_platform_interface/camera_platform_interface.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('DeviceOrientationChangedEvent tests', () { + test('Constructor should initialize all properties', () { + final event = DeviceOrientationChangedEvent(DeviceOrientation.portraitUp); + + expect(event.orientation, DeviceOrientation.portraitUp); + }); + + test('fromJson should initialize all properties', () { + final event = DeviceOrientationChangedEvent.fromJson({ + 'orientation': 'portraitUp', + }); + + expect(event.orientation, DeviceOrientation.portraitUp); + }); + + test('toJson should return a map with all fields', () { + final event = DeviceOrientationChangedEvent(DeviceOrientation.portraitUp); + + final jsonMap = event.toJson(); + + expect(jsonMap.length, 1); + expect(jsonMap['orientation'], 'portraitUp'); + }); + + test('equals should return true if objects are the same', () { + final firstEvent = + DeviceOrientationChangedEvent(DeviceOrientation.portraitUp); + final secondEvent = + DeviceOrientationChangedEvent(DeviceOrientation.portraitUp); + + expect(firstEvent == secondEvent, true); + }); + + test('equals should return false if orientation is different', () { + final firstEvent = + DeviceOrientationChangedEvent(DeviceOrientation.portraitUp); + final secondEvent = + DeviceOrientationChangedEvent(DeviceOrientation.landscapeLeft); + + expect(firstEvent == secondEvent, false); + }); + + test('hashCode should match hashCode of all properties', () { + final event = DeviceOrientationChangedEvent(DeviceOrientation.portraitUp); + final expectedHashCode = event.orientation.hashCode; + + expect(event.hashCode, expectedHashCode); + }); + }); +} diff --git a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart index 550be358f7c9..7e9146344206 100644 --- a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart +++ b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart @@ -7,9 +7,11 @@ import 'dart:math'; import 'package:async/async.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; +import 'package:camera_platform_interface/src/events/device_event.dart'; import 'package:camera_platform_interface/src/method_channel/method_channel_camera.dart'; import 'package:camera_platform_interface/src/types/focus_mode.dart'; import 'package:camera_platform_interface/src/utils/utils.dart'; +import 'package:flutter/services.dart' hide DeviceOrientation; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -239,7 +241,7 @@ void main() { FocusMode.auto, true, ); - await camera.handleMethodCall( + await camera.handleCameraMethodCall( MethodCall('initialized', event.toJson()), cameraId); // Assert @@ -258,13 +260,13 @@ void main() { // Emit test events final fhdEvent = CameraResolutionChangedEvent(cameraId, 1920, 1080); final uhdEvent = CameraResolutionChangedEvent(cameraId, 3840, 2160); - await camera.handleMethodCall( + await camera.handleCameraMethodCall( MethodCall('resolution_changed', fhdEvent.toJson()), cameraId); - await camera.handleMethodCall( + await camera.handleCameraMethodCall( MethodCall('resolution_changed', uhdEvent.toJson()), cameraId); - await camera.handleMethodCall( + await camera.handleCameraMethodCall( MethodCall('resolution_changed', fhdEvent.toJson()), cameraId); - await camera.handleMethodCall( + await camera.handleCameraMethodCall( MethodCall('resolution_changed', uhdEvent.toJson()), cameraId); // Assert @@ -285,11 +287,11 @@ void main() { // Emit test events final event = CameraClosingEvent(cameraId); - await camera.handleMethodCall( + await camera.handleCameraMethodCall( MethodCall('camera_closing', event.toJson()), cameraId); - await camera.handleMethodCall( + await camera.handleCameraMethodCall( MethodCall('camera_closing', event.toJson()), cameraId); - await camera.handleMethodCall( + await camera.handleCameraMethodCall( MethodCall('camera_closing', event.toJson()), cameraId); // Assert @@ -308,11 +310,11 @@ void main() { // Emit test events final event = CameraErrorEvent(cameraId, 'Error Description'); - await camera.handleMethodCall( + await camera.handleCameraMethodCall( MethodCall('error', event.toJson()), cameraId); - await camera.handleMethodCall( + await camera.handleCameraMethodCall( MethodCall('error', event.toJson()), cameraId); - await camera.handleMethodCall( + await camera.handleCameraMethodCall( MethodCall('error', event.toJson()), cameraId); // Assert @@ -323,6 +325,30 @@ void main() { // Clean up await streamQueue.cancel(); }); + + test('Should receive device orientation change events', () async { + // Act + final eventStream = camera.onDeviceOrientationChanged(); + final streamQueue = StreamQueue(eventStream); + + // Emit test events + final event = + DeviceOrientationChangedEvent(DeviceOrientation.portraitUp); + await camera.handleDeviceMethodCall( + MethodCall('orientation_changed', event.toJson())); + await camera.handleDeviceMethodCall( + MethodCall('orientation_changed', event.toJson())); + await camera.handleDeviceMethodCall( + MethodCall('orientation_changed', event.toJson())); + + // Assert + expect(await streamQueue.next, event); + expect(await streamQueue.next, event); + expect(await streamQueue.next, event); + + // Clean up + await streamQueue.cancel(); + }); }); group('Function Tests', () { @@ -751,7 +777,9 @@ void main() { () { final camera = MethodChannelCamera(); - expect(() => camera.handleMethodCall(MethodCall('unknown_method'), 1), + expect( + () => + camera.handleCameraMethodCall(MethodCall('unknown_method'), 1), throwsA(isA())); }); @@ -832,6 +860,41 @@ void main() { .having((e) => e.description, 'description', 'Illegal zoom error'))); }); + + test('Should lock the capture orientation', () async { + // Arrange + MethodChannelMock channel = MethodChannelMock( + channelName: 'plugins.flutter.io/camera', + methods: {'lockCaptureOrientation': null}, + ); + + // Act + await camera.lockCaptureOrientation( + cameraId, DeviceOrientation.portraitUp); + + // Assert + expect(channel.log, [ + isMethodCall('lockCaptureOrientation', + arguments: {'cameraId': cameraId, 'orientation': 'portraitUp'}), + ]); + }); + + test('Should unlock the capture orientation', () async { + // Arrange + MethodChannelMock channel = MethodChannelMock( + channelName: 'plugins.flutter.io/camera', + methods: {'unlockCaptureOrientation': null}, + ); + + // Act + await camera.unlockCaptureOrientation(cameraId); + + // Assert + expect(channel.log, [ + isMethodCall('unlockCaptureOrientation', + arguments: {'cameraId': cameraId}), + ]); + }); }); }); } diff --git a/packages/camera/camera_platform_interface/test/utils/utils_test.dart b/packages/camera/camera_platform_interface/test/utils/utils_test.dart index dccb30754f14..63e3baff265d 100644 --- a/packages/camera/camera_platform_interface/test/utils/utils_test.dart +++ b/packages/camera/camera_platform_interface/test/utils/utils_test.dart @@ -1,5 +1,6 @@ import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:camera_platform_interface/src/utils/utils.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { @@ -29,5 +30,27 @@ void main() { throwsA(isArgumentError), ); }); + + test("serializeDeviceOrientation() should serialize correctly", () { + expect(serializeDeviceOrientation(DeviceOrientation.portraitUp), + "portraitUp"); + expect(serializeDeviceOrientation(DeviceOrientation.portraitDown), + "portraitDown"); + expect(serializeDeviceOrientation(DeviceOrientation.landscapeRight), + "landscapeRight"); + expect(serializeDeviceOrientation(DeviceOrientation.landscapeLeft), + "landscapeLeft"); + }); + + test("deserializeDeviceOrientation() should deserialize correctly", () { + expect(deserializeDeviceOrientation('portraitUp'), + DeviceOrientation.portraitUp); + expect(deserializeDeviceOrientation('portraitDown'), + DeviceOrientation.portraitDown); + expect(deserializeDeviceOrientation('landscapeRight'), + DeviceOrientation.landscapeRight); + expect(deserializeDeviceOrientation('landscapeLeft'), + DeviceOrientation.landscapeLeft); + }); }); } From d026d07afea2fa29eacaff3589d8b11a33a402e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Filipovi=C4=87?= Date: Thu, 7 Jan 2021 19:24:24 +0100 Subject: [PATCH 0020/1565] [camera] set useAutoFocus to true by default (#3396) * set useAutoFocus to true by default there's no way to set useAutoFocus to `true` and it is `false` by default so the auto focus is not working. * Update pubspec.yaml * Update CHANGELOG.md --- packages/camera/camera/CHANGELOG.md | 4 ++++ .../src/main/java/io/flutter/plugins/camera/Camera.java | 2 +- packages/camera/camera/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 55c7eb1fcfd2..6557b8a8e0b3 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.4+4 + +* Set camera auto focus enabled by default. + ## 0.6.4+3 * Detect if selected camera supports auto focus and act accordingly on Android. This solves a problem where front facing cameras are not capturing the picture because auto focus is not supported. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 2db097ceadf7..40656cbabcf1 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -96,7 +96,7 @@ public class Camera { private PictureCaptureRequest pictureCaptureRequest; private CameraRegions cameraRegions; private int exposureOffset; - private boolean useAutoFocus; + private boolean useAutoFocus = true; private Range fpsRange; public Camera( diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 99f41fb165a5..6c6d5159800d 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.6.4+3 +version: 0.6.4+4 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From d0fd4b188719f9cd867c82f01cd39bf2828acea1 Mon Sep 17 00:00:00 2001 From: Aman Verma Date: Fri, 8 Jan 2021 01:24:04 +0530 Subject: [PATCH 0021/1565] [image_picker] Update README.md (#3098) --- packages/image_picker/image_picker/CHANGELOG.md | 4 ++++ packages/image_picker/image_picker/README.md | 4 ++-- packages/image_picker/image_picker/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md index 32d61cc79607..90cf80f9aee6 100644 --- a/packages/image_picker/image_picker/CHANGELOG.md +++ b/packages/image_picker/image_picker/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.7+20 + +* Updated README.md to show the new Android API requirements. + ## 0.6.7+19 * Do not copy static field to another static field. diff --git a/packages/image_picker/image_picker/README.md b/packages/image_picker/image_picker/README.md index 106d78b630b9..ca8ad763c553 100755 --- a/packages/image_picker/image_picker/README.md +++ b/packages/image_picker/image_picker/README.md @@ -19,10 +19,10 @@ Add the following keys to your _Info.plist_ file, located in `/ios ### Android -#### API 29+ +#### API < 29 No configuration required - the plugin should work out of the box. -#### API < 29 +#### API 29+ Add `android:requestLegacyExternalStorage="true"` as an attribute to the `` tag in AndroidManifest.xml. The [attribute](https://developer.android.com/training/data-storage/compatibility) is `false` by default on apps targeting Android Q. diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index 377c3840c2d1..af409fd1c5b3 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker description: Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker -version: 0.6.7+19 +version: 0.6.7+20 flutter: plugin: From 1b7afc52353c53b153176a899f51fc3198ec7f95 Mon Sep 17 00:00:00 2001 From: Andrew Zuo Date: Thu, 7 Jan 2021 14:59:03 -0500 Subject: [PATCH 0022/1565] [in_app_purchase] Added serviceTimeout code (#3287) --- packages/in_app_purchase/CHANGELOG.md | 4 ++++ .../billing_client_wrapper.dart | 5 +++++ .../enum_converters.g.dart | 1 + packages/in_app_purchase/pubspec.yaml | 2 +- .../billing_client_wrapper_test.dart | 18 ++++++++++++++++++ 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/CHANGELOG.md index 0a5794f931a8..d7124407d711 100644 --- a/packages/in_app_purchase/CHANGELOG.md +++ b/packages/in_app_purchase/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.5 + +* [Android] Fixed: added support for the SERVICE_TIMEOUT (-3) response code. + ## 0.3.4+18 * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart index 0c8b348f4cd0..2aa91d9f9225 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart @@ -314,6 +314,11 @@ enum BillingResponse { // WARNING: Changes to this class need to be reflected in our generated code. // Run `flutter packages pub run build_runner watch` to rebuild and watch for // further changes. + + /// The request has reached the maximum timeout before Google Play responds. + @JsonValue(-3) + serviceTimeout, + /// The requested feature is not supported by Play Store on the current device. @JsonValue(-2) featureNotSupported, diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.g.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.g.dart index 899304b08273..947700df64df 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.g.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.g.dart @@ -43,6 +43,7 @@ T _$enumDecode( } const _$BillingResponseEnumMap = { + BillingResponse.serviceTimeout: -3, BillingResponse.featureNotSupported: -2, BillingResponse.serviceDisconnected: -1, BillingResponse.ok: 0, diff --git a/packages/in_app_purchase/pubspec.yaml b/packages/in_app_purchase/pubspec.yaml index 5e5ef2447278..883f8c39c273 100644 --- a/packages/in_app_purchase/pubspec.yaml +++ b/packages/in_app_purchase/pubspec.yaml @@ -1,7 +1,7 @@ name: in_app_purchase description: A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases through the App Store and Google Play. homepage: https://github.com/flutter/plugins/tree/master/packages/in_app_purchase -version: 0.3.4+18 +version: 0.3.5 dependencies: async: ^2.0.8 diff --git a/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart b/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart index 54f7c3eda77f..eee33a698237 100644 --- a/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart +++ b/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart @@ -39,6 +39,24 @@ void main() { }); }); + // Make sure that the enum values are supported and that the converter call + // does not fail + test('response states', () async { + BillingResponseConverter converter = BillingResponseConverter(); + converter.fromJson(-3); + converter.fromJson(-2); + converter.fromJson(-1); + converter.fromJson(0); + converter.fromJson(1); + converter.fromJson(2); + converter.fromJson(3); + converter.fromJson(4); + converter.fromJson(5); + converter.fromJson(6); + converter.fromJson(7); + converter.fromJson(8); + }); + group('startConnection', () { final String methodName = 'BillingClient#startConnection(BillingClientStateListener)'; From a7dd76950e5b240d2d878504a6f010ef24717e34 Mon Sep 17 00:00:00 2001 From: Hans Muller Date: Thu, 7 Jan 2021 14:47:38 -0800 Subject: [PATCH 0023/1565] Update obsolete button refs in plugin examples (#3395) --- packages/android_alarm_manager/CHANGELOG.md | 4 +++ .../example/lib/main.dart | 2 +- packages/android_alarm_manager/pubspec.yaml | 2 +- packages/android_intent/CHANGELOG.md | 4 +++ packages/android_intent/example/lib/main.dart | 20 ++++++------- packages/android_intent/pubspec.yaml | 2 +- packages/battery/battery/CHANGELOG.md | 4 +++ .../battery/battery/example/lib/main.dart | 2 +- packages/battery/battery/pubspec.yaml | 2 +- packages/camera/camera/CHANGELOG.md | 4 +++ packages/camera/camera/example/lib/main.dart | 24 ++++++++------- packages/camera/camera/pubspec.yaml | 2 +- .../file_selector/file_selector/CHANGELOG.md | 4 +++ .../example/lib/get_directory_page.dart | 10 ++++--- .../file_selector/example/lib/home_page.dart | 29 +++++++++--------- .../example/lib/open_image_page.dart | 10 ++++--- .../lib/open_multiple_images_page.dart | 10 ++++--- .../example/lib/open_text_page.dart | 10 ++++--- .../example/lib/save_text_page.dart | 8 +++-- .../file_selector/file_selector/pubspec.yaml | 2 +- .../google_maps_flutter/CHANGELOG.md | 4 +++ .../example/lib/animate_camera.dart | 20 ++++++------- .../example/lib/map_coordinates.dart | 2 +- .../example/lib/map_ui.dart | 30 +++++++++---------- .../example/lib/move_camera.dart | 20 ++++++------- .../example/lib/padding.dart | 4 +-- .../example/lib/place_circle.dart | 12 ++++---- .../example/lib/place_marker.dart | 28 ++++++++--------- .../example/lib/place_polygon.dart | 14 ++++----- .../example/lib/place_polyline.dart | 20 ++++++------- .../example/lib/snapshot.dart | 2 +- .../google_maps_flutter/pubspec.yaml | 2 +- .../CHANGELOG.md | 4 +++ .../example/lib/main.dart | 6 ++-- .../pubspec.yaml | 2 +- .../google_sign_in/CHANGELOG.md | 4 +++ .../google_sign_in/example/lib/main.dart | 6 ++-- .../google_sign_in/pubspec.yaml | 2 +- .../image_picker/image_picker/CHANGELOG.md | 4 +++ .../image_picker/example/lib/main.dart | 4 +-- packages/in_app_purchase/CHANGELOG.md | 4 +++ .../in_app_purchase/example/lib/main.dart | 8 +++-- packages/in_app_purchase/pubspec.yaml | 2 +- packages/local_auth/CHANGELOG.md | 4 +++ packages/local_auth/example/lib/main.dart | 6 ++-- packages/local_auth/pubspec.yaml | 2 +- .../path_provider/path_provider/CHANGELOG.md | 4 +++ .../path_provider/example/lib/main.dart | 14 ++++----- .../path_provider/path_provider/pubspec.yaml | 2 +- .../path_provider_macos/CHANGELOG.md | 4 +++ .../path_provider_macos/example/lib/main.dart | 10 +++---- .../path_provider_macos/pubspec.yaml | 2 +- packages/share/CHANGELOG.md | 4 +++ packages/share/example/lib/main.dart | 8 ++--- packages/share/pubspec.yaml | 2 +- .../url_launcher/url_launcher/CHANGELOG.md | 4 +++ .../url_launcher/example/lib/main.dart | 14 ++++----- .../test/url_launcher_example_test.dart | 2 +- .../url_launcher/lib/src/link.dart | 4 +-- .../url_launcher/url_launcher/pubspec.yaml | 2 +- .../url_launcher_linux/CHANGELOG.md | 4 +++ .../url_launcher_linux/example/lib/main.dart | 12 ++++---- .../url_launcher_linux/pubspec.yaml | 2 +- .../url_launcher_macos/CHANGELOG.md | 4 +++ .../url_launcher_macos/example/lib/main.dart | 12 ++++---- .../url_launcher_macos/pubspec.yaml | 2 +- .../url_launcher_windows/CHANGELOG.md | 4 +++ .../example/lib/main.dart | 2 +- .../url_launcher_windows/pubspec.yaml | 2 +- .../video_player/video_player/CHANGELOG.md | 4 +++ .../video_player/example/lib/main.dart | 4 +-- .../video_player/video_player/pubspec.yaml | 2 +- 72 files changed, 296 insertions(+), 205 deletions(-) diff --git a/packages/android_alarm_manager/CHANGELOG.md b/packages/android_alarm_manager/CHANGELOG.md index 1b6a7b749e66..df5b7a2fa752 100644 --- a/packages/android_alarm_manager/CHANGELOG.md +++ b/packages/android_alarm_manager/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.5+20 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + ## 0.4.5+19 * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) diff --git a/packages/android_alarm_manager/example/lib/main.dart b/packages/android_alarm_manager/example/lib/main.dart index b4d907c127da..ac27fec2e4c6 100644 --- a/packages/android_alarm_manager/example/lib/main.dart +++ b/packages/android_alarm_manager/example/lib/main.dart @@ -131,7 +131,7 @@ class _AlarmHomePageState extends State<_AlarmHomePage> { ), ], ), - RaisedButton( + ElevatedButton( child: Text( 'Schedule OneShot Alarm', ), diff --git a/packages/android_alarm_manager/pubspec.yaml b/packages/android_alarm_manager/pubspec.yaml index b055823c2db3..d1771c0f0380 100644 --- a/packages/android_alarm_manager/pubspec.yaml +++ b/packages/android_alarm_manager/pubspec.yaml @@ -4,7 +4,7 @@ description: Flutter plugin for accessing the Android AlarmManager service, and # 0.4.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.4.5+19 +version: 0.4.5+20 homepage: https://github.com/flutter/plugins/tree/master/packages/android_alarm_manager dependencies: diff --git a/packages/android_intent/CHANGELOG.md b/packages/android_intent/CHANGELOG.md index 113e4464c947..3e878a50aac2 100644 --- a/packages/android_intent/CHANGELOG.md +++ b/packages/android_intent/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.2 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + ## 2.0.0-nullsafety.1 * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) diff --git a/packages/android_intent/example/lib/main.dart b/packages/android_intent/example/lib/main.dart index 45de9632e975..4fd2440285f3 100644 --- a/packages/android_intent/example/lib/main.dart +++ b/packages/android_intent/example/lib/main.dart @@ -59,12 +59,12 @@ class MyHomePage extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - RaisedButton( + ElevatedButton( child: const Text( 'Tap here to set an alarm\non weekdays at 9:30pm.'), onPressed: _createAlarm, ), - RaisedButton( + ElevatedButton( child: const Text('Tap here to test explicit intents.'), onPressed: () => _openExplicitIntentsView(context)), ], @@ -166,40 +166,40 @@ class ExplicitIntentsWidget extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - RaisedButton( + ElevatedButton( child: const Text( 'Tap here to display panorama\nimagery in Google Street View.'), onPressed: _openGoogleMapsStreetView, ), - RaisedButton( + ElevatedButton( child: const Text('Tap here to display\na map in Google Maps.'), onPressed: _displayMapInGoogleMaps, ), - RaisedButton( + ElevatedButton( child: const Text( 'Tap here to launch turn-by-turn\nnavigation in Google Maps.'), onPressed: _launchTurnByTurnNavigationInGoogleMaps, ), - RaisedButton( + ElevatedButton( child: const Text('Tap here to open link in Google Chrome.'), onPressed: _openLinkInGoogleChrome, ), - RaisedButton( + ElevatedButton( child: const Text('Tap here to start activity in new task.'), onPressed: _startActivityInNewTask, ), - RaisedButton( + ElevatedButton( child: const Text( 'Tap here to test explicit intent fallback to implicit.'), onPressed: _testExplicitIntentFallback, ), - RaisedButton( + ElevatedButton( child: const Text( 'Tap here to open Location Settings Configuration', ), onPressed: _openLocationSettingsConfiguration, ), - RaisedButton( + ElevatedButton( child: const Text( 'Tap here to open Application Details', ), diff --git a/packages/android_intent/pubspec.yaml b/packages/android_intent/pubspec.yaml index 52928f08093f..c61460718fc1 100644 --- a/packages/android_intent/pubspec.yaml +++ b/packages/android_intent/pubspec.yaml @@ -1,7 +1,7 @@ name: android_intent description: Flutter plugin for launching Android Intents. Not supported on iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/android_intent -version: 2.0.0-nullsafety.1 +version: 2.0.0-nullsafety.2 flutter: plugin: diff --git a/packages/battery/battery/CHANGELOG.md b/packages/battery/battery/CHANGELOG.md index c9268d4d4e3c..ca35c96fb569 100644 --- a/packages/battery/battery/CHANGELOG.md +++ b/packages/battery/battery/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.11 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + ## 1.0.10 * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) diff --git a/packages/battery/battery/example/lib/main.dart b/packages/battery/battery/example/lib/main.dart index 1c1dfcf252b6..c84f5eec519b 100644 --- a/packages/battery/battery/example/lib/main.dart +++ b/packages/battery/battery/example/lib/main.dart @@ -71,7 +71,7 @@ class _MyHomePageState extends State { builder: (_) => AlertDialog( content: Text('Battery: $batteryLevel%'), actions: [ - FlatButton( + TextButton( child: const Text('OK'), onPressed: () { Navigator.pop(context); diff --git a/packages/battery/battery/pubspec.yaml b/packages/battery/battery/pubspec.yaml index d3c823d73ad2..9c2c2766c85f 100644 --- a/packages/battery/battery/pubspec.yaml +++ b/packages/battery/battery/pubspec.yaml @@ -2,7 +2,7 @@ name: battery description: Flutter plugin for accessing information about the battery state (full, charging, discharging) on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/battery/battery -version: 1.0.10 +version: 1.0.11 flutter: plugin: diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 6557b8a8e0b3..2f9b5399d6dd 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.4+5 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + ## 0.6.4+4 * Set camera auto focus enabled by default. diff --git a/packages/camera/camera/example/lib/main.dart b/packages/camera/camera/example/lib/main.dart index c4fa1c5ed01e..5324e3d09383 100644 --- a/packages/camera/camera/example/lib/main.dart +++ b/packages/camera/camera/example/lib/main.dart @@ -313,6 +313,16 @@ class _CameraExampleHomeState extends State } Widget _exposureModeControlRowWidget() { + final ButtonStyle styleAuto = TextButton.styleFrom( + primary: controller?.value?.exposureMode == ExposureMode.auto + ? Colors.orange + : Colors.blue, + ); + final ButtonStyle styleLocked = TextButton.styleFrom( + primary: controller?.value?.exposureMode == ExposureMode.locked + ? Colors.orange + : Colors.blue, + ); return SizeTransition( sizeFactor: _exposureModeControlRowAnimation, child: ClipRect( @@ -327,12 +337,9 @@ class _CameraExampleHomeState extends State mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisSize: MainAxisSize.max, children: [ - FlatButton( + TextButton( child: Text('AUTO'), - textColor: - controller?.value?.exposureMode == ExposureMode.auto - ? Colors.orange - : Colors.blue, + style: styleAuto, onPressed: controller != null ? () => onSetExposureModeButtonPressed(ExposureMode.auto) @@ -342,12 +349,9 @@ class _CameraExampleHomeState extends State showInSnackBar('Resetting exposure point'); }, ), - FlatButton( + TextButton( child: Text('LOCKED'), - textColor: - controller?.value?.exposureMode == ExposureMode.locked - ? Colors.orange - : Colors.blue, + style: styleLocked, onPressed: controller != null ? () => onSetExposureModeButtonPressed(ExposureMode.locked) diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 6c6d5159800d..50f504a8d0e8 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.6.4+4 +version: 0.6.4+5 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: diff --git a/packages/file_selector/file_selector/CHANGELOG.md b/packages/file_selector/file_selector/CHANGELOG.md index 92136485a447..fe01ffec47b6 100644 --- a/packages/file_selector/file_selector/CHANGELOG.md +++ b/packages/file_selector/file_selector/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.0+2 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + ## 0.7.0+1 * Update Flutter SDK constraint. diff --git a/packages/file_selector/file_selector/example/lib/get_directory_page.dart b/packages/file_selector/file_selector/example/lib/get_directory_page.dart index 2afc58f246a4..6463fb532957 100644 --- a/packages/file_selector/file_selector/example/lib/get_directory_page.dart +++ b/packages/file_selector/file_selector/example/lib/get_directory_page.dart @@ -24,9 +24,11 @@ class GetDirectoryPage extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - RaisedButton( - color: Colors.blue, - textColor: Colors.white, + ElevatedButton( + style: ElevatedButton.styleFrom( + primary: Colors.blue, + onPrimary: Colors.white, + ), child: Text('Press to ask user to choose a directory'), onPressed: () => _getDirectoryPath(context), ), @@ -55,7 +57,7 @@ class TextDisplay extends StatelessWidget { ), ), actions: [ - FlatButton( + TextButton( child: const Text('Close'), onPressed: () => Navigator.pop(context), ), diff --git a/packages/file_selector/file_selector/example/lib/home_page.dart b/packages/file_selector/file_selector/example/lib/home_page.dart index c37d90170f6e..1cb7ef261e88 100644 --- a/packages/file_selector/file_selector/example/lib/home_page.dart +++ b/packages/file_selector/file_selector/example/lib/home_page.dart @@ -4,6 +4,10 @@ import 'package:flutter/material.dart'; class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { + final ButtonStyle style = ElevatedButton.styleFrom( + primary: Colors.blue, + onPrimary: Colors.white, + ); return Scaffold( appBar: AppBar( title: Text('File Selector Demo Home Page'), @@ -12,37 +16,32 @@ class HomePage extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - RaisedButton( - color: Colors.blue, - textColor: Colors.white, + ElevatedButton( + style: style, child: Text('Open a text file'), onPressed: () => Navigator.pushNamed(context, '/open/text'), ), SizedBox(height: 10), - RaisedButton( - color: Colors.blue, - textColor: Colors.white, + ElevatedButton( + style: style, child: Text('Open an image'), onPressed: () => Navigator.pushNamed(context, '/open/image'), ), SizedBox(height: 10), - RaisedButton( - color: Colors.blue, - textColor: Colors.white, + ElevatedButton( + style: style, child: Text('Open multiple images'), onPressed: () => Navigator.pushNamed(context, '/open/images'), ), SizedBox(height: 10), - RaisedButton( - color: Colors.blue, - textColor: Colors.white, + ElevatedButton( + style: style, child: Text('Save a file'), onPressed: () => Navigator.pushNamed(context, '/save/text'), ), SizedBox(height: 10), - RaisedButton( - color: Colors.blue, - textColor: Colors.white, + ElevatedButton( + style: style, child: Text('Open a get directory dialog'), onPressed: () => Navigator.pushNamed(context, '/directory'), ), diff --git a/packages/file_selector/file_selector/example/lib/open_image_page.dart b/packages/file_selector/file_selector/example/lib/open_image_page.dart index 2821635fb30b..593a1d60aed8 100644 --- a/packages/file_selector/file_selector/example/lib/open_image_page.dart +++ b/packages/file_selector/file_selector/example/lib/open_image_page.dart @@ -31,9 +31,11 @@ class OpenImagePage extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - RaisedButton( - color: Colors.blue, - textColor: Colors.white, + ElevatedButton( + style: ElevatedButton.styleFrom( + primary: Colors.blue, + onPrimary: Colors.white, + ), child: Text('Press to open an image file(png, jpg)'), onPressed: () => _openImageFile(context), ), @@ -63,7 +65,7 @@ class ImageDisplay extends StatelessWidget { // while on other platforms it is a system path. content: kIsWeb ? Image.network(filePath) : Image.file(File(filePath)), actions: [ - FlatButton( + TextButton( child: const Text('Close'), onPressed: () { Navigator.pop(context); diff --git a/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart b/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart index 7a27a0c0715f..58b59cd91b03 100644 --- a/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart +++ b/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart @@ -34,9 +34,11 @@ class OpenMultipleImagesPage extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - RaisedButton( - color: Colors.blue, - textColor: Colors.white, + ElevatedButton( + style: ElevatedButton.styleFrom( + primary: Colors.blue, + onPrimary: Colors.white, + ), child: Text('Press to open multiple images (png, jpg)'), onPressed: () => _openImageFile(context), ), @@ -74,7 +76,7 @@ class MultipleImagesDisplay extends StatelessWidget { ), ), actions: [ - FlatButton( + TextButton( child: const Text('Close'), onPressed: () { Navigator.pop(context); diff --git a/packages/file_selector/file_selector/example/lib/open_text_page.dart b/packages/file_selector/file_selector/example/lib/open_text_page.dart index 4cb3064046fd..299d0e2dc21a 100644 --- a/packages/file_selector/file_selector/example/lib/open_text_page.dart +++ b/packages/file_selector/file_selector/example/lib/open_text_page.dart @@ -28,9 +28,11 @@ class OpenTextPage extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - RaisedButton( - color: Colors.blue, - textColor: Colors.white, + ElevatedButton( + style: ElevatedButton.styleFrom( + primary: Colors.blue, + onPrimary: Colors.white, + ), child: Text('Press to open a text file (json, txt)'), onPressed: () => _openTextFile(context), ), @@ -62,7 +64,7 @@ class TextDisplay extends StatelessWidget { ), ), actions: [ - FlatButton( + TextButton( child: const Text('Close'), onPressed: () => Navigator.pop(context), ), diff --git a/packages/file_selector/file_selector/example/lib/save_text_page.dart b/packages/file_selector/file_selector/example/lib/save_text_page.dart index b70231f5a410..47408662ecee 100644 --- a/packages/file_selector/file_selector/example/lib/save_text_page.dart +++ b/packages/file_selector/file_selector/example/lib/save_text_page.dart @@ -51,9 +51,11 @@ class SaveTextPage extends StatelessWidget { ), ), SizedBox(height: 10), - RaisedButton( - color: Colors.blue, - textColor: Colors.white, + ElevatedButton( + style: ElevatedButton.styleFrom( + primary: Colors.blue, + onPrimary: Colors.white, + ), child: Text('Press to save a text file'), onPressed: () => _saveFile(), ), diff --git a/packages/file_selector/file_selector/pubspec.yaml b/packages/file_selector/file_selector/pubspec.yaml index f095ba1f6a36..a55b7f4e06e7 100644 --- a/packages/file_selector/file_selector/pubspec.yaml +++ b/packages/file_selector/file_selector/pubspec.yaml @@ -1,7 +1,7 @@ name: file_selector description: Flutter plugin for opening and saving files. homepage: https://github.com/flutter/plugins/tree/master/packages/file_selector/file_selector -version: 0.7.0+1 +version: 0.7.0+2 dependencies: flutter: diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index 7783f3042dde..b23ef79651e7 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.10 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + ## 1.0.9 * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/animate_camera.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/animate_camera.dart index 37c79d302733..ae5e9f6cee3a 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/animate_camera.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/animate_camera.dart @@ -54,7 +54,7 @@ class AnimateCameraState extends State { children: [ Column( children: [ - FlatButton( + TextButton( onPressed: () { mapController.animateCamera( CameraUpdate.newCameraPosition( @@ -69,7 +69,7 @@ class AnimateCameraState extends State { }, child: const Text('newCameraPosition'), ), - FlatButton( + TextButton( onPressed: () { mapController.animateCamera( CameraUpdate.newLatLng( @@ -79,7 +79,7 @@ class AnimateCameraState extends State { }, child: const Text('newLatLng'), ), - FlatButton( + TextButton( onPressed: () { mapController.animateCamera( CameraUpdate.newLatLngBounds( @@ -93,7 +93,7 @@ class AnimateCameraState extends State { }, child: const Text('newLatLngBounds'), ), - FlatButton( + TextButton( onPressed: () { mapController.animateCamera( CameraUpdate.newLatLngZoom( @@ -104,7 +104,7 @@ class AnimateCameraState extends State { }, child: const Text('newLatLngZoom'), ), - FlatButton( + TextButton( onPressed: () { mapController.animateCamera( CameraUpdate.scrollBy(150.0, -225.0), @@ -116,7 +116,7 @@ class AnimateCameraState extends State { ), Column( children: [ - FlatButton( + TextButton( onPressed: () { mapController.animateCamera( CameraUpdate.zoomBy( @@ -127,7 +127,7 @@ class AnimateCameraState extends State { }, child: const Text('zoomBy with focus'), ), - FlatButton( + TextButton( onPressed: () { mapController.animateCamera( CameraUpdate.zoomBy(-0.5), @@ -135,7 +135,7 @@ class AnimateCameraState extends State { }, child: const Text('zoomBy'), ), - FlatButton( + TextButton( onPressed: () { mapController.animateCamera( CameraUpdate.zoomIn(), @@ -143,7 +143,7 @@ class AnimateCameraState extends State { }, child: const Text('zoomIn'), ), - FlatButton( + TextButton( onPressed: () { mapController.animateCamera( CameraUpdate.zoomOut(), @@ -151,7 +151,7 @@ class AnimateCameraState extends State { }, child: const Text('zoomOut'), ), - FlatButton( + TextButton( onPressed: () { mapController.animateCamera( CameraUpdate.zoomTo(16.0), diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_coordinates.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_coordinates.dart index efdbe016f7c4..f194f8cb3f3b 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_coordinates.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_coordinates.dart @@ -83,7 +83,7 @@ class _MapCoordinatesBodyState extends State<_MapCoordinatesBody> { Widget _getVisibleRegionButton() { return Padding( padding: const EdgeInsets.all(8.0), - child: RaisedButton( + child: ElevatedButton( child: const Text('Get Visible Region Bounds'), onPressed: () async { final LatLngBounds visibleRegion = diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_ui.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_ui.dart index f117c3a48b22..61a62ac0cf6d 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_ui.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_ui.dart @@ -70,7 +70,7 @@ class MapUiBodyState extends State { } Widget _compassToggler() { - return FlatButton( + return TextButton( child: Text('${_compassEnabled ? 'disable' : 'enable'} compass'), onPressed: () { setState(() { @@ -81,7 +81,7 @@ class MapUiBodyState extends State { } Widget _mapToolbarToggler() { - return FlatButton( + return TextButton( child: Text('${_mapToolbarEnabled ? 'disable' : 'enable'} map toolbar'), onPressed: () { setState(() { @@ -92,7 +92,7 @@ class MapUiBodyState extends State { } Widget _latLngBoundsToggler() { - return FlatButton( + return TextButton( child: Text( _cameraTargetBounds.bounds == null ? 'bound camera target' @@ -109,7 +109,7 @@ class MapUiBodyState extends State { } Widget _zoomBoundsToggler() { - return FlatButton( + return TextButton( child: Text(_minMaxZoomPreference.minZoom == null ? 'bound zoom' : 'release zoom'), @@ -126,7 +126,7 @@ class MapUiBodyState extends State { Widget _mapTypeCycler() { final MapType nextType = MapType.values[(_mapType.index + 1) % MapType.values.length]; - return FlatButton( + return TextButton( child: Text('change map type to $nextType'), onPressed: () { setState(() { @@ -137,7 +137,7 @@ class MapUiBodyState extends State { } Widget _rotateToggler() { - return FlatButton( + return TextButton( child: Text('${_rotateGesturesEnabled ? 'disable' : 'enable'} rotate'), onPressed: () { setState(() { @@ -148,7 +148,7 @@ class MapUiBodyState extends State { } Widget _scrollToggler() { - return FlatButton( + return TextButton( child: Text('${_scrollGesturesEnabled ? 'disable' : 'enable'} scroll'), onPressed: () { setState(() { @@ -159,7 +159,7 @@ class MapUiBodyState extends State { } Widget _tiltToggler() { - return FlatButton( + return TextButton( child: Text('${_tiltGesturesEnabled ? 'disable' : 'enable'} tilt'), onPressed: () { setState(() { @@ -170,7 +170,7 @@ class MapUiBodyState extends State { } Widget _zoomToggler() { - return FlatButton( + return TextButton( child: Text('${_zoomGesturesEnabled ? 'disable' : 'enable'} zoom'), onPressed: () { setState(() { @@ -181,7 +181,7 @@ class MapUiBodyState extends State { } Widget _zoomControlsToggler() { - return FlatButton( + return TextButton( child: Text('${_zoomControlsEnabled ? 'disable' : 'enable'} zoom controls'), onPressed: () { @@ -193,7 +193,7 @@ class MapUiBodyState extends State { } Widget _indoorViewToggler() { - return FlatButton( + return TextButton( child: Text('${_indoorViewEnabled ? 'disable' : 'enable'} indoor'), onPressed: () { setState(() { @@ -204,7 +204,7 @@ class MapUiBodyState extends State { } Widget _myLocationToggler() { - return FlatButton( + return TextButton( child: Text( '${_myLocationEnabled ? 'disable' : 'enable'} my location marker'), onPressed: () { @@ -216,7 +216,7 @@ class MapUiBodyState extends State { } Widget _myLocationButtonToggler() { - return FlatButton( + return TextButton( child: Text( '${_myLocationButtonEnabled ? 'disable' : 'enable'} my location button'), onPressed: () { @@ -228,7 +228,7 @@ class MapUiBodyState extends State { } Widget _myTrafficToggler() { - return FlatButton( + return TextButton( child: Text('${_myTrafficEnabled ? 'disable' : 'enable'} my traffic'), onPressed: () { setState(() { @@ -253,7 +253,7 @@ class MapUiBodyState extends State { if (!_isMapCreated) { return null; } - return FlatButton( + return TextButton( child: Text('${_nightMode ? 'disable' : 'enable'} night mode'), onPressed: () { if (_nightMode) { diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/move_camera.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/move_camera.dart index 514a315e03db..262d362d8c3e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/move_camera.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/move_camera.dart @@ -53,7 +53,7 @@ class MoveCameraState extends State { children: [ Column( children: [ - FlatButton( + TextButton( onPressed: () { mapController.moveCamera( CameraUpdate.newCameraPosition( @@ -68,7 +68,7 @@ class MoveCameraState extends State { }, child: const Text('newCameraPosition'), ), - FlatButton( + TextButton( onPressed: () { mapController.moveCamera( CameraUpdate.newLatLng( @@ -78,7 +78,7 @@ class MoveCameraState extends State { }, child: const Text('newLatLng'), ), - FlatButton( + TextButton( onPressed: () { mapController.moveCamera( CameraUpdate.newLatLngBounds( @@ -92,7 +92,7 @@ class MoveCameraState extends State { }, child: const Text('newLatLngBounds'), ), - FlatButton( + TextButton( onPressed: () { mapController.moveCamera( CameraUpdate.newLatLngZoom( @@ -103,7 +103,7 @@ class MoveCameraState extends State { }, child: const Text('newLatLngZoom'), ), - FlatButton( + TextButton( onPressed: () { mapController.moveCamera( CameraUpdate.scrollBy(150.0, -225.0), @@ -115,7 +115,7 @@ class MoveCameraState extends State { ), Column( children: [ - FlatButton( + TextButton( onPressed: () { mapController.moveCamera( CameraUpdate.zoomBy( @@ -126,7 +126,7 @@ class MoveCameraState extends State { }, child: const Text('zoomBy with focus'), ), - FlatButton( + TextButton( onPressed: () { mapController.moveCamera( CameraUpdate.zoomBy(-0.5), @@ -134,7 +134,7 @@ class MoveCameraState extends State { }, child: const Text('zoomBy'), ), - FlatButton( + TextButton( onPressed: () { mapController.moveCamera( CameraUpdate.zoomIn(), @@ -142,7 +142,7 @@ class MoveCameraState extends State { }, child: const Text('zoomIn'), ), - FlatButton( + TextButton( onPressed: () { mapController.moveCamera( CameraUpdate.zoomOut(), @@ -150,7 +150,7 @@ class MoveCameraState extends State { }, child: const Text('zoomOut'), ), - FlatButton( + TextButton( onPressed: () { mapController.moveCamera( CameraUpdate.zoomTo(16.0), diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/padding.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/padding.dart index 94b60b7758f9..934d4c647aa4 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/padding.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/padding.dart @@ -147,7 +147,7 @@ class MarkerIconsBodyState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - FlatButton( + TextButton( child: const Text("Set Padding"), onPressed: () { setState(() { @@ -159,7 +159,7 @@ class MarkerIconsBodyState extends State { }); }, ), - FlatButton( + TextButton( child: const Text("Reset Padding"), onPressed: () { setState(() { diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_circle.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_circle.dart index 954d8876d1d5..7f0447e9a279 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_circle.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_circle.dart @@ -165,15 +165,15 @@ class PlaceCircleBodyState extends State { children: [ Column( children: [ - FlatButton( + TextButton( child: const Text('add'), onPressed: _add, ), - FlatButton( + TextButton( child: const Text('remove'), onPressed: (selectedCircle == null) ? null : _remove, ), - FlatButton( + TextButton( child: const Text('toggle visible'), onPressed: (selectedCircle == null) ? null : _toggleVisible, @@ -182,19 +182,19 @@ class PlaceCircleBodyState extends State { ), Column( children: [ - FlatButton( + TextButton( child: const Text('change stroke width'), onPressed: (selectedCircle == null) ? null : _changeStrokeWidth, ), - FlatButton( + TextButton( child: const Text('change stroke color'), onPressed: (selectedCircle == null) ? null : _changeStrokeColor, ), - FlatButton( + TextButton( child: const Text('change fill color'), onPressed: (selectedCircle == null) ? null diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart index 6808e58c199e..2c5439590443 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart @@ -77,7 +77,7 @@ class PlaceMarkerBodyState extends State { builder: (BuildContext context) { return AlertDialog( actions: [ - FlatButton( + TextButton( child: const Text('OK'), onPressed: () => Navigator.of(context).pop(), ) @@ -313,19 +313,19 @@ class PlaceMarkerBodyState extends State { children: [ Column( children: [ - FlatButton( + TextButton( child: const Text('add'), onPressed: _add, ), - FlatButton( + TextButton( child: const Text('remove'), onPressed: _remove, ), - FlatButton( + TextButton( child: const Text('change info'), onPressed: _changeInfo, ), - FlatButton( + TextButton( child: const Text('change info anchor'), onPressed: _changeInfoAnchor, ), @@ -333,35 +333,35 @@ class PlaceMarkerBodyState extends State { ), Column( children: [ - FlatButton( + TextButton( child: const Text('change alpha'), onPressed: _changeAlpha, ), - FlatButton( + TextButton( child: const Text('change anchor'), onPressed: _changeAnchor, ), - FlatButton( + TextButton( child: const Text('toggle draggable'), onPressed: _toggleDraggable, ), - FlatButton( + TextButton( child: const Text('toggle flat'), onPressed: _toggleFlat, ), - FlatButton( + TextButton( child: const Text('change position'), onPressed: _changePosition, ), - FlatButton( + TextButton( child: const Text('change rotation'), onPressed: _changeRotation, ), - FlatButton( + TextButton( child: const Text('toggle visible'), onPressed: _toggleVisible, ), - FlatButton( + TextButton( child: const Text('change zIndex'), onPressed: _changeZIndex, ), @@ -371,7 +371,7 @@ class PlaceMarkerBodyState extends State { // TODO(amirh): uncomment this one the ImageStream API change makes it to stable. // https://github.com/flutter/flutter/issues/33438 // - // FlatButton( + // TextButton( // child: const Text('set marker icon'), // onPressed: () { // _getAssetIcon(context).then( diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart index 5713f9a099e6..af5ca16bea17 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart @@ -173,20 +173,20 @@ class PlacePolygonBodyState extends State { children: [ Column( children: [ - FlatButton( + TextButton( child: const Text('add'), onPressed: _add, ), - FlatButton( + TextButton( child: const Text('remove'), onPressed: (selectedPolygon == null) ? null : _remove, ), - FlatButton( + TextButton( child: const Text('toggle visible'), onPressed: (selectedPolygon == null) ? null : _toggleVisible, ), - FlatButton( + TextButton( child: const Text('toggle geodesic'), onPressed: (selectedPolygon == null) ? null @@ -196,18 +196,18 @@ class PlacePolygonBodyState extends State { ), Column( children: [ - FlatButton( + TextButton( child: const Text('change stroke width'), onPressed: (selectedPolygon == null) ? null : _changeWidth, ), - FlatButton( + TextButton( child: const Text('change stroke color'), onPressed: (selectedPolygon == null) ? null : _changeStrokeColor, ), - FlatButton( + TextButton( child: const Text('change fill color'), onPressed: (selectedPolygon == null) ? null diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart index 35ffd33a53c2..65201d5d1839 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart @@ -232,22 +232,22 @@ class PlacePolylineBodyState extends State { children: [ Column( children: [ - FlatButton( + TextButton( child: const Text('add'), onPressed: _add, ), - FlatButton( + TextButton( child: const Text('remove'), onPressed: (selectedPolyline == null) ? null : _remove, ), - FlatButton( + TextButton( child: const Text('toggle visible'), onPressed: (selectedPolyline == null) ? null : _toggleVisible, ), - FlatButton( + TextButton( child: const Text('toggle geodesic'), onPressed: (selectedPolyline == null) ? null @@ -257,29 +257,29 @@ class PlacePolylineBodyState extends State { ), Column( children: [ - FlatButton( + TextButton( child: const Text('change width'), onPressed: (selectedPolyline == null) ? null : _changeWidth, ), - FlatButton( + TextButton( child: const Text('change color'), onPressed: (selectedPolyline == null) ? null : _changeColor, ), - FlatButton( + TextButton( child: const Text('change start cap [Android only]'), onPressed: iOSorNotSelected ? null : _changeStartCap, ), - FlatButton( + TextButton( child: const Text('change end cap [Android only]'), onPressed: iOSorNotSelected ? null : _changeEndCap, ), - FlatButton( + TextButton( child: const Text('change joint type [Android only]'), onPressed: iOSorNotSelected ? null : _changeJointType, ), - FlatButton( + TextButton( child: const Text('change pattern [Android only]'), onPressed: iOSorNotSelected ? null : _changePattern, ), diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/snapshot.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/snapshot.dart index 872060d86039..f470a4f9783e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/snapshot.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/snapshot.dart @@ -47,7 +47,7 @@ class _SnapshotBodyState extends State<_SnapshotBody> { initialCameraPosition: _kInitialPosition, ), ), - FlatButton( + TextButton( child: Text('Take a snapshot'), onPressed: () async { final imageBytes = await _mapController?.takeSnapshot(); diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index 7d480ebf74f2..4faadf4c2166 100644 --- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: google_maps_flutter description: A Flutter plugin for integrating Google Maps in iOS and Android applications. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter -version: 1.0.9 +version: 1.0.10 dependencies: flutter: diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md index 25539436f8fa..4afb1a0e98bf 100644 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md +++ b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.4 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + ## 1.0.3 * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/lib/main.dart b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/lib/main.dart index a238ca3bf8b5..597ab563ae5b 100755 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/lib/main.dart +++ b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/lib/main.dart @@ -111,11 +111,11 @@ class SignInDemoState extends State { ), const Text('Signed in successfully.'), Text(_contactText ?? ''), - RaisedButton( + ElevatedButton( child: const Text('SIGN OUT'), onPressed: _handleSignOut, ), - RaisedButton( + ElevatedButton( child: const Text('REFRESH'), onPressed: _handleGetContact, ), @@ -126,7 +126,7 @@ class SignInDemoState extends State { mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ const Text('You are not currently signed in.'), - RaisedButton( + ElevatedButton( child: const Text('SIGN IN'), onPressed: _handleSignIn, ), diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/pubspec.yaml b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/pubspec.yaml index aecd5a9569be..9da5f0baa848 100644 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/pubspec.yaml +++ b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/pubspec.yaml @@ -6,7 +6,7 @@ name: extension_google_sign_in_as_googleapis_auth description: A bridge package between google_sign_in and googleapis_auth, to create Authenticated Clients from google_sign_in user credentials. -version: 1.0.3 +version: 1.0.4 homepage: https://github.com/flutter/plugins/google_sign_in/extension_google_sign_in_as_googleapis_auth dependencies: diff --git a/packages/google_sign_in/google_sign_in/CHANGELOG.md b/packages/google_sign_in/google_sign_in/CHANGELOG.md index 8a4dd6bc817e..7f5b4f2bdd17 100644 --- a/packages/google_sign_in/google_sign_in/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in/CHANGELOG.md @@ -1,3 +1,7 @@ +## 4.5.9 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + ## 4.5.8 * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) diff --git a/packages/google_sign_in/google_sign_in/example/lib/main.dart b/packages/google_sign_in/google_sign_in/example/lib/main.dart index 6c66d56085db..a738c248a4a4 100755 --- a/packages/google_sign_in/google_sign_in/example/lib/main.dart +++ b/packages/google_sign_in/google_sign_in/example/lib/main.dart @@ -120,11 +120,11 @@ class SignInDemoState extends State { ), const Text("Signed in successfully."), Text(_contactText ?? ''), - RaisedButton( + ElevatedButton( child: const Text('SIGN OUT'), onPressed: _handleSignOut, ), - RaisedButton( + ElevatedButton( child: const Text('REFRESH'), onPressed: _handleGetContact, ), @@ -135,7 +135,7 @@ class SignInDemoState extends State { mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ const Text("You are not currently signed in."), - RaisedButton( + ElevatedButton( child: const Text('SIGN IN'), onPressed: _handleSignIn, ), diff --git a/packages/google_sign_in/google_sign_in/pubspec.yaml b/packages/google_sign_in/google_sign_in/pubspec.yaml index b99b231adb9d..6e0366c790bf 100644 --- a/packages/google_sign_in/google_sign_in/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/pubspec.yaml @@ -2,7 +2,7 @@ name: google_sign_in description: Flutter plugin for Google Sign-In, a secure authentication system for signing in with a Google account on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in -version: 4.5.8 +version: 4.5.9 flutter: plugin: diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md index 90cf80f9aee6..1b3146d532fa 100644 --- a/packages/image_picker/image_picker/CHANGELOG.md +++ b/packages/image_picker/image_picker/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.7+21 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + ## 0.6.7+20 * Updated README.md to show the new Android API requirements. diff --git a/packages/image_picker/image_picker/example/lib/main.dart b/packages/image_picker/image_picker/example/lib/main.dart index 3047ac13f235..73327ef0caa6 100755 --- a/packages/image_picker/image_picker/example/lib/main.dart +++ b/packages/image_picker/image_picker/example/lib/main.dart @@ -327,13 +327,13 @@ class _MyHomePageState extends State { ], ), actions: [ - FlatButton( + TextButton( child: const Text('CANCEL'), onPressed: () { Navigator.of(context).pop(); }, ), - FlatButton( + TextButton( child: const Text('PICK'), onPressed: () { double width = maxWidthController.text.isNotEmpty diff --git a/packages/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/CHANGELOG.md index d7124407d711..3c77e0c313f5 100644 --- a/packages/in_app_purchase/CHANGELOG.md +++ b/packages/in_app_purchase/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.5+1 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + ## 0.3.5 * [Android] Fixed: added support for the SERVICE_TIMEOUT (-3) response code. diff --git a/packages/in_app_purchase/example/lib/main.dart b/packages/in_app_purchase/example/lib/main.dart index b285b6e2bb87..911edae98cfb 100644 --- a/packages/in_app_purchase/example/lib/main.dart +++ b/packages/in_app_purchase/example/lib/main.dart @@ -245,10 +245,12 @@ class _MyAppState extends State<_MyApp> { ), trailing: previousPurchase != null ? Icon(Icons.check) - : FlatButton( + : TextButton( child: Text(productDetails.price), - color: Colors.green[800], - textColor: Colors.white, + style: TextButton.styleFrom( + backgroundColor: Colors.green[800], + primary: Colors.white, + ), onPressed: () { PurchaseParam purchaseParam = PurchaseParam( productDetails: productDetails, diff --git a/packages/in_app_purchase/pubspec.yaml b/packages/in_app_purchase/pubspec.yaml index 883f8c39c273..02240ea654db 100644 --- a/packages/in_app_purchase/pubspec.yaml +++ b/packages/in_app_purchase/pubspec.yaml @@ -1,7 +1,7 @@ name: in_app_purchase description: A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases through the App Store and Google Play. homepage: https://github.com/flutter/plugins/tree/master/packages/in_app_purchase -version: 0.3.5 +version: 0.3.5+1 dependencies: async: ^2.0.8 diff --git a/packages/local_auth/CHANGELOG.md b/packages/local_auth/CHANGELOG.md index 863d72ed1da4..b27ec83d41a7 100644 --- a/packages/local_auth/CHANGELOG.md +++ b/packages/local_auth/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.0-nullsafety.3 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + ## 1.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/local_auth/example/lib/main.dart b/packages/local_auth/example/lib/main.dart index 241593a08b6a..0a07e2c4437d 100644 --- a/packages/local_auth/example/lib/main.dart +++ b/packages/local_auth/example/lib/main.dart @@ -99,17 +99,17 @@ class _MyAppState extends State { mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Text('Can check biometrics: $_canCheckBiometrics\n'), - RaisedButton( + ElevatedButton( child: const Text('Check biometrics'), onPressed: _checkBiometrics, ), Text('Available biometrics: $_availableBiometrics\n'), - RaisedButton( + ElevatedButton( child: const Text('Get available biometrics'), onPressed: _getAvailableBiometrics, ), Text('Current State: $_authorized\n'), - RaisedButton( + ElevatedButton( child: Text(_isAuthenticating ? 'Cancel' : 'Authenticate'), onPressed: _isAuthenticating ? _cancelAuthentication : _authenticate, diff --git a/packages/local_auth/pubspec.yaml b/packages/local_auth/pubspec.yaml index 444eec2efa53..050cedb5d7d0 100644 --- a/packages/local_auth/pubspec.yaml +++ b/packages/local_auth/pubspec.yaml @@ -2,7 +2,7 @@ name: local_auth description: Flutter plugin for Android and iOS device authentication sensors such as Fingerprint Reader and Touch ID. homepage: https://github.com/flutter/plugins/tree/master/packages/local_auth -version: 1.0.0-nullsafety.2 +version: 1.0.0-nullsafety.3 flutter: plugin: diff --git a/packages/path_provider/path_provider/CHANGELOG.md b/packages/path_provider/path_provider/CHANGELOG.md index f0e3cd9bfde8..bd6c0bc651f5 100644 --- a/packages/path_provider/path_provider/CHANGELOG.md +++ b/packages/path_provider/path_provider/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.27 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + ## 1.6.26 * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) diff --git a/packages/path_provider/path_provider/example/lib/main.dart b/packages/path_provider/path_provider/example/lib/main.dart index ce496e9d4e63..8e929a6882fe 100644 --- a/packages/path_provider/path_provider/example/lib/main.dart +++ b/packages/path_provider/path_provider/example/lib/main.dart @@ -129,7 +129,7 @@ class _MyHomePageState extends State { children: [ Padding( padding: const EdgeInsets.all(16.0), - child: RaisedButton( + child: ElevatedButton( child: const Text('Get Temporary Directory'), onPressed: _requestTempDirectory, ), @@ -138,7 +138,7 @@ class _MyHomePageState extends State { future: _tempDirectory, builder: _buildDirectory), Padding( padding: const EdgeInsets.all(16.0), - child: RaisedButton( + child: ElevatedButton( child: const Text('Get Application Documents Directory'), onPressed: _requestAppDocumentsDirectory, ), @@ -147,7 +147,7 @@ class _MyHomePageState extends State { future: _appDocumentsDirectory, builder: _buildDirectory), Padding( padding: const EdgeInsets.all(16.0), - child: RaisedButton( + child: ElevatedButton( child: const Text('Get Application Support Directory'), onPressed: _requestAppSupportDirectory, ), @@ -156,7 +156,7 @@ class _MyHomePageState extends State { future: _appSupportDirectory, builder: _buildDirectory), Padding( padding: const EdgeInsets.all(16.0), - child: RaisedButton( + child: ElevatedButton( child: const Text('Get Application Library Directory'), onPressed: _requestAppLibraryDirectory, ), @@ -165,7 +165,7 @@ class _MyHomePageState extends State { future: _appLibraryDirectory, builder: _buildDirectory), Padding( padding: const EdgeInsets.all(16.0), - child: RaisedButton( + child: ElevatedButton( child: Text( '${Platform.isIOS ? "External directories are unavailable " "on iOS" : "Get External Storage Directory"}'), onPressed: @@ -177,7 +177,7 @@ class _MyHomePageState extends State { Column(children: [ Padding( padding: const EdgeInsets.all(16.0), - child: RaisedButton( + child: ElevatedButton( child: Text( '${Platform.isIOS ? "External directories are unavailable " "on iOS" : "Get External Storage Directories"}'), onPressed: Platform.isIOS @@ -196,7 +196,7 @@ class _MyHomePageState extends State { Column(children: [ Padding( padding: const EdgeInsets.all(16.0), - child: RaisedButton( + child: ElevatedButton( child: Text( '${Platform.isIOS ? "External directories are unavailable " "on iOS" : "Get External Cache Directories"}'), onPressed: diff --git a/packages/path_provider/path_provider/pubspec.yaml b/packages/path_provider/path_provider/pubspec.yaml index 15f9c57a0c98..649b3420d72f 100644 --- a/packages/path_provider/path_provider/pubspec.yaml +++ b/packages/path_provider/path_provider/pubspec.yaml @@ -1,7 +1,7 @@ name: path_provider description: Flutter plugin for getting commonly used locations on host platform file systems, such as the temp and app data directories. homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider -version: 1.6.26 +version: 1.6.27 flutter: plugin: diff --git a/packages/path_provider/path_provider_macos/CHANGELOG.md b/packages/path_provider/path_provider_macos/CHANGELOG.md index d9be6859e125..b082aefd9da6 100644 --- a/packages/path_provider/path_provider_macos/CHANGELOG.md +++ b/packages/path_provider/path_provider_macos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.4+8 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + ## 0.0.4+7 * Update Flutter SDK constraint. diff --git a/packages/path_provider/path_provider_macos/example/lib/main.dart b/packages/path_provider/path_provider_macos/example/lib/main.dart index 473a989914f6..1c1c90b983c3 100644 --- a/packages/path_provider/path_provider_macos/example/lib/main.dart +++ b/packages/path_provider/path_provider_macos/example/lib/main.dart @@ -98,7 +98,7 @@ class _MyHomePageState extends State { children: [ Padding( padding: const EdgeInsets.all(16.0), - child: RaisedButton( + child: ElevatedButton( child: const Text('Get Temporary Directory'), onPressed: _requestTempDirectory, ), @@ -107,7 +107,7 @@ class _MyHomePageState extends State { future: _tempDirectory, builder: _buildDirectory), Padding( padding: const EdgeInsets.all(16.0), - child: RaisedButton( + child: ElevatedButton( child: const Text('Get Application Documents Directory'), onPressed: _requestAppDocumentsDirectory, ), @@ -116,7 +116,7 @@ class _MyHomePageState extends State { future: _appDocumentsDirectory, builder: _buildDirectory), Padding( padding: const EdgeInsets.all(16.0), - child: RaisedButton( + child: ElevatedButton( child: const Text('Get Application Support Directory'), onPressed: _requestAppSupportDirectory, ), @@ -125,7 +125,7 @@ class _MyHomePageState extends State { future: _appSupportDirectory, builder: _buildDirectory), Padding( padding: const EdgeInsets.all(16.0), - child: RaisedButton( + child: ElevatedButton( child: const Text('Get Application Library Directory'), onPressed: _requestAppLibraryDirectory, ), @@ -134,7 +134,7 @@ class _MyHomePageState extends State { future: _appLibraryDirectory, builder: _buildDirectory), Padding( padding: const EdgeInsets.all(16.0), - child: RaisedButton( + child: ElevatedButton( child: const Text('Get Downlads Directory'), onPressed: _requestDownloadsDirectory, ), diff --git a/packages/path_provider/path_provider_macos/pubspec.yaml b/packages/path_provider/path_provider_macos/pubspec.yaml index 05f03a7930ba..0af1cfbf0aaa 100644 --- a/packages/path_provider/path_provider_macos/pubspec.yaml +++ b/packages/path_provider/path_provider_macos/pubspec.yaml @@ -3,7 +3,7 @@ description: macOS implementation of the path_provider plugin # 0.0.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.0.4+7 +version: 0.0.4+8 homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_macos flutter: diff --git a/packages/share/CHANGELOG.md b/packages/share/CHANGELOG.md index eef22bfcc76e..855e737a1cd4 100644 --- a/packages/share/CHANGELOG.md +++ b/packages/share/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.2 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + ## 2.0.0-nullsafety.1 * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) diff --git a/packages/share/example/lib/main.dart b/packages/share/example/lib/main.dart index 7ebce3ce5591..a9ebd6bb79fb 100644 --- a/packages/share/example/lib/main.dart +++ b/packages/share/example/lib/main.dart @@ -78,7 +78,7 @@ class DemoAppState extends State { const Padding(padding: EdgeInsets.only(top: 12.0)), Builder( builder: (BuildContext context) { - return RaisedButton( + return ElevatedButton( child: const Text('Share'), onPressed: text.isEmpty && imagePaths.isEmpty ? null @@ -89,7 +89,7 @@ class DemoAppState extends State { const Padding(padding: EdgeInsets.only(top: 12.0)), Builder( builder: (BuildContext context) { - return RaisedButton( + return ElevatedButton( child: const Text('Share With Empty Origin'), onPressed: () => _onShareWithEmptyOrigin(context), ); @@ -110,11 +110,11 @@ class DemoAppState extends State { _onShare(BuildContext context) async { // A builder is used to retrieve the context immediately - // surrounding the RaisedButton. + // surrounding the ElevatedButton. // // The context's `findRenderObject` returns the first // RenderObject in its descendent tree when it's not - // a RenderObjectWidget. The RaisedButton's RenderObject + // a RenderObjectWidget. The ElevatedButton's RenderObject // has its position and size after it's built. final RenderBox box = context.findRenderObject(); diff --git a/packages/share/pubspec.yaml b/packages/share/pubspec.yaml index 07ead8f3f659..ca9b506bf35c 100644 --- a/packages/share/pubspec.yaml +++ b/packages/share/pubspec.yaml @@ -2,7 +2,7 @@ name: share description: Flutter plugin for sharing content via the platform share UI, using the ACTION_SEND intent on Android and UIActivityViewController on iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/share -version: 2.0.0-nullsafety.1 +version: 2.0.0-nullsafety.2 flutter: plugin: diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index eb08455c4785..73852cdfea12 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.0.0-nullsafety.4 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + ## 6.0.0-nullsafety.3 * forceSafariVC should be nullable. diff --git a/packages/url_launcher/url_launcher/example/lib/main.dart b/packages/url_launcher/url_launcher/example/lib/main.dart index b3e65f38a794..0b310490d0e9 100644 --- a/packages/url_launcher/url_launcher/example/lib/main.dart +++ b/packages/url_launcher/url_launcher/example/lib/main.dart @@ -141,7 +141,7 @@ class _MyHomePageState extends State { decoration: const InputDecoration( hintText: 'Input the phone number to launch')), ), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _makePhoneCall('tel:$_phone'); }), @@ -151,33 +151,33 @@ class _MyHomePageState extends State { padding: EdgeInsets.all(16.0), child: Text(toLaunch), ), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _launchInBrowser(toLaunch); }), child: const Text('Launch in browser'), ), const Padding(padding: EdgeInsets.all(16.0)), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _launchInWebViewOrVC(toLaunch); }), child: const Text('Launch in app'), ), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _launchInWebViewWithJavaScript(toLaunch); }), child: const Text('Launch in app(JavaScript ON)'), ), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _launchInWebViewWithDomStorage(toLaunch); }), child: const Text('Launch in app(DOM storage ON)'), ), const Padding(padding: EdgeInsets.all(16.0)), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _launchUniversalLinkIos(toLaunch); }), @@ -185,7 +185,7 @@ class _MyHomePageState extends State { 'Launch a universal link in a native app, fallback to Safari.(Youtube)'), ), const Padding(padding: EdgeInsets.all(16.0)), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _launchInWebViewOrVC(toLaunch); Timer(const Duration(seconds: 5), () { diff --git a/packages/url_launcher/url_launcher/example/test/url_launcher_example_test.dart b/packages/url_launcher/url_launcher/example/test/url_launcher_example_test.dart index eddc126a8e66..a890be7f65f1 100644 --- a/packages/url_launcher/url_launcher/example/test/url_launcher_example_test.dart +++ b/packages/url_launcher/url_launcher/example/test/url_launcher_example_test.dart @@ -32,7 +32,7 @@ void main() { headers: defaultHeaders)); Finder browserlaunchBtn = - find.widgetWithText(RaisedButton, 'Launch in browser'); + find.widgetWithText(ElevatedButton, 'Launch in browser'); expect(browserlaunchBtn, findsOneWidget); await tester.tap(browserlaunchBtn); diff --git a/packages/url_launcher/url_launcher/lib/src/link.dart b/packages/url_launcher/url_launcher/lib/src/link.dart index f859bc4ad2cf..14fdc9055d7a 100644 --- a/packages/url_launcher/url_launcher/lib/src/link.dart +++ b/packages/url_launcher/url_launcher/lib/src/link.dart @@ -17,7 +17,7 @@ import 'package:url_launcher_platform_interface/url_launcher_platform_interface. /// ```dart /// Link( /// uri: Uri.parse('https://flutter.dev'), -/// builder: (BuildContext context, FollowLink followLink) => RaisedButton( +/// builder: (BuildContext context, FollowLink followLink) => ElevatedButton( /// onPressed: followLink, /// // ... other properties here ... /// )}, @@ -29,7 +29,7 @@ import 'package:url_launcher_platform_interface/url_launcher_platform_interface. /// ```dart /// Link( /// uri: Uri.parse('/home'), -/// builder: (BuildContext context, FollowLink followLink) => RaisedButton( +/// builder: (BuildContext context, FollowLink followLink) => ElevatedButton( /// onPressed: followLink, /// // ... other properties here ... /// )}, diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index 0ab2d410c000..871c43ced733 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -2,7 +2,7 @@ name: url_launcher description: Flutter plugin for launching a URL on Android and iOS. Supports web, phone, SMS, and email schemes. homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher -version: 6.0.0-nullsafety.3 +version: 6.0.0-nullsafety.4 flutter: plugin: diff --git a/packages/url_launcher/url_launcher_linux/CHANGELOG.md b/packages/url_launcher/url_launcher_linux/CHANGELOG.md index cc3ee456c938..2d5a9a7d05af 100644 --- a/packages/url_launcher/url_launcher_linux/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_linux/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.0-nullsafety.3 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + ## 0.1.0-nullsafety.2 * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) diff --git a/packages/url_launcher/url_launcher_linux/example/lib/main.dart b/packages/url_launcher/url_launcher_linux/example/lib/main.dart index b5cce7482d07..a45862012328 100644 --- a/packages/url_launcher/url_launcher_linux/example/lib/main.dart +++ b/packages/url_launcher/url_launcher_linux/example/lib/main.dart @@ -140,7 +140,7 @@ class _MyHomePageState extends State { decoration: const InputDecoration( hintText: 'Input the phone number to launch')), ), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _makePhoneCall('tel:$_phone'); }), @@ -150,33 +150,33 @@ class _MyHomePageState extends State { padding: EdgeInsets.all(16.0), child: Text(toLaunch), ), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _launchInBrowser(toLaunch); }), child: const Text('Launch in browser'), ), const Padding(padding: EdgeInsets.all(16.0)), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _launchInWebViewOrVC(toLaunch); }), child: const Text('Launch in app'), ), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _launchInWebViewWithJavaScript(toLaunch); }), child: const Text('Launch in app(JavaScript ON)'), ), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _launchInWebViewWithDomStorage(toLaunch); }), child: const Text('Launch in app(DOM storage ON)'), ), const Padding(padding: EdgeInsets.all(16.0)), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _launchUniversalLinkIos(toLaunch); }), diff --git a/packages/url_launcher/url_launcher_linux/pubspec.yaml b/packages/url_launcher/url_launcher_linux/pubspec.yaml index 41366a1d4f1e..c7aac06b88e5 100644 --- a/packages/url_launcher/url_launcher_linux/pubspec.yaml +++ b/packages/url_launcher/url_launcher_linux/pubspec.yaml @@ -1,6 +1,6 @@ name: url_launcher_linux description: Linux implementation of the url_launcher plugin. -version: 0.1.0-nullsafety.2 +version: 0.1.0-nullsafety.3 homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_linux flutter: diff --git a/packages/url_launcher/url_launcher_macos/CHANGELOG.md b/packages/url_launcher/url_launcher_macos/CHANGELOG.md index 8a0e6575b5f2..a5477a1b1501 100644 --- a/packages/url_launcher/url_launcher_macos/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_macos/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.1.0-nullsafety.2 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + # 0.1.0-nullsafety.1 * Bump SDK to support null safety. diff --git a/packages/url_launcher/url_launcher_macos/example/lib/main.dart b/packages/url_launcher/url_launcher_macos/example/lib/main.dart index b5cce7482d07..a45862012328 100644 --- a/packages/url_launcher/url_launcher_macos/example/lib/main.dart +++ b/packages/url_launcher/url_launcher_macos/example/lib/main.dart @@ -140,7 +140,7 @@ class _MyHomePageState extends State { decoration: const InputDecoration( hintText: 'Input the phone number to launch')), ), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _makePhoneCall('tel:$_phone'); }), @@ -150,33 +150,33 @@ class _MyHomePageState extends State { padding: EdgeInsets.all(16.0), child: Text(toLaunch), ), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _launchInBrowser(toLaunch); }), child: const Text('Launch in browser'), ), const Padding(padding: EdgeInsets.all(16.0)), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _launchInWebViewOrVC(toLaunch); }), child: const Text('Launch in app'), ), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _launchInWebViewWithJavaScript(toLaunch); }), child: const Text('Launch in app(JavaScript ON)'), ), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _launchInWebViewWithDomStorage(toLaunch); }), child: const Text('Launch in app(DOM storage ON)'), ), const Padding(padding: EdgeInsets.all(16.0)), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _launchUniversalLinkIos(toLaunch); }), diff --git a/packages/url_launcher/url_launcher_macos/pubspec.yaml b/packages/url_launcher/url_launcher_macos/pubspec.yaml index 9ce9c9c47ea9..be2dd2739298 100644 --- a/packages/url_launcher/url_launcher_macos/pubspec.yaml +++ b/packages/url_launcher/url_launcher_macos/pubspec.yaml @@ -3,7 +3,7 @@ description: macOS implementation of the url_launcher plugin. # 0.0.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.1.0-nullsafety.1 +version: 0.1.0-nullsafety.2 homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_macos flutter: diff --git a/packages/url_launcher/url_launcher_windows/CHANGELOG.md b/packages/url_launcher/url_launcher_windows/CHANGELOG.md index e9649ff6fd1e..a1998c92e2e2 100644 --- a/packages/url_launcher/url_launcher_windows/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_windows/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.0-nullsafety.2 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + ## 0.1.0-nullsafety.1 * Bump Dart SDK to support null safety. diff --git a/packages/url_launcher/url_launcher_windows/example/lib/main.dart b/packages/url_launcher/url_launcher_windows/example/lib/main.dart index db59af1e5b95..e6c9f477b5a4 100644 --- a/packages/url_launcher/url_launcher_windows/example/lib/main.dart +++ b/packages/url_launcher/url_launcher_windows/example/lib/main.dart @@ -76,7 +76,7 @@ class _MyHomePageState extends State { padding: EdgeInsets.all(16.0), child: Text(toLaunch), ), - RaisedButton( + ElevatedButton( onPressed: () => setState(() { _launched = _launchInBrowser(toLaunch); }), diff --git a/packages/url_launcher/url_launcher_windows/pubspec.yaml b/packages/url_launcher/url_launcher_windows/pubspec.yaml index d2da4c534322..f7c96bf4a1bd 100644 --- a/packages/url_launcher/url_launcher_windows/pubspec.yaml +++ b/packages/url_launcher/url_launcher_windows/pubspec.yaml @@ -3,7 +3,7 @@ description: Windows implementation of the url_launcher plugin. # 0.0.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.1.0-nullsafety.1 +version: 0.1.0-nullsafety.2 homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_windows flutter: diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index c79b0a02bc98..f9bae8dee6e1 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.7 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + ## 2.0.0-nullsafety.6 * Fix `VideoPlayerValue toString()` test. diff --git a/packages/video_player/video_player/example/lib/main.dart b/packages/video_player/video_player/example/lib/main.dart index 42eaaa578fcf..c874f740eab2 100644 --- a/packages/video_player/video_player/example/lib/main.dart +++ b/packages/video_player/video_player/example/lib/main.dart @@ -124,13 +124,13 @@ class _ExampleCard extends StatelessWidget { ), ButtonBar( children: [ - FlatButton( + TextButton( child: const Text('BUY TICKETS'), onPressed: () { /* ... */ }, ), - FlatButton( + TextButton( child: const Text('SELL TICKETS'), onPressed: () { /* ... */ diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index a8066e129608..e4694195ebde 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -4,7 +4,7 @@ description: Flutter plugin for displaying inline video with other Flutter # 0.10.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 2.0.0-nullsafety.6 +version: 2.0.0-nullsafety.7 homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player flutter: From 105c2bca87e97569aa63a491fdada81451b03850 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Fri, 8 Jan 2021 09:04:04 -0800 Subject: [PATCH 0024/1565] fix version (#3399) --- packages/image_picker/image_picker/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index af409fd1c5b3..789ca13d5bcb 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker description: Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker -version: 0.6.7+20 +version: 0.6.7+21 flutter: plugin: From d01c84cb64d12c8f5e92fd9ed44e04b6350cd973 Mon Sep 17 00:00:00 2001 From: Zachary Anderson Date: Fri, 8 Jan 2021 09:09:05 -0800 Subject: [PATCH 0025/1565] Ignore deprecated_member_use analysis lint (#3400) --- .../lib/src/path_provider_windows_real.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart index 7ff448abf020..e1063957879e 100644 --- a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart +++ b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart @@ -123,7 +123,11 @@ class PathProviderWindows extends PathProviderPlatform { GUID knownFolderID = GUID.fromString(folderID); final hr = SHGetKnownFolderPath( - knownFolderID.addressOf, KF_FLAG_DEFAULT, NULL, pathPtrPtr); + knownFolderID.addressOf, // ignore: deprecated_member_use + KF_FLAG_DEFAULT, + NULL, + pathPtrPtr, + ); if (FAILED(hr)) { if (hr == E_INVALIDARG || hr == E_FAIL) { From b3bc1f2e246f78593b40c6d6cfbbd1ae36c9324b Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Fri, 8 Jan 2021 14:12:00 -0500 Subject: [PATCH 0026/1565] [battery] Migrate battery_plugin_interface to null safety (#3366) --- .../battery/battery_platform_interface/CHANGELOG.md | 4 ++++ .../lib/method_channel/method_channel_battery.dart | 9 +++++---- .../battery/battery_platform_interface/pubspec.yaml | 12 ++++++------ .../test/method_channel_battery_test.dart | 10 +++++----- script/nnbd_plugins.sh | 1 + 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/packages/battery/battery_platform_interface/CHANGELOG.md b/packages/battery/battery_platform_interface/CHANGELOG.md index 09ac38cc5b4b..6fc7228a89f9 100644 --- a/packages/battery/battery_platform_interface/CHANGELOG.md +++ b/packages/battery/battery_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Migrate to null safety. + ## 1.0.1 - Update Flutter SDK constraint. diff --git a/packages/battery/battery_platform_interface/lib/method_channel/method_channel_battery.dart b/packages/battery/battery_platform_interface/lib/method_channel/method_channel_battery.dart index 4a3365cc2475..739812dc95e5 100644 --- a/packages/battery/battery_platform_interface/lib/method_channel/method_channel_battery.dart +++ b/packages/battery/battery_platform_interface/lib/method_channel/method_channel_battery.dart @@ -11,11 +11,11 @@ import '../battery_platform_interface.dart'; class MethodChannelBattery extends BatteryPlatform { /// The method channel used to interact with the native platform. @visibleForTesting - MethodChannel channel = MethodChannel('plugins.flutter.io/battery'); + final MethodChannel channel = MethodChannel('plugins.flutter.io/battery'); /// The event channel used to interact with the native platform. @visibleForTesting - EventChannel eventChannel = EventChannel('plugins.flutter.io/charging'); + final EventChannel eventChannel = EventChannel('plugins.flutter.io/charging'); /// Method channel for getting battery level. Future batteryLevel() async { @@ -23,7 +23,7 @@ class MethodChannelBattery extends BatteryPlatform { } /// Stream variable for storing battery state. - Stream _onBatteryStateChanged; + Stream? _onBatteryStateChanged; /// Event channel for getting battery change state. Stream onBatteryStateChanged() { @@ -32,7 +32,8 @@ class MethodChannelBattery extends BatteryPlatform { .receiveBroadcastStream() .map((dynamic event) => _parseBatteryState(event)); } - return _onBatteryStateChanged; + + return _onBatteryStateChanged!; } } diff --git a/packages/battery/battery_platform_interface/pubspec.yaml b/packages/battery/battery_platform_interface/pubspec.yaml index e88ef378be6e..c7c4f5e8395e 100644 --- a/packages/battery/battery_platform_interface/pubspec.yaml +++ b/packages/battery/battery_platform_interface/pubspec.yaml @@ -3,20 +3,20 @@ description: A common platform interface for the battery plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/battery # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.0.1 +version: 2.0.0-nullsafety dependencies: flutter: sdk: flutter - meta: ^1.1.8 - plugin_platform_interface: ^1.0.2 + meta: ^1.3.0-nullsafety + plugin_platform_interface: ^1.1.0-nullsafety.1 dev_dependencies: flutter_test: sdk: flutter - mockito: ^4.1.1 - pedantic: ^1.8.0 + mockito: ^5.0.0-nullsafety.0 + pedantic: ^1.10.0-nullsafety environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.9.1+hotfix.4" diff --git a/packages/battery/battery_platform_interface/test/method_channel_battery_test.dart b/packages/battery/battery_platform_interface/test/method_channel_battery_test.dart index 65323e4044de..2b17cf97e711 100644 --- a/packages/battery/battery_platform_interface/test/method_channel_battery_test.dart +++ b/packages/battery/battery_platform_interface/test/method_channel_battery_test.dart @@ -12,8 +12,8 @@ import 'package:battery_platform_interface/method_channel/method_channel_battery void main() { TestWidgetsFlutterBinding.ensureInitialized(); - group("$MethodChannelBattery", () { - MethodChannelBattery methodChannelBattery; + group('$MethodChannelBattery', () { + late MethodChannelBattery methodChannelBattery; setUp(() async { methodChannelBattery = MethodChannelBattery(); @@ -32,7 +32,7 @@ void main() { .setMockMethodCallHandler((MethodCall methodCall) async { switch (methodCall.method) { case 'listen': - await ServicesBinding.instance.defaultBinaryMessenger + await ServicesBinding.instance!.defaultBinaryMessenger .handlePlatformMessage( methodChannelBattery.eventChannel.name, methodChannelBattery.eventChannel.codec @@ -48,13 +48,13 @@ void main() { }); /// Test for batetry level call. - test("getBatteryLevel", () async { + test('getBatteryLevel', () async { final int result = await methodChannelBattery.batteryLevel(); expect(result, 90); }); /// Test for battery changed state call. - test("onBatteryChanged", () async { + test('onBatteryChanged', () async { final BatteryState result = await methodChannelBattery.onBatteryStateChanged().first; expect(result, BatteryState.full); diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index 0cab28abe2ab..7bc5ac35a3a5 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -6,6 +6,7 @@ readonly NNBD_PLUGINS_LIST=( "android_intent" + "battery" "connectivity" "device_info" "flutter_plugin_android_lifecycle" From 34faaafe507126c2ec636759df323b256cd6920f Mon Sep 17 00:00:00 2001 From: Ian Hickson Date: Fri, 8 Jan 2021 16:44:05 -0800 Subject: [PATCH 0027/1565] Sync the PR template to the new style (#3397) --- .github/PULL_REQUEST_TEMPLATE.md | 43 ++++++++++++++------------------ 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 083e125b32d2..741216982d35 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,37 +1,32 @@ -## Description +*Replace this paragraph with a description of what this PR is changing or adding, and why. Consider including before/after screenshots.* -*Replace this paragraph with a description of what this PR is doing. If you're modifying existing behavior, describe the existing behavior, how this PR is changing it, and what motivated the change.* +*List which issues are fixed by this PR. You must list at least one issue.* -## Related Issues +*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].* -*Replace this paragraph with a list of issues related to this PR from the [issue database](https://github.com/flutter/flutter/issues). Indicate, which of these issues are resolved or fixed by this PR. Note that you'll have to prefix the issue numbers with flutter/flutter#.* - -## Checklist - -Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes (`[x]`). This will ensure a smooth and quick review process. +## Pre-launch Checklist +- [ ] The title of the PR starts with the name of the plugin surrounded by square brackets, e.g. `[shared_preferences]` - [ ] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. -- [ ] My PR includes unit or integration tests for *all* changed/updated/fixed behaviors (See [Contributor Guide]). -- [ ] All existing and new tests are passing. -- [ ] I updated/added relevant documentation (doc comments with `///`). -- [ ] The analyzer (`flutter analyze`) does not report any problems on my PR. -- [ ] I read and followed the [Flutter Style Guide]. -- [ ] The title of the PR starts with the name of the plugin surrounded by square brackets, e.g. [shared_preferences] +- [ ] I read the [Tree Hygiene] wiki page, which explains my responsibilities. +- [ ] I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides]. +- [ ] I listed at least one issue that this PR fixes in the description above. +- [ ] I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test exempt. - [ ] I updated pubspec.yaml with an appropriate new version according to the [pub versioning philosophy]. - [ ] I updated CHANGELOG.md to add a description of the change. +- [ ] I updated/added relevant documentation (doc comments with `///`). - [ ] I signed the [CLA]. -- [ ] I am willing to follow-up on review comments in a timely manner. - -## Breaking Change - -Does your PR require plugin users to manually update their apps to accommodate your change? +- [ ] All existing and new tests are passing. -- [ ] Yes, this is a breaking change (please indicate a breaking change in CHANGELOG.md and increment major revision). -- [ ] No, this is *not* a breaking change. +If you need help, consider asking for advice on the #hackers-new channel on [Discord]. -[issue database]: https://github.com/flutter/flutter/issues -[Contributor Guide]: https://github.com/flutter/plugins/blob/master/CONTRIBUTING.md +[Contributor Guide]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview +[Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo -[pub versioning philosophy]: https://www.dartlang.org/tools/pub/versioning +[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/master/CONTRIBUTING.md#style [CLA]: https://cla.developers.google.com/ +[flutter/tests]: https://github.com/flutter/tests +[breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes +[Discord]: https://github.com/flutter/flutter/wiki/Chat +[pub versioning philosophy]: https://dart.dev/tools/pub/versioning From da1b4638b750a5ff832d7be86a42831c42c6d6c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl?= <32639467+danielroek@users.noreply.github.com> Date: Mon, 11 Jan 2021 14:56:10 +0100 Subject: [PATCH 0028/1565] [camera] Implemented ImageStream ImageFormat setting for Dart and Android (#3359) * Implemented ImageStream ImageFormat setting for Dart and Android * Fixed formatting and toString test * Apply suggestions from code review * Removed imageStreamImageFormat from CameraValue * Removed imageStreamImageFormat from CameraValue * Removed imageStreamImageFormat from CameraValue * fixed formatting * fixed formatting * fixed formatting * WIP: iOS implementation * Imaplemented suggested changes, added tests. * iOS switch case videoFormat * Added imageFormatGroup to initialize * Apply suggestions from code review Co-authored-by: Maurits van Beusekom * Added period to sentence * Moved ImageFormatGroup to platform_interface; Added extension to convert ImageFormatGroup to name; Changed int to ImageFormatGroup for initializeCamera * Fixed test * Separated Android and iOS in name extension * Clarified returns on name extension * updated Android implementation to support String output * removed getOrDefault * Updated camera implementation to use ImageFormatGroupName; Updated to Dart 2.7.0 to support extensions; * removed unused import * Export image_format_group.dart in types.dart * Changed enum values to lowercase * Added ImageFormatGroup test * Fixed formatting * made enum strings lowercase * Removed target platform switch. * Fixed formatting * Updated Android implementation * Updated iOS implementation * updated log message for unsupported ImageFormatGroup * Updated Android implementation * fixed period in docs * Switch change to if-statement * Moved switching videoFormat to method in iOS * Implemented feedback * fixed formatting * fixed mistakingly removed bracket * fixed formatting * Updated version * Updated version * fixed formatting * Define TAG correctly Co-authored-by: anniek Co-authored-by: Maurits van Beusekom Co-authored-by: Maurits van Beusekom --- packages/camera/camera/CHANGELOG.md | 5 ++- .../io/flutter/plugins/camera/Camera.java | 21 +++++++++-- .../plugins/camera/MethodCallHandlerImpl.java | 2 +- packages/camera/camera/example/lib/main.dart | 1 + packages/camera/camera/example/pubspec.yaml | 2 +- .../camera/camera/ios/Classes/CameraPlugin.m | 16 +++++++- packages/camera/camera/lib/camera.dart | 3 +- .../camera/lib/src/camera_controller.dart | 11 +++++- .../camera/camera/lib/src/camera_image.dart | 37 ++++--------------- packages/camera/camera/pubspec.yaml | 6 +-- .../camera/camera/test/camera_image_test.dart | 1 + packages/camera/camera/test/camera_test.dart | 21 +++++++++++ 12 files changed, 85 insertions(+), 41 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 2f9b5399d6dd..0ba77e5ee1d5 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.6.5 + +* Adds ImageFormat selection for ImageStream and Video(iOS only). ## 0.6.4+5 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. @@ -16,7 +19,7 @@ ## 0.6.4+1 -* Added closeCaptureSession() to stopVideoRecording in Camera.java to fix an Android 6 crash +* Added closeCaptureSession() to stopVideoRecording in Camera.java to fix an Android 6 crash. ## 0.6.4 diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 40656cbabcf1..fd7f4d67fa04 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -67,6 +67,8 @@ interface ErrorCallback { } public class Camera { + private static final String TAG = "Camera"; + private final SurfaceTextureEntry flutterTexture; private final CameraManager cameraManager; private final OrientationEventListener orientationEventListener; @@ -99,6 +101,14 @@ public class Camera { private boolean useAutoFocus = true; private Range fpsRange; + private static final HashMap supportedImageFormats; + // Current supported outputs + static { + supportedImageFormats = new HashMap<>(); + supportedImageFormats.put("yuv420", 35); + supportedImageFormats.put("jpeg", 256); + } + public Camera( final Activity activity, final SurfaceTextureEntry flutterTexture, @@ -183,15 +193,20 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException { } @SuppressLint("MissingPermission") - public void open() throws CameraAccessException { + public void open(String imageFormatGroup) throws CameraAccessException { pictureImageReader = ImageReader.newInstance( captureSize.getWidth(), captureSize.getHeight(), ImageFormat.JPEG, 2); + Integer imageFormat = supportedImageFormats.get(imageFormatGroup); + if (imageFormat == null) { + Log.w(TAG, "The selected imageFormatGroup is not supported by Android. Defaulting to yuv420"); + imageFormat = ImageFormat.YUV_420_888; + } + // Used to steam image byte data to dart side. imageStreamReader = - ImageReader.newInstance( - previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2); + ImageReader.newInstance(previewSize.getWidth(), previewSize.getHeight(), imageFormat, 2); cameraManager.openCamera( cameraName, diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java index 2ceff845ed4b..95c0b198e43d 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java @@ -80,7 +80,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) { if (camera != null) { try { - camera.open(); + camera.open(call.argument("imageFormatGroup")); result.success(null); } catch (Exception e) { handleException(e, result); diff --git a/packages/camera/camera/example/lib/main.dart b/packages/camera/camera/example/lib/main.dart index 5324e3d09383..6eaf66a256de 100644 --- a/packages/camera/camera/example/lib/main.dart +++ b/packages/camera/camera/example/lib/main.dart @@ -486,6 +486,7 @@ class _CameraExampleHomeState extends State cameraDescription, ResolutionPreset.medium, enableAudio: enableAudio, + imageFormatGroup: ImageFormatGroup.jpeg, ); // If the controller is updated then update the UI. diff --git a/packages/camera/camera/example/pubspec.yaml b/packages/camera/camera/example/pubspec.yaml index 0d1f03bef437..5d59ebf75c62 100644 --- a/packages/camera/camera/example/pubspec.yaml +++ b/packages/camera/camera/example/pubspec.yaml @@ -22,5 +22,5 @@ flutter: uses-material-design: true environment: - sdk: ">=2.0.0-dev.28.0 <3.0.0" + sdk: ">=2.7.0 <3.0.0" flutter: ">=1.9.1+hotfix.4 <2.0.0" diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index 816792e2fc1d..d1ef0e5c923e 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -162,6 +162,17 @@ static FlashMode getFlashModeForString(NSString *mode) { } } +static OSType getVideoFormatFromString(NSString *videoFormatString) { + if ([videoFormatString isEqualToString:@"bgra8888"]) { + return kCVPixelFormatType_32BGRA; + } else if ([videoFormatString isEqualToString:@"yuv420"]) { + return kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; + } else { + NSLog(@"The selected imageFormatGroup is not supported by iOS. Defaulting to brga8888"); + return kCVPixelFormatType_32BGRA; + } +} + static AVCaptureFlashMode getAVCaptureFlashModeForFlashMode(FlashMode mode) { switch (mode) { case FlashModeOff: @@ -296,7 +307,7 @@ @implementation FLTCam { dispatch_queue_t _dispatchQueue; } // Format used for video and image streaming. -FourCharCode const videoFormat = kCVPixelFormatType_32BGRA; +FourCharCode videoFormat = kCVPixelFormatType_32BGRA; NSString *const errorMethod = @"error"; - (instancetype)initWithCameraName:(NSString *)cameraName @@ -1147,6 +1158,9 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re NSDictionary *argsMap = call.arguments; NSUInteger cameraId = ((NSNumber *)argsMap[@"cameraId"]).unsignedIntegerValue; if ([@"initialize" isEqualToString:call.method]) { + NSString *videoFormatValue = ((NSString *)argsMap[@"imageFormatGroup"]); + videoFormat = getVideoFormatFromString(videoFormatValue); + __weak CameraPlugin *weakSelf = self; _camera.onFrameAvailable = ^{ [weakSelf.registry textureFrameAvailable:cameraId]; diff --git a/packages/camera/camera/lib/camera.dart b/packages/camera/camera/lib/camera.dart index 55e7aa9444aa..8058ea8f9cb1 100644 --- a/packages/camera/camera/lib/camera.dart +++ b/packages/camera/camera/lib/camera.dart @@ -14,4 +14,5 @@ export 'package:camera_platform_interface/camera_platform_interface.dart' FlashMode, ExposureMode, ResolutionPreset, - XFile; + XFile, + ImageFormatGroup; diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index c1f44bc9630a..53b990e783f3 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -160,6 +160,7 @@ class CameraController extends ValueNotifier { this.description, this.resolutionPreset, { this.enableAudio = true, + this.imageFormatGroup, }) : super(const CameraValue.uninitialized()); /// The properties of the camera device controlled by this controller. @@ -176,6 +177,11 @@ class CameraController extends ValueNotifier { /// Whether to include audio when recording a video. final bool enableAudio; + /// The [ImageFormatGroup] describes the output of the raw image format. + /// + /// When null the imageFormat will fallback to the platforms default. + final ImageFormatGroup imageFormatGroup; + int _cameraId; bool _isDisposed = false; StreamSubscription _imageStreamSubscription; @@ -217,7 +223,10 @@ class CameraController extends ValueNotifier { _initializeCompleter.complete(event); })); - await CameraPlatform.instance.initializeCamera(_cameraId); + await CameraPlatform.instance.initializeCamera( + _cameraId, + imageFormatGroup: imageFormatGroup, + ); value = value.copyWith( isInitialized: true, diff --git a/packages/camera/camera/lib/src/camera_image.dart b/packages/camera/camera/lib/src/camera_image.dart index ca8115eb758d..dffa5066d14f 100644 --- a/packages/camera/camera/lib/src/camera_image.dart +++ b/packages/camera/camera/lib/src/camera_image.dart @@ -6,6 +6,7 @@ import 'dart:typed_data'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:camera_platform_interface/camera_platform_interface.dart'; /// A single color plane of image data. /// @@ -41,32 +42,6 @@ class Plane { final int width; } -// TODO:(bmparr) Turn [ImageFormatGroup] to a class with int values. -/// Group of image formats that are comparable across Android and iOS platforms. -enum ImageFormatGroup { - /// The image format does not fit into any specific group. - unknown, - - /// Multi-plane YUV 420 format. - /// - /// This format is a generic YCbCr format, capable of describing any 4:2:0 - /// chroma-subsampled planar or semiplanar buffer (but not fully interleaved), - /// with 8 bits per color sample. - /// - /// On Android, this is `android.graphics.ImageFormat.YUV_420_888`. See - /// https://developer.android.com/reference/android/graphics/ImageFormat.html#YUV_420_888 - /// - /// On iOS, this is `kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange`. See - /// https://developer.apple.com/documentation/corevideo/1563591-pixel_format_identifiers/kcvpixelformattype_420ypcbcr8biplanarvideorange?language=objc - yuv420, - - /// 32-bit BGRA. - /// - /// On iOS, this is `kCVPixelFormatType_32BGRA`. See - /// https://developer.apple.com/documentation/corevideo/1563591-pixel_format_identifiers/kcvpixelformattype_32bgra?language=objc - bgra8888, -} - /// Describes how pixels are represented in an image. class ImageFormat { ImageFormat._fromPlatformData(this.raw) : group = _asImageFormatGroup(raw); @@ -86,9 +61,13 @@ class ImageFormat { ImageFormatGroup _asImageFormatGroup(dynamic rawFormat) { if (defaultTargetPlatform == TargetPlatform.android) { - // android.graphics.ImageFormat.YUV_420_888 - if (rawFormat == 35) { - return ImageFormatGroup.yuv420; + switch (rawFormat) { + // android.graphics.ImageFormat.YUV_420_888 + case 35: + return ImageFormatGroup.yuv420; + // android.graphics.ImageFormat.JPEG + case 256: + return ImageFormatGroup.jpeg; } } diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 50f504a8d0e8..7c275c2268cd 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,13 +2,13 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.6.4+5 +version: 0.6.5 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: flutter: sdk: flutter - camera_platform_interface: ^1.2.0 + camera_platform_interface: ^1.3.0 pedantic: ^1.8.0 dev_dependencies: @@ -31,5 +31,5 @@ flutter: pluginClass: CameraPlugin environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.7.0 <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/camera/camera/test/camera_image_test.dart b/packages/camera/camera/test/camera_image_test.dart index c8f808f2c1a1..c7f8e4320434 100644 --- a/packages/camera/camera/test/camera_image_test.dart +++ b/packages/camera/camera/test/camera_image_test.dart @@ -5,6 +5,7 @@ import 'dart:typed_data'; import 'package:camera/camera.dart'; +import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index 5a4a7fc8771b..4f2109371392 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -8,6 +8,7 @@ import 'dart:ui'; import 'package:camera/camera.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -164,6 +165,22 @@ void main() { mockPlatformException = false; }); + test('initialize() sets imageFormat', () async { + debugDefaultTargetPlatformOverride = TargetPlatform.android; + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max, + imageFormatGroup: ImageFormatGroup.yuv420, + ); + await cameraController.initialize(); + verify(CameraPlatform.instance + .initializeCamera(13, imageFormatGroup: ImageFormatGroup.yuv420)) + .called(1); + }); + test('prepareForVideoRecording() calls $CameraPlatform ', () async { CameraController cameraController = CameraController( CameraDescription( @@ -1004,6 +1021,10 @@ class MockCameraPlatform extends Mock with MockPlatformInterfaceMixin implements CameraPlatform { @override + Future initializeCamera(int cameraId, + {ImageFormatGroup imageFormatGroup}); + + @override Future> availableCameras() => Future.value(mockAvailableCameras); From 71a831790220f898bf8120c8a23840ac6e742db5 Mon Sep 17 00:00:00 2001 From: Bodhi Mulders Date: Mon, 11 Jan 2021 17:20:24 +0100 Subject: [PATCH 0029/1565] [camera] Add iOS and Android implementations for managing auto focus. (#3370) * Added platform interface methods for setting auto exposure. * Added platform interface methods for setting auto exposure. * Remove workspace files * Added auto exposure implementations for Android and iOS * Added platform interface methods for managing auto focus. * Formatted code * Export focus mode * Add Android and iOS implementations (WIP) * Update platform interface for changes to autofocus methods * WIP * Revert "Update platform interface for changes to autofocus methods" This reverts commit bdeed1d213a9f106d0bd80b8905c0ae3af29886e. * Finish android implementation * Fix iOS implementation * iOS fix for setting the exposure point * Removed unnecessary check * Updated changelog and pubspec.yaml * Updated changelog and pubspec.yaml * Update platform interface dependency * Implement PR feedback * Restore test * Revert test change * Update camera pubspec * Update platform interface to prevent breaking changes with current master * Update test to match platform interface updates * Code format * Fixed compilation error * Fix formatting * Add missing license headers to java source files. * Update platform interface dependency * Change fps range determination * Fix analysis warnings Co-authored-by: Maurits van Beusekom --- packages/camera/camera/CHANGELOG.md | 5 + .../io/flutter/plugins/camera/Camera.java | 115 ++++++++++++++--- .../plugins/camera/CameraPermissions.java | 4 + .../flutter/plugins/camera/CameraRegions.java | 17 +++ .../flutter/plugins/camera/CameraUtils.java | 4 + .../io/flutter/plugins/camera/CameraZoom.java | 4 + .../flutter/plugins/camera/DartMessenger.java | 13 +- .../plugins/camera/MethodCallHandlerImpl.java | 36 ++++++ .../plugins/camera/PictureCaptureRequest.java | 4 + .../camera/media/MediaRecorderBuilder.java | 1 + .../plugins/camera/types/ExposureMode.java | 4 + .../plugins/camera/types/FlashMode.java | 4 + .../plugins/camera/types/FocusMode.java | 29 +++++ .../camera/types/ResolutionPreset.java | 4 + .../plugins/camera/CameraPermissionsTest.java | 4 + .../plugins/camera/CameraRegionsTest.java | 21 ++++ .../plugins/camera/CameraZoomTest.java | 4 + .../plugins/camera/DartMessengerTest.java | 9 +- .../camera/PictureCaptureRequestTest.java | 4 + .../media/MediaRecorderBuilderTest.java | 4 + .../camera/types/ExposureModeTest.java | 4 + .../plugins/camera/types/FlashModeTest.java | 4 + .../plugins/camera/types/FocusModeTest.java | 34 +++++ packages/camera/camera/example/lib/main.dart | 104 ++++++++++++++- .../camera/camera/ios/Classes/CameraPlugin.m | 118 ++++++++++++++++-- packages/camera/camera/lib/camera.dart | 1 + .../camera/lib/src/camera_controller.dart | 53 +++++++- packages/camera/camera/pubspec.yaml | 4 +- packages/camera/camera/test/camera_test.dart | 11 +- .../camera/camera/test/camera_value_test.dart | 5 +- 30 files changed, 591 insertions(+), 37 deletions(-) create mode 100644 packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FocusMode.java create mode 100644 packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FocusModeTest.java diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 0ba77e5ee1d5..1a2b03d93a6a 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,6 +1,11 @@ +## 0.6.6 + +* Adds auto focus support for Android and iOS implementations. + ## 0.6.5 * Adds ImageFormat selection for ImageStream and Video(iOS only). + ## 0.6.4+5 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index fd7f4d67fa04..3fc702a2a879 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera; import static android.view.OrientationEventListener.ORIENTATION_UNKNOWN; @@ -47,6 +51,7 @@ import io.flutter.plugins.camera.media.MediaRecorderBuilder; import io.flutter.plugins.camera.types.ExposureMode; import io.flutter.plugins.camera.types.FlashMode; +import io.flutter.plugins.camera.types.FocusMode; import io.flutter.plugins.camera.types.ResolutionPreset; import io.flutter.view.TextureRegistry.SurfaceTextureEntry; import java.io.File; @@ -95,6 +100,7 @@ public class Camera { private int currentOrientation = ORIENTATION_UNKNOWN; private FlashMode flashMode; private ExposureMode exposureMode; + private FocusMode focusMode; private PictureCaptureRequest pictureCaptureRequest; private CameraRegions cameraRegions; private int exposureOffset; @@ -128,6 +134,7 @@ public Camera( this.applicationContext = activity.getApplicationContext(); this.flashMode = FlashMode.auto; this.exposureMode = ExposureMode.auto; + this.focusMode = FocusMode.auto; this.exposureOffset = 0; orientationEventListener = new OrientationEventListener(activity.getApplicationContext()) { @@ -168,7 +175,7 @@ private void initFps(CameraCharacteristics cameraCharacteristics) { int upper = range.getUpper(); Log.i("Camera", "[FPS Range Available] is:" + range); if (upper >= 10) { - if (fpsRange == null || upper < fpsRange.getUpper()) { + if (fpsRange == null || upper > fpsRange.getUpper()) { fpsRange = range; } } @@ -221,7 +228,9 @@ public void onOpened(@NonNull CameraDevice device) { previewSize.getWidth(), previewSize.getHeight(), exposureMode, - isExposurePointSupported()); + focusMode, + isExposurePointSupported(), + isFocusPointSupported()); } catch (CameraAccessException e) { dartMessenger.sendCameraErrorEvent(e.getMessage()); close(); @@ -309,7 +318,7 @@ public void onConfigured(@NonNull CameraCaptureSession session) { cameraCaptureSession = session; updateFpsRange(); - updateAutoFocus(); + updateFocus(focusMode); updateFlash(flashMode); updateExposure(exposureMode); @@ -510,7 +519,7 @@ private void runPictureAutoFocus() { assert (pictureCaptureRequest != null); pictureCaptureRequest.setState(PictureCaptureRequest.State.focusing); - lockAutoFocus(); + lockAutoFocus(pictureCaptureCallback); } private void runPicturePreCapture() { @@ -570,7 +579,7 @@ public void onCaptureCompleted( } } - private void lockAutoFocus() { + private void lockAutoFocus(CaptureCallback callback) { captureRequestBuilder.set( CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START); @@ -581,7 +590,7 @@ private void lockAutoFocus() { private void unlockAutoFocus() { captureRequestBuilder.set( CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL); - updateAutoFocus(); + updateFocus(focusMode); try { cameraCaptureSession.capture(captureRequestBuilder.build(), null, null); } catch (CameraAccessException ignored) { @@ -764,25 +773,72 @@ public void setExposurePoint(@NonNull final Result result, Double x, Double y) "setExposurePointFailed", "Device does not have exposure point capabilities", null); return; } - // Check if we are doing a reset or not - if (x == null || y == null) { - x = 0.5; - y = 0.5; - } - // Get the current region boundaries. - Size maxBoundaries = getRegionBoundaries(); - if (maxBoundaries == null) { + // Check if the current region boundaries are known + if (cameraRegions.getMaxBoundaries() == null) { result.error("setExposurePointFailed", "Could not determine max region boundaries", null); return; } // Set the metering rectangle - cameraRegions.setAutoExposureMeteringRectangleFromPoint(x, y); + if (x == null || y == null) cameraRegions.resetAutoExposureMeteringRectangle(); + else cameraRegions.setAutoExposureMeteringRectangleFromPoint(x, y); // Apply it updateExposure(exposureMode); refreshPreviewCaptureSession( () -> result.success(null), (code, message) -> result.error("CameraAccess", message, null)); } + public void setFocusMode(@NonNull final Result result, FocusMode mode) + throws CameraAccessException { + this.focusMode = mode; + + updateFocus(mode); + + switch (mode) { + case auto: + refreshPreviewCaptureSession( + null, (code, message) -> result.error("setFocusMode", message, null)); + break; + case locked: + lockAutoFocus( + new CaptureCallback() { + @Override + public void onCaptureCompleted( + @NonNull CameraCaptureSession session, + @NonNull CaptureRequest request, + @NonNull TotalCaptureResult result) { + unlockAutoFocus(); + } + }); + break; + } + result.success(null); + } + + public void setFocusPoint(@NonNull final Result result, Double x, Double y) + throws CameraAccessException { + // Check if focus point functionality is available. + if (!isFocusPointSupported()) { + result.error("setFocusPointFailed", "Device does not have focus point capabilities", null); + return; + } + + // Check if the current region boundaries are known + if (cameraRegions.getMaxBoundaries() == null) { + result.error("setFocusPointFailed", "Could not determine max region boundaries", null); + return; + } + + // Set the metering rectangle + if (x == null || y == null) { + cameraRegions.resetAutoFocusMeteringRectangle(); + } else { + cameraRegions.setAutoFocusMeteringRectangleFromPoint(x, y); + } + + // Apply the new metering rectangle + setFocusMode(result, focusMode); + } + @TargetApi(VERSION_CODES.P) private boolean supportsDistortionCorrection() throws CameraAccessException { int[] availableDistortionCorrectionModes = @@ -832,6 +888,14 @@ private boolean isExposurePointSupported() throws CameraAccessException { return supportedRegions != null && supportedRegions > 0; } + private boolean isFocusPointSupported() throws CameraAccessException { + Integer supportedRegions = + cameraManager + .getCameraCharacteristics(cameraDevice.getId()) + .get(CameraCharacteristics.CONTROL_MAX_REGIONS_AF); + return supportedRegions != null && supportedRegions > 0; + } + public double getMinExposureOffset() throws CameraAccessException { Range range = cameraManager @@ -912,7 +976,7 @@ private void updateFpsRange() { captureRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange); } - private void updateAutoFocus() { + private void updateFocus(FocusMode mode) { if (useAutoFocus) { int[] modes = cameraCharacteristics.get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES); // Auto focus is not supported @@ -923,8 +987,25 @@ private void updateAutoFocus() { captureRequestBuilder.set( CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF); } else { + // Applying auto focus + switch (mode) { + case locked: + captureRequestBuilder.set( + CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO); + break; + case auto: + captureRequestBuilder.set( + CaptureRequest.CONTROL_AF_MODE, + recordingVideo + ? CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO + : CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); + default: + break; + } + MeteringRectangle afRect = cameraRegions.getAFMeteringRectangle(); captureRequestBuilder.set( - CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); + CaptureRequest.CONTROL_AF_REGIONS, + afRect == null ? null : new MeteringRectangle[] {afRect}); } } else { captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF); diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPermissions.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPermissions.java index b4569d2fec07..3529e69a2b0b 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPermissions.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPermissions.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera; import android.Manifest; diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegions.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegions.java index 2285f67ad25c..04412a56631f 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegions.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegions.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera; import android.hardware.camera2.params.MeteringRectangle; @@ -5,6 +9,7 @@ public final class CameraRegions { private MeteringRectangle aeMeteringRectangle; + private MeteringRectangle afMeteringRectangle; private Size maxBoundaries; public CameraRegions(Size maxBoundaries) { @@ -17,6 +22,10 @@ public MeteringRectangle getAEMeteringRectangle() { return aeMeteringRectangle; } + public MeteringRectangle getAFMeteringRectangle() { + return afMeteringRectangle; + } + public Size getMaxBoundaries() { return this.maxBoundaries; } @@ -29,6 +38,14 @@ public void setAutoExposureMeteringRectangleFromPoint(double x, double y) { this.aeMeteringRectangle = getMeteringRectangleForPoint(maxBoundaries, x, y); } + public void resetAutoFocusMeteringRectangle() { + this.afMeteringRectangle = null; + } + + public void setAutoFocusMeteringRectangleFromPoint(double x, double y) { + this.afMeteringRectangle = getMeteringRectangleForPoint(maxBoundaries, x, y); + } + public MeteringRectangle getMeteringRectangleForPoint(Size maxBoundaries, double x, double y) { assert (x >= 0 && x <= 1); assert (y >= 0 && y <= 1); diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java index 3b665d6b24f2..6f04dc80e102 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera; import android.app.Activity; diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraZoom.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraZoom.java index a179f12db224..5eed9f4734b7 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraZoom.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraZoom.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera; import android.graphics.Rect; diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java index 2fee13816b51..ec68ac0acda3 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera; import android.text.TextUtils; @@ -5,6 +9,7 @@ import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugins.camera.types.ExposureMode; +import io.flutter.plugins.camera.types.FocusMode; import java.util.HashMap; import java.util.Map; @@ -25,11 +30,15 @@ void sendCameraInitializedEvent( Integer previewWidth, Integer previewHeight, ExposureMode exposureMode, - Boolean exposurePointSupported) { + FocusMode focusMode, + Boolean exposurePointSupported, + Boolean focusPointSupported) { assert (previewWidth != null); assert (previewHeight != null); assert (exposureMode != null); + assert (focusMode != null); assert (exposurePointSupported != null); + assert (focusPointSupported != null); this.send( EventType.INITIALIZED, new HashMap() { @@ -37,7 +46,9 @@ void sendCameraInitializedEvent( put("previewWidth", previewWidth.doubleValue()); put("previewHeight", previewHeight.doubleValue()); put("exposureMode", exposureMode.toString()); + put("focusMode", focusMode.toString()); put("exposurePointSupported", exposurePointSupported); + put("focusPointSupported", focusPointSupported); } }); } diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java index 95c0b198e43d..36048dbb5176 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera; import android.app.Activity; @@ -12,6 +16,7 @@ import io.flutter.plugins.camera.CameraPermissions.PermissionsRegistry; import io.flutter.plugins.camera.types.ExposureMode; import io.flutter.plugins.camera.types.FlashMode; +import io.flutter.plugins.camera.types.FocusMode; import io.flutter.view.TextureRegistry; import java.util.HashMap; import java.util.Map; @@ -206,6 +211,37 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) } break; } + case "setFocusMode": + { + String modeStr = call.argument("mode"); + FocusMode mode = FocusMode.getValueForString(modeStr); + if (mode == null) { + result.error("setFocusModeFailed", "Unknown focus mode " + modeStr, null); + return; + } + try { + camera.setFocusMode(result, mode); + } catch (Exception e) { + handleException(e, result); + } + break; + } + case "setFocusPoint": + { + Boolean reset = call.argument("reset"); + Double x = null; + Double y = null; + if (reset == null || !reset) { + x = call.argument("x"); + y = call.argument("y"); + } + try { + camera.setFocusPoint(result, x, y); + } catch (Exception e) { + handleException(e, result); + } + break; + } case "startImageStream": { try { diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java index 1103b8583ad6..189f2f1490dc 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera; import androidx.annotation.Nullable; diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/media/MediaRecorderBuilder.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/media/MediaRecorderBuilder.java index b2309c83a4a5..4c3fb3add230 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/media/MediaRecorderBuilder.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/media/MediaRecorderBuilder.java @@ -1,6 +1,7 @@ // Copyright 2019 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. + package io.flutter.plugins.camera.media; import android.media.CamcorderProfile; diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ExposureMode.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ExposureMode.java index 8066f59d2b14..595206fa2216 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ExposureMode.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ExposureMode.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera.types; // Mirrors exposure_mode.dart diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java index ee6fe489511f..c4f0998c418a 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera.types; // Mirrors flash_mode.dart diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FocusMode.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FocusMode.java new file mode 100644 index 000000000000..b0dba047f7eb --- /dev/null +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FocusMode.java @@ -0,0 +1,29 @@ +// Copyright 2019 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. + +package io.flutter.plugins.camera.types; + +// Mirrors focus_mode.dart +public enum FocusMode { + auto("auto"), + locked("locked"); + + private final String strValue; + + FocusMode(String strValue) { + this.strValue = strValue; + } + + public static FocusMode getValueForString(String modeStr) { + for (FocusMode value : values()) { + if (value.strValue.equals(modeStr)) return value; + } + return null; + } + + @Override + public String toString() { + return strValue; + } +} diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ResolutionPreset.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ResolutionPreset.java index ffbe2e62095d..1508dcefb293 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ResolutionPreset.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ResolutionPreset.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera.types; // Mirrors camera.dart diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraPermissionsTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraPermissionsTest.java index b622c313258a..2b19b5dbb0d6 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraPermissionsTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraPermissionsTest.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera; import static junit.framework.TestCase.assertEquals; diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionsTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionsTest.java index ca66918e2493..99745e56a857 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionsTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionsTest.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera; import static org.junit.Assert.assertEquals; @@ -85,6 +89,7 @@ public void constructor_should_initialize() { CameraRegions cr = new CameraRegions(new Size(100, 50)); assertEquals(new Size(100, 50), cr.getMaxBoundaries()); assertNull(cr.getAEMeteringRectangle()); + assertNull(cr.getAFMeteringRectangle()); } @Test @@ -102,4 +107,20 @@ public void resetAutoExposureMeteringRectangle_should_reset_aeMeteringRectangle( cr.resetAutoExposureMeteringRectangle(); assertNull(cr.getAEMeteringRectangle()); } + + @Test + public void setAutoFocusMeteringRectangleFromPoint_should_set_afMeteringRectangle_for_point() { + CameraRegions cr = new CameraRegions(new Size(100, 50)); + cr.setAutoFocusMeteringRectangleFromPoint(0, 0); + assertEquals(new MeteringRectangle(0, 0, 10, 5, 1), cr.getAFMeteringRectangle()); + } + + @Test + public void resetAutoFocusMeteringRectangle_should_reset_afMeteringRectangle() { + CameraRegions cr = new CameraRegions(new Size(100, 50)); + cr.setAutoFocusMeteringRectangleFromPoint(0, 0); + assertNotNull(cr.getAFMeteringRectangle()); + cr.resetAutoFocusMeteringRectangle(); + assertNull(cr.getAFMeteringRectangle()); + } } diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraZoomTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraZoomTest.java index 93aaa5d926b4..8f05da71b5c5 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraZoomTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraZoomTest.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera; import static org.junit.Assert.assertEquals; diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java index f91bf82c7063..64425b7b8283 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera; import static junit.framework.TestCase.assertNull; @@ -8,6 +12,7 @@ import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.StandardMethodCodec; import io.flutter.plugins.camera.types.ExposureMode; +import io.flutter.plugins.camera.types.FocusMode; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; @@ -59,7 +64,7 @@ public void sendCameraErrorEvent_includesErrorDescriptions() { @Test public void sendCameraInitializedEvent_includesPreviewSize() { - dartMessenger.sendCameraInitializedEvent(0, 0, ExposureMode.auto, true); + dartMessenger.sendCameraInitializedEvent(0, 0, ExposureMode.auto, FocusMode.auto, true, true); List sentMessages = fakeBinaryMessenger.getMessages(); assertEquals(1, sentMessages.size()); @@ -68,7 +73,9 @@ public void sendCameraInitializedEvent_includesPreviewSize() { assertEquals(0, (double) call.argument("previewWidth"), 0); assertEquals(0, (double) call.argument("previewHeight"), 0); assertEquals("ExposureMode auto", call.argument("exposureMode"), "auto"); + assertEquals("FocusMode continuous", call.argument("focusMode"), "auto"); assertEquals("exposurePointSupported", call.argument("exposurePointSupported"), true); + assertEquals("focusPointSupported", call.argument("focusPointSupported"), true); } @Test diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java index 2356b306c6c4..3ede0b7abe3a 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera; import static org.junit.Assert.assertEquals; diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/media/MediaRecorderBuilderTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/media/MediaRecorderBuilderTest.java index 622b49b660a2..823975803994 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/media/MediaRecorderBuilderTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/media/MediaRecorderBuilderTest.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera.media; import static org.junit.Assert.assertNotNull; diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/ExposureModeTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/ExposureModeTest.java index 28d2343cedcd..63810f0b5684 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/ExposureModeTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/ExposureModeTest.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera.types; import static org.junit.Assert.assertEquals; diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java index bba01836545a..1f5f0c6272ed 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.camera.types; import static org.junit.Assert.assertEquals; diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FocusModeTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FocusModeTest.java new file mode 100644 index 000000000000..4aa6fadf776b --- /dev/null +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FocusModeTest.java @@ -0,0 +1,34 @@ +// Copyright 2019 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. + +package io.flutter.plugins.camera.types; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class FocusModeTest { + + @Test + public void getValueForString_returns_correct_values() { + assertEquals( + "Returns FocusMode.auto for 'auto'", FocusMode.getValueForString("auto"), FocusMode.auto); + assertEquals( + "Returns FocusMode.locked for 'locked'", + FocusMode.getValueForString("locked"), + FocusMode.locked); + } + + @Test + public void getValueForString_returns_null_for_nonexistant_value() { + assertEquals( + "Returns null for 'nonexistant'", FocusMode.getValueForString("nonexistant"), null); + } + + @Test + public void toString_returns_correct_value() { + assertEquals("Returns 'auto' for FocusMode.auto", FocusMode.auto.toString(), "auto"); + assertEquals("Returns 'locked' for FocusMode.locked", FocusMode.locked.toString(), "locked"); + } +} diff --git a/packages/camera/camera/example/lib/main.dart b/packages/camera/camera/example/lib/main.dart index 6eaf66a256de..681a45172816 100644 --- a/packages/camera/camera/example/lib/main.dart +++ b/packages/camera/camera/example/lib/main.dart @@ -49,6 +49,8 @@ class _CameraExampleHomeState extends State Animation _flashModeControlRowAnimation; AnimationController _exposureModeControlRowAnimationController; Animation _exposureModeControlRowAnimation; + AnimationController _focusModeControlRowAnimationController; + Animation _focusModeControlRowAnimation; double _minAvailableZoom; double _maxAvailableZoom; double _currentScale = 1.0; @@ -77,6 +79,14 @@ class _CameraExampleHomeState extends State parent: _exposureModeControlRowAnimationController, curve: Curves.easeInCubic, ); + _focusModeControlRowAnimationController = AnimationController( + duration: const Duration(milliseconds: 300), + vsync: this, + ); + _focusModeControlRowAnimation = CurvedAnimation( + parent: _focusModeControlRowAnimationController, + curve: Curves.easeInCubic, + ); } @override @@ -249,6 +259,11 @@ class _CameraExampleHomeState extends State onPressed: controller != null ? onExposureModeButtonPressed : null, ), + IconButton( + icon: Icon(Icons.filter_center_focus), + color: Colors.blue, + onPressed: controller != null ? onFocusModeButtonPressed : null, + ), IconButton( icon: Icon(enableAudio ? Icons.volume_up : Icons.volume_mute), color: Colors.blue, @@ -258,6 +273,7 @@ class _CameraExampleHomeState extends State ), _flashModeControlRowWidget(), _exposureModeControlRowWidget(), + _focusModeControlRowWidget(), ], ); } @@ -323,6 +339,7 @@ class _CameraExampleHomeState extends State ? Colors.orange : Colors.blue, ); + return SizeTransition( sizeFactor: _exposureModeControlRowAnimation, child: ClipRect( @@ -387,6 +404,59 @@ class _CameraExampleHomeState extends State ); } + Widget _focusModeControlRowWidget() { + final ButtonStyle styleAuto = TextButton.styleFrom( + primary: controller?.value?.focusMode == FocusMode.auto + ? Colors.orange + : Colors.blue, + ); + final ButtonStyle styleLocked = TextButton.styleFrom( + primary: controller?.value?.focusMode == FocusMode.locked + ? Colors.orange + : Colors.blue, + ); + + return SizeTransition( + sizeFactor: _focusModeControlRowAnimation, + child: ClipRect( + child: Container( + color: Colors.grey.shade50, + child: Column( + children: [ + Center( + child: Text("Focus Mode"), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisSize: MainAxisSize.max, + children: [ + TextButton( + child: Text('AUTO'), + style: styleAuto, + onPressed: controller != null + ? () => onSetFocusModeButtonPressed(FocusMode.auto) + : null, + onLongPress: () { + if (controller != null) controller.setFocusPoint(null); + showInSnackBar('Resetting focus point'); + }, + ), + TextButton( + child: Text('LOCKED'), + style: styleLocked, + onPressed: controller != null + ? () => onSetFocusModeButtonPressed(FocusMode.locked) + : null, + ), + ], + ), + ], + ), + ), + ), + ); + } + /// Display the control bar with buttons to take pictures and record videos. Widget _captureControlRowWidget() { return Row( @@ -472,10 +542,12 @@ class _CameraExampleHomeState extends State } void onViewFinderTap(TapDownDetails details, BoxConstraints constraints) { - controller.setExposurePoint(Offset( + final offset = Offset( details.localPosition.dx / constraints.maxWidth, details.localPosition.dy / constraints.maxHeight, - )); + ); + controller.setExposurePoint(offset); + controller.setFocusPoint(offset); } void onNewCameraSelected(CameraDescription cameraDescription) async { @@ -531,6 +603,7 @@ class _CameraExampleHomeState extends State } else { _flashModeControlRowAnimationController.forward(); _exposureModeControlRowAnimationController.reverse(); + _focusModeControlRowAnimationController.reverse(); } } @@ -540,6 +613,17 @@ class _CameraExampleHomeState extends State } else { _exposureModeControlRowAnimationController.forward(); _flashModeControlRowAnimationController.reverse(); + _focusModeControlRowAnimationController.reverse(); + } + } + + void onFocusModeButtonPressed() { + if (_focusModeControlRowAnimationController.value == 1) { + _focusModeControlRowAnimationController.reverse(); + } else { + _focusModeControlRowAnimationController.forward(); + _flashModeControlRowAnimationController.reverse(); + _exposureModeControlRowAnimationController.reverse(); } } @@ -564,6 +648,13 @@ class _CameraExampleHomeState extends State }); } + void onSetFocusModeButtonPressed(FocusMode mode) { + setFocusMode(mode).then((_) { + if (mounted) setState(() {}); + showInSnackBar('Focus mode set to ${mode.toString().split('.').last}'); + }); + } + void onVideoRecordButtonPressed() { startVideoRecording().then((_) { if (mounted) setState(() {}); @@ -683,6 +774,15 @@ class _CameraExampleHomeState extends State } } + Future setFocusMode(FocusMode mode) async { + try { + await controller.setFocusMode(mode); + } on CameraException catch (e) { + _showCameraException(e); + rethrow; + } + } + Future _startVideoPlayer() async { final VideoPlayerController vController = VideoPlayerController.file(File(videoFile.path)); diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index d1ef0e5c923e..298b906ace7b 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -226,6 +226,44 @@ static ExposureMode getExposureModeForString(NSString *mode) { } } +// Mirrors FocusMode in camera.dart +typedef enum { + FocusModeAuto, + FocusModeLocked, +} FocusMode; + +static NSString *getStringForFocusMode(FocusMode mode) { + switch (mode) { + case FocusModeAuto: + return @"auto"; + case FocusModeLocked: + return @"locked"; + } + NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain + code:NSURLErrorUnknown + userInfo:@{ + NSLocalizedDescriptionKey : [NSString + stringWithFormat:@"Unknown string for focus mode"] + }]; + @throw error; +} + +static FocusMode getFocusModeForString(NSString *mode) { + if ([mode isEqualToString:@"auto"]) { + return FocusModeAuto; + } else if ([mode isEqualToString:@"locked"]) { + return FocusModeLocked; + } else { + NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain + code:NSURLErrorUnknown + userInfo:@{ + NSLocalizedDescriptionKey : [NSString + stringWithFormat:@"Unknown focus mode %@", mode] + }]; + @throw error; + } +} + // Mirrors ResolutionPreset in camera.dart typedef enum { veryLow, @@ -294,6 +332,7 @@ @interface FLTCam : NSObject { )), exposureMode: await _initializeCompleter.future .then((event) => event.exposureMode), + focusMode: + await _initializeCompleter.future.then((event) => event.focusMode), exposurePointSupported: await _initializeCompleter.future .then((event) => event.exposurePointSupported), + focusPointSupported: await _initializeCompleter.future + .then((event) => event.focusPointSupported), ); } on PlatformException catch (e) { throw CameraException(e.code, e.message); @@ -699,6 +718,38 @@ class CameraController extends ValueNotifier { } } + /// Sets the focus mode for taking pictures. + Future setFocusMode(FocusMode mode) async { + try { + await CameraPlatform.instance.setFocusMode(_cameraId, mode); + value = value.copyWith(focusMode: mode); + } on PlatformException catch (e) { + throw CameraException(e.code, e.message); + } + } + + /// Sets the focus point for automatically determining the focus value. + Future setFocusPoint(Offset point) async { + if (point != null && + (point.dx < 0 || point.dx > 1 || point.dy < 0 || point.dy > 1)) { + throw ArgumentError( + 'The values of point should be anywhere between (0,0) and (1,1).'); + } + try { + await CameraPlatform.instance.setFocusPoint( + _cameraId, + point == null + ? null + : Point( + point.dx, + point.dy, + ), + ); + } on PlatformException catch (e) { + throw CameraException(e.code, e.message); + } + } + /// Releases the resources of this camera. @override Future dispose() async { diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 7c275c2268cd..0b21497b5462 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,13 +2,13 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.6.5 +version: 0.6.6 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: flutter: sdk: flutter - camera_platform_interface: ^1.3.0 + camera_platform_interface: ^1.5.0 pedantic: ^1.8.0 dev_dependencies: diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index 4f2109371392..1cea609d1741 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -28,8 +28,15 @@ get mockAvailableCameras => [ get mockInitializeCamera => 13; -get mockOnCameraInitializedEvent => - CameraInitializedEvent(13, 75, 75, ExposureMode.auto, true); +get mockOnCameraInitializedEvent => CameraInitializedEvent( + 13, + 75, + 75, + ExposureMode.auto, + true, + FocusMode.auto, + true, + ); get mockOnCameraClosingEvent => null; diff --git a/packages/camera/camera/test/camera_value_test.dart b/packages/camera/camera/test/camera_value_test.dart index d9193e212ea9..eb7927b9eb6c 100644 --- a/packages/camera/camera/test/camera_value_test.dart +++ b/packages/camera/camera/test/camera_value_test.dart @@ -106,11 +106,14 @@ void main() { isTakingPicture: false, isStreamingImages: false, flashMode: FlashMode.auto, + exposureMode: ExposureMode.auto, + focusMode: FocusMode.auto, exposurePointSupported: true, + focusPointSupported: true, ); expect(cameraValue.toString(), - 'CameraValue(isRecordingVideo: false, isInitialized: false, errorDescription: null, previewSize: Size(10.0, 10.0), isStreamingImages: false, flashMode: FlashMode.auto, exposureMode: null, exposurePointSupported: true)'); + 'CameraValue(isRecordingVideo: false, isInitialized: false, errorDescription: null, previewSize: Size(10.0, 10.0), isStreamingImages: false, flashMode: FlashMode.auto, exposureMode: ExposureMode.auto, focusMode: FocusMode.auto, exposurePointSupported: true, focusPointSupported: true)'); }); }); } From a0e793734eac4eeb566ce090c64ed928e72214b2 Mon Sep 17 00:00:00 2001 From: Aleksandr Yurkovskiy Date: Tue, 12 Jan 2021 21:39:02 +0300 Subject: [PATCH 0030/1565] [google_maps_flutter_platform_interface] Adds support for holes in polygon overlays to the Google Maps plugin (#3135) --- AUTHORS | 1 + .../CHANGELOG.md | 4 +++ .../lib/src/types/polygon.dart | 29 +++++++++++++++++++ .../pubspec.yaml | 3 +- 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 51345c9a3481..09bab9d34d02 100644 --- a/AUTHORS +++ b/AUTHORS @@ -59,3 +59,4 @@ Kazuki Yamaguchi Eitan Schwartz Chris Rutkowski Juan Alvarez +Aleksandr Yurkovskiy diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md index b40fc9d40e5b..1e761681e543 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.0 + +* Add support for holes in Polygons. + ## 1.0.6 * Update Flutter SDK constraint. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart index 3b5e25060faf..96b39157418d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart' show listEquals, VoidCallback; import 'package:flutter/material.dart' show Color, Colors; import 'package:meta/meta.dart' show immutable, required; @@ -46,6 +47,7 @@ class Polygon { this.fillColor = Colors.black, this.geodesic = false, this.points = const [], + this.holes = const >[], this.strokeColor = Colors.black, this.strokeWidth = 10, this.visible = true, @@ -77,6 +79,14 @@ class Polygon { /// default; to form a closed polygon, the start and end points must be the same. final List points; + /// To create an empty area within a polygon, you need to use holes. + /// To create the hole, the coordinates defining the hole path must be inside the polygon. + /// + /// The vertices of the holes to be cut out of polygon. + /// + /// Line segments of each points of hole are drawn inside polygon between consecutive hole points. + final List> holes; + /// True if the marker is visible. final bool visible; @@ -106,6 +116,7 @@ class Polygon { Color fillColorParam, bool geodesicParam, List pointsParam, + List> holesParam, Color strokeColorParam, int strokeWidthParam, bool visibleParam, @@ -118,6 +129,7 @@ class Polygon { fillColor: fillColorParam ?? fillColor, geodesic: geodesicParam ?? geodesic, points: pointsParam ?? points, + holes: holesParam ?? holes, strokeColor: strokeColorParam ?? strokeColor, strokeWidth: strokeWidthParam ?? strokeWidth, visible: visibleParam ?? visible, @@ -154,6 +166,10 @@ class Polygon { json['points'] = _pointsToJson(); } + if (holes != null) { + json['holes'] = _holesToJson(); + } + return json; } @@ -167,6 +183,7 @@ class Polygon { fillColor == typedOther.fillColor && geodesic == typedOther.geodesic && listEquals(points, typedOther.points) && + DeepCollectionEquality().equals(holes, typedOther.holes) && visible == typedOther.visible && strokeColor == typedOther.strokeColor && strokeWidth == typedOther.strokeWidth && @@ -183,4 +200,16 @@ class Polygon { } return result; } + + List> _holesToJson() { + final List> result = >[]; + for (final List hole in holes) { + final List jsonHole = []; + for (final LatLng point in hole) { + jsonHole.add(point.toJson()); + } + result.add(jsonHole); + } + return result; + } } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml index 633478c5d636..d8b260a7a3eb 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the google_maps_flutter plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.0.6 +version: 1.1.0 dependencies: flutter: @@ -11,6 +11,7 @@ dependencies: meta: ^1.0.5 plugin_platform_interface: ^1.0.1 stream_transform: ^1.2.0 + collection: ^1.14.13 dev_dependencies: flutter_test: From 782a7a9c95c81724eaed543a4aa99947b8b83ea5 Mon Sep 17 00:00:00 2001 From: Kate Lovett Date: Wed, 13 Jan 2021 11:50:34 -0600 Subject: [PATCH 0031/1565] [video_player] Migrate deprecated api (#3409) --- .../video_player/video_player/CHANGELOG.md | 4 + .../video_player/video_player/pubspec.yaml | 2 +- .../video_player/test/video_player_test.dart | 6 +- .../method_channel_video_player_test.dart | 123 ++++++++---------- 4 files changed, 58 insertions(+), 77 deletions(-) diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index f9bae8dee6e1..3e8047ced6bc 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.8 + +* Migrated from deprecated `defaultBinaryMessenger`. + ## 2.0.0-nullsafety.7 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index e4694195ebde..72fb54b125ea 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -4,7 +4,7 @@ description: Flutter plugin for displaying inline video with other Flutter # 0.10.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 2.0.0-nullsafety.7 +version: 2.0.0-nullsafety.8 homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player flutter: diff --git a/packages/video_player/video_player/test/video_player_test.dart b/packages/video_player/video_player/test/video_player_test.dart index f3f2b5e8faf1..eb276a8d72e7 100644 --- a/packages/video_player/video_player/test/video_player_test.dart +++ b/packages/video_player/video_player/test/video_player_test.dart @@ -795,11 +795,7 @@ class FakeEventsChannel { } void _sendMessage(ByteData data) { - // TODO(jackson): This has been deprecated and should be replaced - // with `ServicesBinding.instance.defaultBinaryMessenger` when it's - // available on all the versions of Flutter that we test. - // ignore: deprecated_member_use - defaultBinaryMessenger.handlePlatformMessage( + ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage( eventsMethodChannel.name, data, (ByteData? data) {}); } } diff --git a/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart b/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart index 5c19ebca0d12..7f54c4f24f2c 100644 --- a/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart +++ b/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart @@ -234,82 +234,63 @@ void main() { }); test('videoEventsFor', () async { - // TODO(cbenhagen): This has been deprecated and should be replaced - // with `ServicesBinding.instance.defaultBinaryMessenger` when it's - // available on all the versions of Flutter that we test. - // ignore: deprecated_member_use - defaultBinaryMessenger.setMockMessageHandler( + ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler( "flutter.io/videoPlayer/videoEvents123", (ByteData message) async { final MethodCall methodCall = const StandardMethodCodec().decodeMethodCall(message); if (methodCall.method == 'listen') { - // TODO(cbenhagen): This has been deprecated and should be replaced - // with `ServicesBinding.instance.defaultBinaryMessenger` when it's - // available on all the versions of Flutter that we test. - // ignore: deprecated_member_use - await defaultBinaryMessenger.handlePlatformMessage( - "flutter.io/videoPlayer/videoEvents123", - const StandardMethodCodec() - .encodeSuccessEnvelope({ - 'event': 'initialized', - 'duration': 98765, - 'width': 1920, - 'height': 1080, - }), - (ByteData data) {}); - - // TODO(cbenhagen): This has been deprecated and should be replaced - // with `ServicesBinding.instance.defaultBinaryMessenger` when it's - // available on all the versions of Flutter that we test. - // ignore: deprecated_member_use - await defaultBinaryMessenger.handlePlatformMessage( - "flutter.io/videoPlayer/videoEvents123", - const StandardMethodCodec() - .encodeSuccessEnvelope({ - 'event': 'completed', - }), - (ByteData data) {}); - - // TODO(cbenhagen): This has been deprecated and should be replaced - // with `ServicesBinding.instance.defaultBinaryMessenger` when it's - // available on all the versions of Flutter that we test. - // ignore: deprecated_member_use - await defaultBinaryMessenger.handlePlatformMessage( - "flutter.io/videoPlayer/videoEvents123", - const StandardMethodCodec() - .encodeSuccessEnvelope({ - 'event': 'bufferingUpdate', - 'values': >[ - [0, 1234], - [1235, 4000], - ], - }), - (ByteData data) {}); - - // TODO(cbenhagen): This has been deprecated and should be replaced - // with `ServicesBinding.instance.defaultBinaryMessenger` when it's - // available on all the versions of Flutter that we test. - // ignore: deprecated_member_use - await defaultBinaryMessenger.handlePlatformMessage( - "flutter.io/videoPlayer/videoEvents123", - const StandardMethodCodec() - .encodeSuccessEnvelope({ - 'event': 'bufferingStart', - }), - (ByteData data) {}); - - // TODO(cbenhagen): This has been deprecated and should be replaced - // with `ServicesBinding.instance.defaultBinaryMessenger` when it's - // available on all the versions of Flutter that we test. - // ignore: deprecated_member_use - await defaultBinaryMessenger.handlePlatformMessage( - "flutter.io/videoPlayer/videoEvents123", - const StandardMethodCodec() - .encodeSuccessEnvelope({ - 'event': 'bufferingEnd', - }), - (ByteData data) {}); + await ServicesBinding.instance.defaultBinaryMessenger + .handlePlatformMessage( + "flutter.io/videoPlayer/videoEvents123", + const StandardMethodCodec() + .encodeSuccessEnvelope({ + 'event': 'initialized', + 'duration': 98765, + 'width': 1920, + 'height': 1080, + }), + (ByteData data) {}); + + await ServicesBinding.instance.defaultBinaryMessenger + .handlePlatformMessage( + "flutter.io/videoPlayer/videoEvents123", + const StandardMethodCodec() + .encodeSuccessEnvelope({ + 'event': 'completed', + }), + (ByteData data) {}); + + await ServicesBinding.instance.defaultBinaryMessenger + .handlePlatformMessage( + "flutter.io/videoPlayer/videoEvents123", + const StandardMethodCodec() + .encodeSuccessEnvelope({ + 'event': 'bufferingUpdate', + 'values': >[ + [0, 1234], + [1235, 4000], + ], + }), + (ByteData data) {}); + + await ServicesBinding.instance.defaultBinaryMessenger + .handlePlatformMessage( + "flutter.io/videoPlayer/videoEvents123", + const StandardMethodCodec() + .encodeSuccessEnvelope({ + 'event': 'bufferingStart', + }), + (ByteData data) {}); + + await ServicesBinding.instance.defaultBinaryMessenger + .handlePlatformMessage( + "flutter.io/videoPlayer/videoEvents123", + const StandardMethodCodec() + .encodeSuccessEnvelope({ + 'event': 'bufferingEnd', + }), + (ByteData data) {}); return const StandardMethodCodec().encodeSuccessEnvelope(null); } else if (methodCall.method == 'cancel') { From 4fec227387314d86fd1acbdb056802e57675a463 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Wed, 13 Jan 2021 13:03:38 -0500 Subject: [PATCH 0032/1565] [battery] Migrate battery to null safety (#3380) --- packages/battery/battery/CHANGELOG.md | 4 ++++ packages/battery/battery/example/lib/main.dart | 8 ++++---- packages/battery/battery/example/pubspec.yaml | 4 ++-- .../battery/integration_test/battery_test.dart | 2 ++ packages/battery/battery/pubspec.yaml | 16 +++++++--------- packages/battery/battery/test/battery_test.dart | 4 ++-- 6 files changed, 21 insertions(+), 17 deletions(-) diff --git a/packages/battery/battery/CHANGELOG.md b/packages/battery/battery/CHANGELOG.md index ca35c96fb569..d907ca33fe1e 100644 --- a/packages/battery/battery/CHANGELOG.md +++ b/packages/battery/battery/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Migrate to null safety. + ## 1.0.11 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. diff --git a/packages/battery/battery/example/lib/main.dart b/packages/battery/battery/example/lib/main.dart index c84f5eec519b..8482655771f2 100644 --- a/packages/battery/battery/example/lib/main.dart +++ b/packages/battery/battery/example/lib/main.dart @@ -27,7 +27,7 @@ class MyApp extends StatelessWidget { } class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); + MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @@ -36,10 +36,10 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { - Battery _battery = Battery(); + final Battery _battery = Battery(); - BatteryState _batteryState; - StreamSubscription _batteryStateSubscription; + BatteryState? _batteryState; + late StreamSubscription _batteryStateSubscription; @override void initState() { diff --git a/packages/battery/battery/example/pubspec.yaml b/packages/battery/battery/example/pubspec.yaml index 4e7b9ef035eb..748660adf284 100644 --- a/packages/battery/battery/example/pubspec.yaml +++ b/packages/battery/battery/example/pubspec.yaml @@ -12,11 +12,11 @@ dev_dependencies: sdk: flutter integration_test: path: ../../../integration_test - pedantic: ^1.8.0 + pedantic: ^1.10.0-nullsafety 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/battery/battery/integration_test/battery_test.dart b/packages/battery/battery/integration_test/battery_test.dart index ed7b6fe5a0e4..2b0e26967b6c 100644 --- a/packages/battery/battery/integration_test/battery_test.dart +++ b/packages/battery/battery/integration_test/battery_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:battery/battery.dart'; import 'package:integration_test/integration_test.dart'; diff --git a/packages/battery/battery/pubspec.yaml b/packages/battery/battery/pubspec.yaml index 9c2c2766c85f..455905d62a9a 100644 --- a/packages/battery/battery/pubspec.yaml +++ b/packages/battery/battery/pubspec.yaml @@ -2,7 +2,7 @@ name: battery description: Flutter plugin for accessing information about the battery state (full, charging, discharging) on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/battery/battery -version: 1.0.11 +version: 2.0.0-nullsafety flutter: plugin: @@ -16,20 +16,18 @@ flutter: dependencies: flutter: sdk: flutter - meta: ^1.0.5 - battery_platform_interface: ^1.0.0 + meta: ^1.3.0-nullsafety + battery_platform_interface: ^2.0.0-nullsafety dev_dependencies: - async: ^2.0.8 - test: ^1.3.0 - mockito: ^4.1.1 + mockito: ^5.0.0-nullsafety.0 flutter_test: sdk: flutter - plugin_platform_interface: ^1.0.0 + plugin_platform_interface: ^1.1.0-nullsafety integration_test: path: ../../integration_test - pedantic: ^1.8.0 + pedantic: ^1.10.0-nullsafety environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/battery/battery/test/battery_test.dart b/packages/battery/battery/test/battery_test.dart index 5c789207d7eb..43155c59692c 100644 --- a/packages/battery/battery/test/battery_test.dart +++ b/packages/battery/battery/test/battery_test.dart @@ -5,14 +5,14 @@ import 'dart:async'; import 'package:battery_platform_interface/battery_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; -import 'package:test/test.dart'; import 'package:battery/battery.dart'; import 'package:mockito/mockito.dart'; void main() { group('battery', () { - Battery battery; + late Battery battery; MockBatteryPlatform fakePlatform; setUp(() async { fakePlatform = MockBatteryPlatform(); From 1eabad7de3ab62eb1d38bdc86e61cdaa4fe0dfa1 Mon Sep 17 00:00:00 2001 From: Juanjo Tugores Date: Wed, 13 Jan 2021 13:15:13 -0600 Subject: [PATCH 0033/1565] [file_selector_web] Add initial implementation (#3141) Add the file_selector web implementation --- .../file_selector_web/CHANGELOG.md | 3 + .../file_selector/file_selector_web/LICENSE | 25 ++++ .../file_selector/file_selector_web/README.md | 30 +++++ .../integration_test/dom_helper_test.dart | 116 ++++++++++++++++++ .../file_selector_web_test.dart | 89 ++++++++++++++ .../lib/file_selector_web.dart | 74 +++++++++++ .../file_selector_web/lib/src/dom_helper.dart | 63 ++++++++++ .../file_selector_web/lib/src/utils.dart | 38 ++++++ .../file_selector_web/pubspec.yaml | 32 +++++ .../file_selector_web/run_integration_test | 17 +++ .../file_selector_web/test/utils_test.dart | 59 +++++++++ .../test_driver/integration_test.dart | 7 ++ 12 files changed, 553 insertions(+) create mode 100644 packages/file_selector/file_selector_web/CHANGELOG.md create mode 100644 packages/file_selector/file_selector_web/LICENSE create mode 100644 packages/file_selector/file_selector_web/README.md create mode 100644 packages/file_selector/file_selector_web/integration_test/dom_helper_test.dart create mode 100644 packages/file_selector/file_selector_web/integration_test/file_selector_web_test.dart create mode 100644 packages/file_selector/file_selector_web/lib/file_selector_web.dart create mode 100644 packages/file_selector/file_selector_web/lib/src/dom_helper.dart create mode 100644 packages/file_selector/file_selector_web/lib/src/utils.dart create mode 100644 packages/file_selector/file_selector_web/pubspec.yaml create mode 100755 packages/file_selector/file_selector_web/run_integration_test create mode 100644 packages/file_selector/file_selector_web/test/utils_test.dart create mode 100644 packages/file_selector/file_selector_web/test_driver/integration_test.dart diff --git a/packages/file_selector/file_selector_web/CHANGELOG.md b/packages/file_selector/file_selector_web/CHANGELOG.md new file mode 100644 index 000000000000..cf87cfec36fd --- /dev/null +++ b/packages/file_selector/file_selector_web/CHANGELOG.md @@ -0,0 +1,3 @@ +# 0.7.0 + +- Initial open-source release. diff --git a/packages/file_selector/file_selector_web/LICENSE b/packages/file_selector/file_selector_web/LICENSE new file mode 100644 index 000000000000..2c91f1438173 --- /dev/null +++ b/packages/file_selector/file_selector_web/LICENSE @@ -0,0 +1,25 @@ +Copyright 2020 The Flutter Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/packages/file_selector/file_selector_web/README.md b/packages/file_selector/file_selector_web/README.md new file mode 100644 index 000000000000..36e0b446ffe8 --- /dev/null +++ b/packages/file_selector/file_selector_web/README.md @@ -0,0 +1,30 @@ +# file_picker_web + +The web implementation of [`file_picker`][1]. + +## Usage + +### Import the package +To use this plugin in your Flutter Web app, simply add it as a dependency in +your pubspec alongside the base `file_picker` plugin. + +_(This is only temporary: in the future we hope to make this package an +"endorsed" implementation of `file_picker`, so that it is automatically +included in your Flutter Web app when you depend on `package:file_picker`.)_ + +This is what the above means to your `pubspec.yaml`: + +```yaml +... +dependencies: + ... + file_picker: ^0.7.0 + file_picker_web: ^0.7.0 + ... +``` + +### Use the plugin +Once you have the `file_picker_web` dependency in your pubspec, you should +be able to use `package:file_picker` as normal. + +[1]: ../file_picker/file_picker diff --git a/packages/file_selector/file_selector_web/integration_test/dom_helper_test.dart b/packages/file_selector/file_selector_web/integration_test/dom_helper_test.dart new file mode 100644 index 000000000000..a942c0db10bf --- /dev/null +++ b/packages/file_selector/file_selector_web/integration_test/dom_helper_test.dart @@ -0,0 +1,116 @@ +// 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. + +// @dart = 2.9 + +import 'dart:html'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; +import 'package:file_selector_web/src/dom_helper.dart'; +import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; + +void main() { + group('FileSelectorWeb', () { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + DomHelper domHelper; + FileUploadInputElement input; + + FileList FileListItems(List files) { + final dataTransfer = DataTransfer(); + files.forEach(dataTransfer.items.add); + return dataTransfer.files; + } + + void setFilesAndTriggerChange(List files) { + input.files = FileListItems(files); + input.dispatchEvent(Event('change')); + } + + setUp(() { + domHelper = DomHelper(); + input = FileUploadInputElement(); + }); + + group('getFiles', () { + final mockFile1 = File(['123456'], 'file1.txt'); + final mockFile2 = File([], 'file2.txt'); + + testWidgets('works', (_) async { + final Future> futureFiles = domHelper.getFiles( + input: input, + ); + + setFilesAndTriggerChange([mockFile1, mockFile2]); + + final List files = await futureFiles; + + expect(files.length, 2); + + expect(files[0].name, 'file1.txt'); + expect(await files[0].length(), 6); + expect(await files[0].readAsString(), '123456'); + expect(await files[0].lastModified(), isNotNull); + + expect(files[1].name, 'file2.txt'); + expect(await files[1].length(), 0); + expect(await files[1].readAsString(), ''); + expect(await files[1].lastModified(), isNotNull); + }); + + testWidgets('works multiple times', (_) async { + Future> futureFiles; + List files; + + // It should work the first time + futureFiles = domHelper.getFiles(input: input); + setFilesAndTriggerChange([mockFile1]); + + files = await futureFiles; + + expect(files.length, 1); + expect(files.first.name, mockFile1.name); + + // The same input should work more than once + futureFiles = domHelper.getFiles(input: input); + setFilesAndTriggerChange([mockFile2]); + + files = await futureFiles; + + expect(files.length, 1); + expect(files.first.name, mockFile2.name); + }); + + testWidgets('sets the attributes and clicks it', (_) async { + final accept = '.jpg,.png'; + final multiple = true; + bool wasClicked = false; + + //ignore: unawaited_futures + input.onClick.first.then((_) => wasClicked = true); + + final futureFile = domHelper.getFiles( + accept: accept, + multiple: multiple, + input: input, + ); + + expect(input.matchesWithAncestors('body'), true); + expect(input.accept, accept); + expect(input.multiple, multiple); + expect( + wasClicked, + true, + reason: + 'The should be clicked otherwise no dialog will be shown', + ); + + setFilesAndTriggerChange([]); + await futureFile; + + // It should be already removed from the DOM after the file is resolved. + expect(input.parent, isNull); + }); + }); + }); +} diff --git a/packages/file_selector/file_selector_web/integration_test/file_selector_web_test.dart b/packages/file_selector/file_selector_web/integration_test/file_selector_web_test.dart new file mode 100644 index 000000000000..abd31dd9fcc6 --- /dev/null +++ b/packages/file_selector/file_selector_web/integration_test/file_selector_web_test.dart @@ -0,0 +1,89 @@ +// 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. + +// @dart = 2.9 + +import 'dart:typed_data'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:integration_test/integration_test.dart'; +import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; +import 'package:file_selector_web/file_selector_web.dart'; +import 'package:file_selector_web/src/dom_helper.dart'; + +void main() { + group('FileSelectorWeb', () { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + MockDomHelper mockDomHelper; + FileSelectorWeb plugin; + + setUp(() { + mockDomHelper = MockDomHelper(); + plugin = FileSelectorWeb(domHelper: mockDomHelper); + }); + + group('openFile', () { + final mockFile = createXFile('1001', 'identity.png'); + + testWidgets('works', (WidgetTester _) async { + final typeGroup = XTypeGroup( + label: 'images', + extensions: ['jpg', 'jpeg'], + mimeTypes: ['image/png'], + webWildCards: ['image/*'], + ); + + when(mockDomHelper.getFiles( + accept: '.jpg,.jpeg,image/png,image/*', + multiple: false, + )).thenAnswer((_) async => [mockFile]); + + final file = await plugin.openFile(acceptedTypeGroups: [typeGroup]); + + expect(file.name, mockFile.name); + expect(await file.length(), 4); + expect(await file.readAsString(), '1001'); + expect(await file.lastModified(), isNotNull); + }); + }); + + group('openFiles', () { + final mockFile1 = createXFile('123456', 'file1.txt'); + final mockFile2 = createXFile('', 'file2.txt'); + + testWidgets('works', (WidgetTester _) async { + final typeGroup = XTypeGroup( + label: 'files', + extensions: ['.txt'], + ); + + when(mockDomHelper.getFiles( + accept: '.txt', + multiple: true, + )).thenAnswer((_) async => [mockFile1, mockFile2]); + + final files = await plugin.openFiles(acceptedTypeGroups: [typeGroup]); + + expect(files.length, 2); + + expect(files[0].name, mockFile1.name); + expect(await files[0].length(), 6); + expect(await files[0].readAsString(), '123456'); + expect(await files[0].lastModified(), isNotNull); + + expect(files[1].name, mockFile2.name); + expect(await files[1].length(), 0); + expect(await files[1].readAsString(), ''); + expect(await files[1].lastModified(), isNotNull); + }); + }); + }); +} + +class MockDomHelper extends Mock implements DomHelper {} + +XFile createXFile(String content, String name) { + final data = Uint8List.fromList(content.codeUnits); + return XFile.fromData(data, name: name, lastModified: DateTime.now()); +} diff --git a/packages/file_selector/file_selector_web/lib/file_selector_web.dart b/packages/file_selector/file_selector_web/lib/file_selector_web.dart new file mode 100644 index 000000000000..48f57ee880c8 --- /dev/null +++ b/packages/file_selector/file_selector_web/lib/file_selector_web.dart @@ -0,0 +1,74 @@ +// 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 'dart:async'; +import 'package:meta/meta.dart'; +import 'package:flutter_web_plugins/flutter_web_plugins.dart'; +import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; +import 'package:file_selector_web/src/dom_helper.dart'; +import 'package:file_selector_web/src/utils.dart'; + +/// The web implementation of [FileSelectorPlatform]. +/// +/// This class implements the `package:file_selector` functionality for the web. +class FileSelectorWeb extends FileSelectorPlatform { + final _domHelper; + + /// Registers this class as the default instance of [FileSelectorPlatform]. + static void registerWith(Registrar registrar) { + FileSelectorPlatform.instance = FileSelectorWeb(); + } + + /// Default constructor, initializes _domHelper that we can use + /// to interact with the DOM. + /// overrides parameter allows for testing to override functions + FileSelectorWeb({@visibleForTesting DomHelper domHelper}) + : _domHelper = domHelper ?? DomHelper(); + + @override + Future openFile({ + List acceptedTypeGroups, + String initialDirectory, + String confirmButtonText, + }) async { + final files = await _openFiles(acceptedTypeGroups: acceptedTypeGroups); + return files.first; + } + + @override + Future> openFiles({ + List acceptedTypeGroups, + String initialDirectory, + String confirmButtonText, + }) async { + return _openFiles(acceptedTypeGroups: acceptedTypeGroups, multiple: true); + } + + @override + Future getSavePath({ + List acceptedTypeGroups, + String initialDirectory, + String suggestedName, + String confirmButtonText, + }) async => + null; + + @override + Future getDirectoryPath({ + String initialDirectory, + String confirmButtonText, + }) async => + null; + + Future> _openFiles({ + List acceptedTypeGroups, + bool multiple = false, + }) async { + final accept = acceptedTypesToString(acceptedTypeGroups); + return _domHelper.getFiles( + accept: accept, + multiple: multiple, + ); + } +} diff --git a/packages/file_selector/file_selector_web/lib/src/dom_helper.dart b/packages/file_selector/file_selector_web/lib/src/dom_helper.dart new file mode 100644 index 000000000000..a965cebe97f9 --- /dev/null +++ b/packages/file_selector/file_selector_web/lib/src/dom_helper.dart @@ -0,0 +1,63 @@ +// 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 'dart:async'; +import 'dart:html'; +import 'package:meta/meta.dart'; +import 'package:flutter/services.dart'; +import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; + +/// Class to manipulate the DOM with the intention of reading files from it. +class DomHelper { + final _container = Element.tag('file-selector'); + + /// Default constructor, initializes the container DOM element. + DomHelper() { + final body = querySelector('body'); + body.children.add(_container); + } + + /// Sets the attributes and waits for a file to be selected. + Future> getFiles({ + String accept = '', + bool multiple = false, + @visibleForTesting FileUploadInputElement input, + }) { + final Completer> _completer = Completer(); + input = input ?? FileUploadInputElement(); + + _container.children.add( + input + ..accept = accept + ..multiple = multiple, + ); + + input.onChange.first.then((_) { + final List files = input.files.map(_convertFileToXFile).toList(); + input.remove(); + _completer.complete(files); + }); + + input.onError.first.then((event) { + final ErrorEvent error = event; + final platformException = PlatformException( + code: error.type, + message: error.message, + ); + input.remove(); + _completer.completeError(platformException); + }); + + input.click(); + + return _completer.future; + } + + XFile _convertFileToXFile(File file) => XFile( + Url.createObjectUrl(file), + name: file.name, + length: file.size, + lastModified: DateTime.fromMillisecondsSinceEpoch(file.lastModified), + ); +} diff --git a/packages/file_selector/file_selector_web/lib/src/utils.dart b/packages/file_selector/file_selector_web/lib/src/utils.dart new file mode 100644 index 000000000000..4ddd7ddcbda5 --- /dev/null +++ b/packages/file_selector/file_selector_web/lib/src/utils.dart @@ -0,0 +1,38 @@ +// 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:file_selector_platform_interface/file_selector_platform_interface.dart'; + +/// Convert list of XTypeGroups to a comma-separated string +String acceptedTypesToString(List acceptedTypes) { + if (acceptedTypes == null) return ''; + final List allTypes = []; + for (final group in acceptedTypes) { + _assertTypeGroupIsValid(group); + if (group.extensions != null) { + allTypes.addAll(group.extensions.map(_normalizeExtension)); + } + if (group.mimeTypes != null) { + allTypes.addAll(group.mimeTypes); + } + if (group.webWildCards != null) { + allTypes.addAll(group.webWildCards); + } + } + return allTypes.join(','); +} + +/// Make sure that at least one of its fields is populated. +void _assertTypeGroupIsValid(XTypeGroup group) { + assert( + !((group.extensions == null || group.extensions.isEmpty) && + (group.mimeTypes == null || group.mimeTypes.isEmpty) && + (group.webWildCards == null || group.webWildCards.isEmpty)), + 'At least one of extensions / mimeTypes / webWildCards is required for web.'); +} + +/// Append a dot at the beggining if it is not there png -> .png +String _normalizeExtension(String ext) { + return ext.isNotEmpty && ext[0] != '.' ? '.' + ext : ext; +} diff --git a/packages/file_selector/file_selector_web/pubspec.yaml b/packages/file_selector/file_selector_web/pubspec.yaml new file mode 100644 index 000000000000..c8e0eef56276 --- /dev/null +++ b/packages/file_selector/file_selector_web/pubspec.yaml @@ -0,0 +1,32 @@ +name: file_selector_web +description: Web platform implementation of file_selector +homepage: https://github.com/flutter/plugins/tree/master/packages/file_selector/file_selector_web +version: 0.7.0 + +flutter: + plugin: + platforms: + web: + pluginClass: FileSelectorWeb + fileName: file_selector_web.dart + +dependencies: + file_selector_platform_interface: ^1.0.2 + platform_detect: ^1.4.0 + flutter: + sdk: flutter + flutter_web_plugins: + sdk: flutter + meta: ^1.1.7 + +dev_dependencies: + flutter_test: + sdk: flutter + mockito: ^4.1.1 + pedantic: ^1.8.0 + integration_test: + path: ../../integration_test + +environment: + sdk: ">=2.2.0 <3.0.0" + flutter: ">=1.10.0" diff --git a/packages/file_selector/file_selector_web/run_integration_test b/packages/file_selector/file_selector_web/run_integration_test new file mode 100755 index 000000000000..c9f547a4f7d7 --- /dev/null +++ b/packages/file_selector/file_selector_web/run_integration_test @@ -0,0 +1,17 @@ +#!/usr/bin/bash + +if pgrep -lf chromedriver > /dev/null; then + echo "chromedriver is running." + + if [ $# -eq 0 ]; then + echo "No target specified, running all tests..." + find integration_test/ -iname *_test.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_test.dart --target='{}' + else + echo "Running test target: $1..." + set -x + flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_test.dart --target=$1 + fi + + else + echo "chromedriver is not running." +fi diff --git a/packages/file_selector/file_selector_web/test/utils_test.dart b/packages/file_selector/file_selector_web/test/utils_test.dart new file mode 100644 index 000000000000..9fa187eede5b --- /dev/null +++ b/packages/file_selector/file_selector_web/test/utils_test.dart @@ -0,0 +1,59 @@ +// 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. + +// @dart = 2.9 + +import 'package:flutter_test/flutter_test.dart'; +import 'package:file_selector_web/src/utils.dart'; +import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; + +void main() { + group('FileSelectorWeb utils', () { + group('acceptedTypesToString', () { + test('works', () { + final List acceptedTypes = [ + XTypeGroup(label: 'images', webWildCards: ['images/*']), + XTypeGroup(label: 'jpgs', extensions: ['jpg', 'jpeg']), + XTypeGroup(label: 'pngs', mimeTypes: ['image/png']), + ]; + final accepts = acceptedTypesToString(acceptedTypes); + expect(accepts, 'images/*,.jpg,.jpeg,image/png'); + }); + + test('works with an empty list', () { + final List acceptedTypes = []; + final accepts = acceptedTypesToString(acceptedTypes); + expect(accepts, ''); + }); + + test('works with extensions', () { + final List acceptedTypes = [ + XTypeGroup(label: 'jpgs', extensions: ['jpeg', 'jpg']), + XTypeGroup(label: 'pngs', extensions: ['png']), + ]; + final accepts = acceptedTypesToString(acceptedTypes); + expect(accepts, '.jpeg,.jpg,.png'); + }); + + test('works with mime types', () { + final List acceptedTypes = [ + XTypeGroup(label: 'jpgs', mimeTypes: ['image/jpeg', 'image/jpg']), + XTypeGroup(label: 'pngs', mimeTypes: ['image/png']), + ]; + final accepts = acceptedTypesToString(acceptedTypes); + expect(accepts, 'image/jpeg,image/jpg,image/png'); + }); + + test('works with web wild cards', () { + final List acceptedTypes = [ + XTypeGroup(label: 'images', webWildCards: ['image/*']), + XTypeGroup(label: 'audios', webWildCards: ['audio/*']), + XTypeGroup(label: 'videos', webWildCards: ['video/*']), + ]; + final accepts = acceptedTypesToString(acceptedTypes); + expect(accepts, 'image/*,audio/*,video/*'); + }); + }); + }); +} diff --git a/packages/file_selector/file_selector_web/test_driver/integration_test.dart b/packages/file_selector/file_selector_web/test_driver/integration_test.dart new file mode 100644 index 000000000000..44d6ed9c64bc --- /dev/null +++ b/packages/file_selector/file_selector_web/test_driver/integration_test.dart @@ -0,0 +1,7 @@ +// 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:integration_test/integration_test_driver.dart'; + +Future main() => integrationDriver(); From 100c7470d4066b1d0f8f7e4ec6d7c943e736f970 Mon Sep 17 00:00:00 2001 From: Bodhi Mulders Date: Wed, 13 Jan 2021 20:59:04 +0100 Subject: [PATCH 0034/1565] [camera] Implemented capture orientation locking. Fixed preview rotation issues. Fixed video and photo orientation upon save. (#3390) --- packages/camera/camera/CHANGELOG.md | 10 +- packages/camera/camera/android/build.gradle | 2 +- .../io/flutter/plugins/camera/Camera.java | 52 +++-- .../flutter/plugins/camera/CameraUtils.java | 54 +++++ .../flutter/plugins/camera/DartMessenger.java | 66 ++++-- .../camera/DeviceOrientationManager.java | 201 +++++++++++++++++ .../plugins/camera/MethodCallHandlerImpl.java | 26 ++- .../plugins/camera/CameraUtilsTest.java | 102 +++++++++ .../plugins/camera/DartMessengerTest.java | 12 + .../camera/example/android/app/build.gradle | 2 +- .../camera/example/ios/Runner/Info.plist | 1 + packages/camera/camera/example/lib/main.dart | 34 ++- .../camera/camera/ios/Classes/CameraPlugin.m | 209 +++++++++++++----- .../camera/lib/src/camera_controller.dart | 81 ++++++- .../camera/camera/lib/src/camera_preview.dart | 47 +++- packages/camera/camera/pubspec.yaml | 3 +- packages/camera/camera/test/camera_test.dart | 107 +++++++++ .../camera/camera/test/camera_value_test.dart | 42 +++- 18 files changed, 930 insertions(+), 121 deletions(-) create mode 100644 packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java create mode 100644 packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraUtilsTest.java diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 1a2b03d93a6a..8525ad1e21d8 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.7.0 + +* Added support for capture orientation locking on Android and iOS. +* Fixed camera preview not rotating correctly on Android and iOS. +* Fixed camera preview sometimes appearing stretched on Android and iOS. +* Fixed videos & photos saving with the incorrect rotation on iOS. +* BREAKING CHANGE: `CameraValue.aspectRatio` now returns `width / height` rather than `height / width`. + ## 0.6.6 * Adds auto focus support for Android and iOS implementations. @@ -20,7 +28,7 @@ ## 0.6.4+2 -* Set ImageStreamReader listener to null to prevent stale images when streaming images. +* Set ImageStreamReader listener to null to prevent stale images when streaming images. ## 0.6.4+1 diff --git a/packages/camera/camera/android/build.gradle b/packages/camera/camera/android/build.gradle index 0b88fd10fb71..0606738a0a69 100644 --- a/packages/camera/camera/android/build.gradle +++ b/packages/camera/camera/android/build.gradle @@ -27,7 +27,7 @@ project.getTasks().withType(JavaCompile){ apply plugin: 'com.android.library' android { - compileSdkVersion 29 + compileSdkVersion 30 defaultConfig { minSdkVersion 21 diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 3fc702a2a879..10d58f5e8792 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -4,7 +4,6 @@ package io.flutter.plugins.camera; -import static android.view.OrientationEventListener.ORIENTATION_UNKNOWN; import static io.flutter.plugins.camera.CameraUtils.computeBestPreviewSize; import android.annotation.SuppressLint; @@ -41,10 +40,10 @@ import android.util.Range; import android.util.Rational; import android.util.Size; -import android.view.OrientationEventListener; import android.view.Surface; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import io.flutter.embedding.engine.systemchannels.PlatformChannel; import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugins.camera.PictureCaptureRequest.State; @@ -76,7 +75,7 @@ public class Camera { private final SurfaceTextureEntry flutterTexture; private final CameraManager cameraManager; - private final OrientationEventListener orientationEventListener; + private final DeviceOrientationManager deviceOrientationListener; private final boolean isFrontFacing; private final int sensorOrientation; private final String cameraName; @@ -97,7 +96,6 @@ public class Camera { private MediaRecorder mediaRecorder; private boolean recordingVideo; private File videoRecordingFile; - private int currentOrientation = ORIENTATION_UNKNOWN; private FlashMode flashMode; private ExposureMode exposureMode; private FocusMode focusMode; @@ -106,6 +104,7 @@ public class Camera { private int exposureOffset; private boolean useAutoFocus = true; private Range fpsRange; + private PlatformChannel.DeviceOrientation lockedCaptureOrientation; private static final HashMap supportedImageFormats; // Current supported outputs @@ -136,18 +135,6 @@ public Camera( this.exposureMode = ExposureMode.auto; this.focusMode = FocusMode.auto; this.exposureOffset = 0; - orientationEventListener = - new OrientationEventListener(activity.getApplicationContext()) { - @Override - public void onOrientationChanged(int i) { - if (i == ORIENTATION_UNKNOWN) { - return; - } - // Convert the raw deg angle to the nearest multiple of 90. - currentOrientation = (int) Math.round(i / 90.0) * 90; - } - }; - orientationEventListener.enable(); cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraName); initFps(cameraCharacteristics); @@ -164,6 +151,10 @@ public void onOrientationChanged(int i) { new CameraZoom( cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE), cameraCharacteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM)); + + deviceOrientationListener = + new DeviceOrientationManager(activity, dartMessenger, isFrontFacing, sensorOrientation); + deviceOrientationListener.start(); } private void initFps(CameraCharacteristics cameraCharacteristics) { @@ -195,7 +186,10 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException { mediaRecorder = new MediaRecorderBuilder(recordingProfile, outputFilePath) .setEnableAudio(enableAudio) - .setMediaOrientation(getMediaOrientation()) + .setMediaOrientation( + lockedCaptureOrientation == null + ? deviceOrientationListener.getMediaOrientation() + : deviceOrientationListener.getMediaOrientation(lockedCaptureOrientation)) .build(); } @@ -545,7 +539,11 @@ private void runPictureCapture() { final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); captureBuilder.addTarget(pictureImageReader.getSurface()); - captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getMediaOrientation()); + captureBuilder.set( + CaptureRequest.JPEG_ORIENTATION, + lockedCaptureOrientation == null + ? deviceOrientationListener.getMediaOrientation() + : deviceOrientationListener.getMediaOrientation(lockedCaptureOrientation)); switch (flashMode) { case off: captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); @@ -968,6 +966,14 @@ public void setZoomLevel(@NonNull final Result result, float zoom) throws Camera result.success(null); } + public void lockCaptureOrientation(PlatformChannel.DeviceOrientation orientation) { + this.lockedCaptureOrientation = orientation; + } + + public void unlockCaptureOrientation() { + this.lockedCaptureOrientation = null; + } + private void updateFpsRange() { if (fpsRange == null) { return; @@ -1160,14 +1166,6 @@ public void close() { public void dispose() { close(); flutterTexture.release(); - orientationEventListener.disable(); - } - - private int getMediaOrientation() { - final int sensorOrientationOffset = - (currentOrientation == ORIENTATION_UNKNOWN) - ? 0 - : (isFrontFacing) ? -currentOrientation : currentOrientation; - return (sensorOrientationOffset + sensorOrientation + 360) % 360; + deviceOrientationListener.stop(); } } diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java index 6f04dc80e102..03993a3b51f9 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java @@ -14,6 +14,7 @@ import android.hardware.camera2.params.StreamConfigurationMap; import android.media.CamcorderProfile; import android.util.Size; +import io.flutter.embedding.engine.systemchannels.PlatformChannel; import io.flutter.plugins.camera.types.ResolutionPreset; import java.util.ArrayList; import java.util.Arrays; @@ -28,6 +29,59 @@ public final class CameraUtils { private CameraUtils() {} + static PlatformChannel.DeviceOrientation getDeviceOrientationFromDegrees(int degrees) { + // Round to the nearest 90 degrees. + degrees = (int) (Math.round(degrees / 90.0) * 90) % 360; + // Determine the corresponding device orientation. + switch (degrees) { + case 90: + return PlatformChannel.DeviceOrientation.LANDSCAPE_LEFT; + case 180: + return PlatformChannel.DeviceOrientation.PORTRAIT_DOWN; + case 270: + return PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT; + case 0: + default: + return PlatformChannel.DeviceOrientation.PORTRAIT_UP; + } + } + + static String serializeDeviceOrientation(PlatformChannel.DeviceOrientation orientation) { + if (orientation == null) + throw new UnsupportedOperationException("Could not serialize null device orientation."); + switch (orientation) { + case PORTRAIT_UP: + return "portraitUp"; + case PORTRAIT_DOWN: + return "portraitDown"; + case LANDSCAPE_LEFT: + return "landscapeLeft"; + case LANDSCAPE_RIGHT: + return "landscapeRight"; + default: + throw new UnsupportedOperationException( + "Could not serialize device orientation: " + orientation.toString()); + } + } + + static PlatformChannel.DeviceOrientation deserializeDeviceOrientation(String orientation) { + if (orientation == null) + throw new UnsupportedOperationException("Could not deserialize null device orientation."); + switch (orientation) { + case "portraitUp": + return PlatformChannel.DeviceOrientation.PORTRAIT_UP; + case "portraitDown": + return PlatformChannel.DeviceOrientation.PORTRAIT_DOWN; + case "landscapeLeft": + return PlatformChannel.DeviceOrientation.LANDSCAPE_LEFT; + case "landscapeRight": + return PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT; + default: + throw new UnsupportedOperationException( + "Could not deserialize device orientation: " + orientation); + } + } + static Size computeBestPreviewSize(String cameraName, ResolutionPreset preset) { if (preset.ordinal() > ResolutionPreset.high.ordinal()) { preset = ResolutionPreset.high; diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java index ec68ac0acda3..5681f723ed80 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java @@ -6,6 +6,7 @@ import android.text.TextUtils; import androidx.annotation.Nullable; +import io.flutter.embedding.engine.systemchannels.PlatformChannel; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugins.camera.types.ExposureMode; @@ -14,16 +15,44 @@ import java.util.Map; class DartMessenger { - @Nullable private MethodChannel channel; + @Nullable private MethodChannel cameraChannel; + @Nullable private MethodChannel deviceChannel; - enum EventType { - ERROR, - CAMERA_CLOSING, - INITIALIZED, + enum DeviceEventType { + ORIENTATION_CHANGED("orientation_changed"); + private final String method; + + DeviceEventType(String method) { + this.method = method; + } + } + + enum CameraEventType { + ERROR("error"), + CLOSING("camera_closing"), + INITIALIZED("initialized"); + + private final String method; + + CameraEventType(String method) { + this.method = method; + } } DartMessenger(BinaryMessenger messenger, long cameraId) { - channel = new MethodChannel(messenger, "flutter.io/cameraPlugin/camera" + cameraId); + cameraChannel = new MethodChannel(messenger, "flutter.io/cameraPlugin/camera" + cameraId); + deviceChannel = new MethodChannel(messenger, "flutter.io/cameraPlugin/device"); + } + + void sendDeviceOrientationChangeEvent(PlatformChannel.DeviceOrientation orientation) { + assert (orientation != null); + this.send( + DeviceEventType.ORIENTATION_CHANGED, + new HashMap() { + { + put("orientation", CameraUtils.serializeDeviceOrientation(orientation)); + } + }); } void sendCameraInitializedEvent( @@ -40,7 +69,7 @@ void sendCameraInitializedEvent( assert (exposurePointSupported != null); assert (focusPointSupported != null); this.send( - EventType.INITIALIZED, + CameraEventType.INITIALIZED, new HashMap() { { put("previewWidth", previewWidth.doubleValue()); @@ -54,12 +83,12 @@ void sendCameraInitializedEvent( } void sendCameraClosingEvent() { - send(EventType.CAMERA_CLOSING); + send(CameraEventType.CLOSING); } void sendCameraErrorEvent(@Nullable String description) { this.send( - EventType.ERROR, + CameraEventType.ERROR, new HashMap() { { if (!TextUtils.isEmpty(description)) put("description", description); @@ -67,14 +96,25 @@ void sendCameraErrorEvent(@Nullable String description) { }); } - void send(EventType eventType) { + void send(CameraEventType eventType) { + send(eventType, new HashMap<>()); + } + + void send(CameraEventType eventType, Map args) { + if (cameraChannel == null) { + return; + } + cameraChannel.invokeMethod(eventType.method, args); + } + + void send(DeviceEventType eventType) { send(eventType, new HashMap<>()); } - void send(EventType eventType, Map args) { - if (channel == null) { + void send(DeviceEventType eventType, Map args) { + if (deviceChannel == null) { return; } - channel.invokeMethod(eventType.toString().toLowerCase(), args); + deviceChannel.invokeMethod(eventType.method, args); } } diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java new file mode 100644 index 000000000000..d39a8da55cc8 --- /dev/null +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java @@ -0,0 +1,201 @@ +// Copyright 2019 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. + +package io.flutter.plugins.camera; + +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.res.Configuration; +import android.hardware.SensorManager; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; +import android.provider.Settings; +import android.view.Display; +import android.view.OrientationEventListener; +import android.view.Surface; +import android.view.WindowManager; +import io.flutter.embedding.engine.systemchannels.PlatformChannel; + +class DeviceOrientationManager { + + private static final IntentFilter orientationIntentFilter = + new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED); + + private final Activity activity; + private final DartMessenger messenger; + private final boolean isFrontFacing; + private final int sensorOrientation; + private PlatformChannel.DeviceOrientation lastOrientation; + private OrientationEventListener orientationEventListener; + private BroadcastReceiver broadcastReceiver; + + public DeviceOrientationManager( + Activity activity, DartMessenger messenger, boolean isFrontFacing, int sensorOrientation) { + this.activity = activity; + this.messenger = messenger; + this.isFrontFacing = isFrontFacing; + this.sensorOrientation = sensorOrientation; + } + + public void start() { + startSensorListener(); + startUIListener(); + } + + public void stop() { + stopSensorListener(); + stopUIListener(); + } + + public int getMediaOrientation() { + return this.getMediaOrientation(this.lastOrientation); + } + + public int getMediaOrientation(PlatformChannel.DeviceOrientation orientation) { + int angle = 0; + switch (orientation) { + case PORTRAIT_UP: + angle = 0; + break; + case PORTRAIT_DOWN: + angle = 180; + break; + case LANDSCAPE_LEFT: + angle = 90; + break; + case LANDSCAPE_RIGHT: + angle = 270; + break; + } + if (isFrontFacing) angle *= -1; + return (angle + sensorOrientation + 360) % 360; + } + + private void startSensorListener() { + if (orientationEventListener != null) return; + orientationEventListener = + new OrientationEventListener(activity, SensorManager.SENSOR_DELAY_NORMAL) { + @Override + public void onOrientationChanged(int angle) { + if (!isSystemAutoRotationLocked()) { + PlatformChannel.DeviceOrientation newOrientation = calculateSensorOrientation(angle); + if (!newOrientation.equals(lastOrientation)) { + lastOrientation = newOrientation; + messenger.sendDeviceOrientationChangeEvent(newOrientation); + } + } + } + }; + if (orientationEventListener.canDetectOrientation()) { + orientationEventListener.enable(); + } + } + + private void startUIListener() { + if (broadcastReceiver != null) return; + broadcastReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (isSystemAutoRotationLocked()) { + PlatformChannel.DeviceOrientation orientation = getUIOrientation(); + if (!orientation.equals(lastOrientation)) { + lastOrientation = orientation; + messenger.sendDeviceOrientationChangeEvent(orientation); + } + } + } + }; + activity.registerReceiver(broadcastReceiver, orientationIntentFilter); + broadcastReceiver.onReceive(activity, null); + } + + private void stopSensorListener() { + if (orientationEventListener == null) return; + orientationEventListener.disable(); + orientationEventListener = null; + } + + private void stopUIListener() { + if (broadcastReceiver == null) return; + activity.unregisterReceiver(broadcastReceiver); + broadcastReceiver = null; + } + + private boolean isSystemAutoRotationLocked() { + return android.provider.Settings.System.getInt( + activity.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0) + != 1; + } + + private PlatformChannel.DeviceOrientation getUIOrientation() { + final int rotation = getDisplay().getRotation(); + final int orientation = activity.getResources().getConfiguration().orientation; + + switch (orientation) { + case Configuration.ORIENTATION_PORTRAIT: + if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90) { + return PlatformChannel.DeviceOrientation.PORTRAIT_UP; + } else { + return PlatformChannel.DeviceOrientation.PORTRAIT_DOWN; + } + case Configuration.ORIENTATION_LANDSCAPE: + if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90) { + return PlatformChannel.DeviceOrientation.LANDSCAPE_LEFT; + } else { + return PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT; + } + default: + return PlatformChannel.DeviceOrientation.PORTRAIT_UP; + } + } + + private PlatformChannel.DeviceOrientation calculateSensorOrientation(int angle) { + final int tolerance = 45; + angle += tolerance; + + // Orientation is 0 in the default orientation mode. This is portait-mode for phones + // and landscape for tablets. We have to compensate for this by calculating the default + // orientation, and apply an offset accordingly. + int defaultDeviceOrientation = getDeviceDefaultOrientation(); + if (defaultDeviceOrientation == Configuration.ORIENTATION_LANDSCAPE) { + angle += 90; + } + // Determine the orientation + angle = angle % 360; + return new PlatformChannel.DeviceOrientation[] { + PlatformChannel.DeviceOrientation.PORTRAIT_UP, + PlatformChannel.DeviceOrientation.LANDSCAPE_LEFT, + PlatformChannel.DeviceOrientation.PORTRAIT_DOWN, + PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT, + } + [angle / 90]; + } + + private int getDeviceDefaultOrientation() { + Configuration config = activity.getResources().getConfiguration(); + int rotation = getDisplay().getRotation(); + if (((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) + && config.orientation == Configuration.ORIENTATION_LANDSCAPE) + || ((rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) + && config.orientation == Configuration.ORIENTATION_PORTRAIT)) { + return Configuration.ORIENTATION_LANDSCAPE; + } else { + return Configuration.ORIENTATION_PORTRAIT; + } + } + + @SuppressWarnings("deprecation") + private Display getDisplay() { + if (VERSION.SDK_INT >= VERSION_CODES.R) { + return activity.getDisplay(); + } else { + return ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)) + .getDefaultDisplay(); + } + } +} diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java index 36048dbb5176..aa7483f55679 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java @@ -8,6 +8,7 @@ import android.hardware.camera2.CameraAccessException; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import io.flutter.embedding.engine.systemchannels.PlatformChannel; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.MethodCall; @@ -255,7 +256,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) case "stopImageStream": { try { - camera.stopImageStream(); + camera.startPreview(); result.success(null); } catch (Exception e) { handleException(e, result); @@ -305,6 +306,29 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) } break; } + case "lockCaptureOrientation": + { + PlatformChannel.DeviceOrientation orientation = + CameraUtils.deserializeDeviceOrientation(call.argument("orientation")); + + try { + camera.lockCaptureOrientation(orientation); + result.success(null); + } catch (Exception e) { + handleException(e, result); + } + break; + } + case "unlockCaptureOrientation": + { + try { + camera.unlockCaptureOrientation(); + result.success(null); + } catch (Exception e) { + handleException(e, result); + } + break; + } case "dispose": { if (camera != null) { diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraUtilsTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraUtilsTest.java new file mode 100644 index 000000000000..8026b6349aa1 --- /dev/null +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraUtilsTest.java @@ -0,0 +1,102 @@ +// Copyright 2019 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. + +package io.flutter.plugins.camera; + +import static org.junit.Assert.assertEquals; + +import io.flutter.embedding.engine.systemchannels.PlatformChannel; +import org.junit.Test; + +public class CameraUtilsTest { + + @Test + public void serializeDeviceOrientation_serializes_correctly() { + assertEquals( + "portraitUp", + CameraUtils.serializeDeviceOrientation(PlatformChannel.DeviceOrientation.PORTRAIT_UP)); + assertEquals( + "portraitDown", + CameraUtils.serializeDeviceOrientation(PlatformChannel.DeviceOrientation.PORTRAIT_DOWN)); + assertEquals( + "landscapeLeft", + CameraUtils.serializeDeviceOrientation(PlatformChannel.DeviceOrientation.LANDSCAPE_LEFT)); + assertEquals( + "landscapeRight", + CameraUtils.serializeDeviceOrientation(PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT)); + } + + @Test(expected = UnsupportedOperationException.class) + public void serializeDeviceOrientation_throws_for_null() { + CameraUtils.serializeDeviceOrientation(null); + } + + @Test + public void deserializeDeviceOrientation_deserializes_correctly() { + assertEquals( + PlatformChannel.DeviceOrientation.PORTRAIT_UP, + CameraUtils.deserializeDeviceOrientation("portraitUp")); + assertEquals( + PlatformChannel.DeviceOrientation.PORTRAIT_DOWN, + CameraUtils.deserializeDeviceOrientation("portraitDown")); + assertEquals( + PlatformChannel.DeviceOrientation.LANDSCAPE_LEFT, + CameraUtils.deserializeDeviceOrientation("landscapeLeft")); + assertEquals( + PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT, + CameraUtils.deserializeDeviceOrientation("landscapeRight")); + } + + @Test(expected = UnsupportedOperationException.class) + public void deserializeDeviceOrientation_throws_for_null() { + CameraUtils.deserializeDeviceOrientation(null); + } + + @Test + public void getDeviceOrientationFromDegrees_converts_correctly() { + // Portrait UP + assertEquals( + PlatformChannel.DeviceOrientation.PORTRAIT_UP, + CameraUtils.getDeviceOrientationFromDegrees(0)); + assertEquals( + PlatformChannel.DeviceOrientation.PORTRAIT_UP, + CameraUtils.getDeviceOrientationFromDegrees(315)); + assertEquals( + PlatformChannel.DeviceOrientation.PORTRAIT_UP, + CameraUtils.getDeviceOrientationFromDegrees(44)); + assertEquals( + PlatformChannel.DeviceOrientation.PORTRAIT_UP, + CameraUtils.getDeviceOrientationFromDegrees(-45)); + // Portrait DOWN + assertEquals( + PlatformChannel.DeviceOrientation.PORTRAIT_DOWN, + CameraUtils.getDeviceOrientationFromDegrees(180)); + assertEquals( + PlatformChannel.DeviceOrientation.PORTRAIT_DOWN, + CameraUtils.getDeviceOrientationFromDegrees(135)); + assertEquals( + PlatformChannel.DeviceOrientation.PORTRAIT_DOWN, + CameraUtils.getDeviceOrientationFromDegrees(224)); + // Landscape LEFT + assertEquals( + PlatformChannel.DeviceOrientation.LANDSCAPE_LEFT, + CameraUtils.getDeviceOrientationFromDegrees(90)); + assertEquals( + PlatformChannel.DeviceOrientation.LANDSCAPE_LEFT, + CameraUtils.getDeviceOrientationFromDegrees(45)); + assertEquals( + PlatformChannel.DeviceOrientation.LANDSCAPE_LEFT, + CameraUtils.getDeviceOrientationFromDegrees(134)); + // Landscape RIGHT + assertEquals( + PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT, + CameraUtils.getDeviceOrientationFromDegrees(270)); + assertEquals( + PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT, + CameraUtils.getDeviceOrientationFromDegrees(225)); + assertEquals( + PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT, + CameraUtils.getDeviceOrientationFromDegrees(314)); + } +} diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java index 64425b7b8283..e835b08f441a 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java @@ -8,6 +8,7 @@ import static org.junit.Assert.assertEquals; import androidx.annotation.NonNull; +import io.flutter.embedding.engine.systemchannels.PlatformChannel; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.StandardMethodCodec; @@ -89,6 +90,17 @@ public void sendCameraClosingEvent() { assertNull(call.argument("description")); } + @Test + public void sendDeviceOrientationChangedEvent() { + dartMessenger.sendDeviceOrientationChangeEvent(PlatformChannel.DeviceOrientation.PORTRAIT_UP); + + List sentMessages = fakeBinaryMessenger.getMessages(); + assertEquals(1, sentMessages.size()); + MethodCall call = decodeSentMessage(sentMessages.get(0)); + assertEquals("orientation_changed", call.method); + assertEquals(call.argument("orientation"), "portraitUp"); + } + private MethodCall decodeSentMessage(ByteBuffer sentMessage) { sentMessage.position(0); diff --git a/packages/camera/camera/example/android/app/build.gradle b/packages/camera/camera/example/android/app/build.gradle index 7d0e281b74e8..c5eeb246fe30 100644 --- a/packages/camera/camera/example/android/app/build.gradle +++ b/packages/camera/camera/example/android/app/build.gradle @@ -25,7 +25,7 @@ apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 29 + compileSdkVersion 30 lintOptions { disable 'InvalidPackage' diff --git a/packages/camera/camera/example/ios/Runner/Info.plist b/packages/camera/camera/example/ios/Runner/Info.plist index f389a129e028..ff2e341a1803 100644 --- a/packages/camera/camera/example/ios/Runner/Info.plist +++ b/packages/camera/camera/example/ios/Runner/Info.plist @@ -39,6 +39,7 @@ UISupportedInterfaceOrientations UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight diff --git a/packages/camera/camera/example/lib/main.dart b/packages/camera/camera/example/lib/main.dart index 681a45172816..490cae6676d3 100644 --- a/packages/camera/camera/example/lib/main.dart +++ b/packages/camera/camera/example/lib/main.dart @@ -171,18 +171,18 @@ class _CameraExampleHomeState extends State ), ); } else { - return AspectRatio( - aspectRatio: controller.value.aspectRatio, - child: Listener( - onPointerDown: (_) => _pointers++, - onPointerUp: (_) => _pointers--, + return Listener( + onPointerDown: (_) => _pointers++, + onPointerUp: (_) => _pointers--, + child: CameraPreview( + controller, child: LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { return GestureDetector( + behavior: HitTestBehavior.opaque, onScaleStart: _handleScaleStart, onScaleUpdate: _handleScaleUpdate, onTapDown: (details) => onViewFinderTap(details, constraints), - child: CameraPreview(controller), ); }), ), @@ -269,6 +269,15 @@ class _CameraExampleHomeState extends State color: Colors.blue, onPressed: controller != null ? onAudioModeButtonPressed : null, ), + IconButton( + icon: Icon(controller?.value?.isCaptureOrientationLocked ?? false + ? Icons.screen_lock_rotation + : Icons.screen_rotation), + color: Colors.blue, + onPressed: controller != null + ? onCaptureOrientationLockButtonPressed + : null, + ), ], ), _flashModeControlRowWidget(), @@ -634,6 +643,19 @@ class _CameraExampleHomeState extends State } } + void onCaptureOrientationLockButtonPressed() async { + if (controller != null) { + if (controller.value.isCaptureOrientationLocked) { + await controller.unlockCaptureOrientation(); + showInSnackBar('Capture orientation unlocked'); + } else { + await controller.lockCaptureOrientation(); + showInSnackBar( + 'Capture orientation locked to ${controller.value.lockedCaptureOrientation.toString().split('.').last}'); + } + } + } + void onSetFlashModeButtonPressed(FlashMode mode) { setFlashMode(mode).then((_) { if (mounted) setState(() {}); diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index 298b906ace7b..40d93fde7af6 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -18,8 +18,6 @@ @interface FLTSavePhotoDelegate : NSObject @property(readonly, nonatomic) NSString *path; @property(readonly, nonatomic) FlutterResult result; -@property(readonly, nonatomic) CMMotionManager *motionManager; -@property(readonly, nonatomic) AVCaptureDevicePosition cameraPosition; @end @interface FLTImageStreamHandler : NSObject @@ -45,15 +43,10 @@ @implementation FLTSavePhotoDelegate { FLTSavePhotoDelegate *selfReference; } -- initWithPath:(NSString *)path - result:(FlutterResult)result - motionManager:(CMMotionManager *)motionManager - cameraPosition:(AVCaptureDevicePosition)cameraPosition { +- initWithPath:(NSString *)path result:(FlutterResult)result { self = [super init]; NSAssert(self, @"super init cannot be nil"); _path = path; - _motionManager = motionManager; - _cameraPosition = cameraPosition; selfReference = self; _result = result; return self; @@ -70,15 +63,14 @@ - (void)captureOutput:(AVCapturePhotoOutput *)output _result(getFlutterError(error)); return; } + NSData *data = [AVCapturePhotoOutput JPEGPhotoDataRepresentationForJPEGSampleBuffer:photoSampleBuffer previewPhotoSampleBuffer:previewPhotoSampleBuffer]; - UIImage *image = [UIImage imageWithCGImage:[UIImage imageWithData:data].CGImage - scale:1.0 - orientation:[self getImageRotation]]; // TODO(sigurdm): Consider writing file asynchronously. - bool success = [UIImageJPEGRepresentation(image, 1.0) writeToFile:_path atomically:YES]; + bool success = [data writeToFile:_path atomically:YES]; + if (!success) { _result([FlutterError errorWithCode:@"IOError" message:@"Unable to write file" details:nil]); return; @@ -104,34 +96,6 @@ - (void)captureOutput:(AVCapturePhotoOutput *)output } _result(_path); } - -- (UIImageOrientation)getImageRotation { - float const threshold = 45.0; - BOOL (^isNearValue)(float value1, float value2) = ^BOOL(float value1, float value2) { - return fabsf(value1 - value2) < threshold; - }; - BOOL (^isNearValueABS)(float value1, float value2) = ^BOOL(float value1, float value2) { - return isNearValue(fabsf(value1), fabsf(value2)); - }; - float yxAtan = (atan2(_motionManager.accelerometerData.acceleration.y, - _motionManager.accelerometerData.acceleration.x)) * - 180 / M_PI; - if (isNearValue(-90.0, yxAtan)) { - return UIImageOrientationRight; - } else if (isNearValueABS(180.0, yxAtan)) { - return _cameraPosition == AVCaptureDevicePositionBack ? UIImageOrientationUp - : UIImageOrientationDown; - } else if (isNearValueABS(0.0, yxAtan)) { - return _cameraPosition == AVCaptureDevicePositionBack ? UIImageOrientationDown /*rotate 180* */ - : UIImageOrientationUp /*do not rotate*/; - } else if (isNearValue(90.0, yxAtan)) { - return UIImageOrientationLeft; - } - // If none of the above, then the device is likely facing straight down or straight up -- just - // pick something arbitrary - // TODO: Maybe use the UIInterfaceOrientation if in these scenarios - return UIImageOrientationUp; -} @end // Mirrors FlashMode in flash_mode.dart @@ -226,6 +190,42 @@ static ExposureMode getExposureModeForString(NSString *mode) { } } +static UIDeviceOrientation getUIDeviceOrientationForString(NSString *orientation) { + if ([orientation isEqualToString:@"portraitDown"]) { + return UIDeviceOrientationPortraitUpsideDown; + } else if ([orientation isEqualToString:@"landscapeLeft"]) { + return UIDeviceOrientationLandscapeRight; + } else if ([orientation isEqualToString:@"landscapeRight"]) { + return UIDeviceOrientationLandscapeLeft; + } else if ([orientation isEqualToString:@"portraitUp"]) { + return UIDeviceOrientationPortrait; + } else { + NSError *error = [NSError + errorWithDomain:NSCocoaErrorDomain + code:NSURLErrorUnknown + userInfo:@{ + NSLocalizedDescriptionKey : + [NSString stringWithFormat:@"Unknown device orientation %@", orientation] + }]; + @throw error; + } +} + +static NSString *getStringForUIDeviceOrientation(UIDeviceOrientation orientation) { + switch (orientation) { + case UIDeviceOrientationPortraitUpsideDown: + return @"portraitDown"; + case UIDeviceOrientationLandscapeRight: + return @"landscapeLeft"; + case UIDeviceOrientationLandscapeLeft: + return @"landscapeRight"; + case UIDeviceOrientationPortrait: + default: + return @"portraitUp"; + break; + }; +} + // Mirrors FocusMode in camera.dart typedef enum { FocusModeAuto, @@ -334,6 +334,7 @@ @interface FLTCam : NSObject *registry; @property(readonly, nonatomic) NSObject *messenger; @property(readonly, nonatomic) FLTCam *camera; +@property(readonly, nonatomic) FlutterMethodChannel *deviceEventMethodChannel; @end @implementation CameraPlugin { @@ -1161,9 +1236,36 @@ - (instancetype)initWithRegistry:(NSObject *)registry NSAssert(self, @"super init cannot be nil"); _registry = registry; _messenger = messenger; + [self initDeviceEventMethodChannel]; + [self startOrientationListener]; return self; } +- (void)initDeviceEventMethodChannel { + _deviceEventMethodChannel = + [FlutterMethodChannel methodChannelWithName:@"flutter.io/cameraPlugin/device" + binaryMessenger:_messenger]; +} + +- (void)startOrientationListener { + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(orientationChanged:) + name:UIDeviceOrientationDidChangeNotification + object:[UIDevice currentDevice]]; +} + +- (void)orientationChanged:(NSNotification *)note { + UIDevice *device = note.object; + [self sendDeviceOrientation:device.orientation]; +} + +- (void)sendDeviceOrientation:(UIDeviceOrientation)orientation { + [_deviceEventMethodChannel + invokeMethod:@"orientation_changed" + arguments:@{@"orientation" : getStringForUIDeviceOrientation(orientation)}]; +} + - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { if (_dispatchQueue == nil) { _dispatchQueue = dispatch_queue_create("io.flutter.camera.dispatchqueue", NULL); @@ -1265,6 +1367,7 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re @([_camera.captureDevice isExposurePointOfInterestSupported]), @"focusPointSupported" : @([_camera.captureDevice isFocusPointOfInterestSupported]), }]; + [self sendDeviceOrientation:[UIDevice currentDevice].orientation]; [_camera start]; result(nil); } else if ([@"takePicture" isEqualToString:call.method]) { @@ -1318,6 +1421,10 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re } else if ([@"setExposureOffset" isEqualToString:call.method]) { [_camera setExposureOffsetWithResult:result offset:((NSNumber *)call.arguments[@"offset"]).doubleValue]; + } else if ([@"lockCaptureOrientation" isEqualToString:call.method]) { + [_camera lockCaptureOrientationWithResult:result orientation:call.arguments[@"orientation"]]; + } else if ([@"unlockCaptureOrientation" isEqualToString:call.method]) { + [_camera unlockCaptureOrientationWithResult:result]; } else if ([@"setFocusMode" isEqualToString:call.method]) { [_camera setFocusModeWithResult:result mode:call.arguments[@"mode"]]; } else if ([@"setFocusPoint" isEqualToString:call.method]) { diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index ae79cc4ad367..807bec367256 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -11,6 +11,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:pedantic/pedantic.dart'; +import 'package:quiver/core.dart'; final MethodChannel _channel = const MethodChannel('plugins.flutter.io/camera'); @@ -43,6 +44,9 @@ class CameraValue { this.focusMode, this.exposurePointSupported, this.focusPointSupported, + this.deviceOrientation, + this.lockedCaptureOrientation, + this.recordingOrientation, }) : _isRecordingPaused = isRecordingPaused; /// Creates a new camera controller state for an uninitialized controller. @@ -56,6 +60,7 @@ class CameraValue { flashMode: FlashMode.auto, exposurePointSupported: false, focusPointSupported: false, + deviceOrientation: DeviceOrientation.portraitUp, ); /// True after [CameraController.initialize] has completed successfully. @@ -86,10 +91,10 @@ class CameraValue { /// Is `null` until [isInitialized] is `true`. final Size previewSize; - /// Convenience getter for `previewSize.height / previewSize.width`. + /// Convenience getter for `previewSize.width / previewSize.height`. /// /// Can only be called when [initialize] is done. - double get aspectRatio => previewSize.height / previewSize.width; + double get aspectRatio => previewSize.width / previewSize.height; /// Whether the controller is in an error state. /// @@ -111,6 +116,18 @@ class CameraValue { /// Whether setting the focus point is supported. final bool focusPointSupported; + /// The current device orientation. + final DeviceOrientation deviceOrientation; + + /// The currently locked capture orientation. + final DeviceOrientation lockedCaptureOrientation; + + /// Whether the capture orientation is currently locked. + bool get isCaptureOrientationLocked => lockedCaptureOrientation != null; + + /// The orientation of the currently running video recording. + final DeviceOrientation recordingOrientation; + /// Creates a modified copy of the object. /// /// Explicitly specified fields get the specified value, all other fields get @@ -128,6 +145,9 @@ class CameraValue { FocusMode focusMode, bool exposurePointSupported, bool focusPointSupported, + DeviceOrientation deviceOrientation, + Optional lockedCaptureOrientation, + Optional recordingOrientation, }) { return CameraValue( isInitialized: isInitialized ?? this.isInitialized, @@ -143,6 +163,13 @@ class CameraValue { exposurePointSupported: exposurePointSupported ?? this.exposurePointSupported, focusPointSupported: focusPointSupported ?? this.focusPointSupported, + deviceOrientation: deviceOrientation ?? this.deviceOrientation, + lockedCaptureOrientation: lockedCaptureOrientation == null + ? this.lockedCaptureOrientation + : lockedCaptureOrientation.orNull, + recordingOrientation: recordingOrientation == null + ? this.recordingOrientation + : recordingOrientation.orNull, ); } @@ -158,7 +185,10 @@ class CameraValue { 'exposureMode: $exposureMode, ' 'focusMode: $focusMode, ' 'exposurePointSupported: $exposurePointSupported, ' - 'focusPointSupported: $focusPointSupported)'; + 'focusPointSupported: $focusPointSupported, ' + 'deviceOrientation: $deviceOrientation, ' + 'lockedCaptureOrientation: $lockedCaptureOrientation, ' + 'recordingOrientation: $recordingOrientation)'; } } @@ -201,6 +231,7 @@ class CameraController extends ValueNotifier { bool _isDisposed = false; StreamSubscription _imageStreamSubscription; FutureOr _initCalled; + StreamSubscription _deviceOrientationSubscription; /// Checks whether [CameraController.dispose] has completed successfully. /// @@ -225,6 +256,13 @@ class CameraController extends ValueNotifier { try { Completer _initializeCompleter = Completer(); + _deviceOrientationSubscription = + CameraPlatform.instance.onDeviceOrientationChanged().listen((event) { + value = value.copyWith( + deviceOrientation: event.orientation, + ); + }); + _cameraId = await CameraPlatform.instance.createCamera( description, resolutionPreset, @@ -431,7 +469,11 @@ class CameraController extends ValueNotifier { try { await CameraPlatform.instance.startVideoRecording(_cameraId); - value = value.copyWith(isRecordingVideo: true, isRecordingPaused: false); + value = value.copyWith( + isRecordingVideo: true, + isRecordingPaused: false, + recordingOrientation: Optional.fromNullable( + value.lockedCaptureOrientation ?? value.deviceOrientation)); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } @@ -455,7 +497,10 @@ class CameraController extends ValueNotifier { } try { XFile file = await CameraPlatform.instance.stopVideoRecording(_cameraId); - value = value.copyWith(isRecordingVideo: false); + value = value.copyWith( + isRecordingVideo: false, + recordingOrientation: Optional.absent(), + ); return file; } on PlatformException catch (e) { throw CameraException(e.code, e.message); @@ -718,6 +763,21 @@ class CameraController extends ValueNotifier { } } + /// Locks the capture orientation. + /// + /// If [orientation] is omitted, the current device orientation is used. + Future lockCaptureOrientation([DeviceOrientation orientation]) async { + try { + await CameraPlatform.instance.lockCaptureOrientation( + _cameraId, orientation ?? value.deviceOrientation); + value = value.copyWith( + lockedCaptureOrientation: + Optional.fromNullable(orientation ?? value.deviceOrientation)); + } on PlatformException catch (e) { + throw CameraException(e.code, e.message); + } + } + /// Sets the focus mode for taking pictures. Future setFocusMode(FocusMode mode) async { try { @@ -728,6 +788,16 @@ class CameraController extends ValueNotifier { } } + /// Unlocks the capture orientation. + Future unlockCaptureOrientation() async { + try { + await CameraPlatform.instance.unlockCaptureOrientation(_cameraId); + value = value.copyWith(lockedCaptureOrientation: Optional.absent()); + } on PlatformException catch (e) { + throw CameraException(e.code, e.message); + } + } + /// Sets the focus point for automatically determining the focus value. Future setFocusPoint(Offset point) async { if (point != null && @@ -756,6 +826,7 @@ class CameraController extends ValueNotifier { if (_isDisposed) { return; } + unawaited(_deviceOrientationSubscription?.cancel()); _isDisposed = true; super.dispose(); if (_initCalled != null) { diff --git a/packages/camera/camera/lib/src/camera_preview.dart b/packages/camera/camera/lib/src/camera_preview.dart index bf7862eb9151..05e969004233 100644 --- a/packages/camera/camera/lib/src/camera_preview.dart +++ b/packages/camera/camera/lib/src/camera_preview.dart @@ -4,20 +4,63 @@ import 'package:camera/camera.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; /// A widget showing a live camera preview. class CameraPreview extends StatelessWidget { /// Creates a preview widget for the given camera controller. - const CameraPreview(this.controller); + const CameraPreview(this.controller, {this.child}); /// The controller for the camera that the preview is shown for. final CameraController controller; + /// A widget to overlay on top of the camera preview + final Widget child; + @override Widget build(BuildContext context) { return controller.value.isInitialized - ? CameraPlatform.instance.buildPreview(controller.cameraId) + ? AspectRatio( + aspectRatio: _isLandscape() + ? controller.value.aspectRatio + : (1 / controller.value.aspectRatio), + child: Stack( + fit: StackFit.expand, + children: [ + RotatedBox( + quarterTurns: _getQuarterTurns(), + child: + CameraPlatform.instance.buildPreview(controller.cameraId), + ), + child ?? Container(), + ], + ), + ) : Container(); } + + DeviceOrientation _getApplicableOrientation() { + return controller.value.isRecordingVideo + ? controller.value.recordingOrientation + : (controller.value.lockedCaptureOrientation ?? + controller.value.deviceOrientation); + } + + bool _isLandscape() { + return [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight] + .contains(_getApplicableOrientation()); + } + + int _getQuarterTurns() { + int platformOffset = defaultTargetPlatform == TargetPlatform.iOS ? 1 : 0; + Map turns = { + DeviceOrientation.portraitUp: 0, + DeviceOrientation.landscapeLeft: 1, + DeviceOrientation.portraitDown: 2, + DeviceOrientation.landscapeRight: 3, + }; + return turns[_getApplicableOrientation()] + platformOffset; + } } diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 0b21497b5462..b0ebb9c16361 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.6.6 +version: 0.7.0 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: @@ -10,6 +10,7 @@ dependencies: sdk: flutter camera_platform_interface: ^1.5.0 pedantic: ^1.8.0 + quiver: ^2.1.5 dev_dependencies: path_provider: ^0.5.0 diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index 1cea609d1741..2f53691217cb 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -38,6 +38,9 @@ get mockOnCameraInitializedEvent => CameraInitializedEvent( true, ); +get mockOnDeviceOrientationChangedEvent => + DeviceOrientationChangedEvent(DeviceOrientation.portraitUp); + get mockOnCameraClosingEvent => null; get mockOnCameraErrorEvent => CameraErrorEvent(13, 'closing'); @@ -1021,6 +1024,106 @@ void main() { .setExposureOffset(cameraController.cameraId, -0.4)) .called(4); }); + + test('lockCaptureOrientation() calls $CameraPlatform', () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max); + await cameraController.initialize(); + + await cameraController.lockCaptureOrientation(); + expect(cameraController.value.lockedCaptureOrientation, + equals(DeviceOrientation.portraitUp)); + await cameraController + .lockCaptureOrientation(DeviceOrientation.landscapeRight); + expect(cameraController.value.lockedCaptureOrientation, + equals(DeviceOrientation.landscapeRight)); + + verify(CameraPlatform.instance.lockCaptureOrientation( + cameraController.cameraId, DeviceOrientation.portraitUp)) + .called(1); + verify(CameraPlatform.instance.lockCaptureOrientation( + cameraController.cameraId, DeviceOrientation.landscapeRight)) + .called(1); + }); + + test( + 'lockCaptureOrientation() throws $CameraException on $PlatformException', + () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max); + await cameraController.initialize(); + when(CameraPlatform.instance.lockCaptureOrientation( + cameraController.cameraId, DeviceOrientation.portraitUp)) + .thenThrow( + PlatformException( + code: 'TEST_ERROR', + message: 'This is a test error message', + details: null, + ), + ); + + expect( + cameraController.lockCaptureOrientation(DeviceOrientation.portraitUp), + throwsA(isA().having( + (error) => error.description, + 'TEST_ERROR', + 'This is a test error message', + ))); + }); + + test('unlockCaptureOrientation() calls $CameraPlatform', () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max); + await cameraController.initialize(); + + await cameraController.unlockCaptureOrientation(); + expect(cameraController.value.lockedCaptureOrientation, equals(null)); + + verify(CameraPlatform.instance + .unlockCaptureOrientation(cameraController.cameraId)) + .called(1); + }); + + test( + 'unlockCaptureOrientation() throws $CameraException on $PlatformException', + () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max); + await cameraController.initialize(); + when(CameraPlatform.instance + .unlockCaptureOrientation(cameraController.cameraId)) + .thenThrow( + PlatformException( + code: 'TEST_ERROR', + message: 'This is a test error message', + details: null, + ), + ); + + expect( + cameraController.unlockCaptureOrientation(), + throwsA(isA().having( + (error) => error.description, + 'TEST_ERROR', + 'This is a test error message', + ))); + }); }); } @@ -1057,6 +1160,10 @@ class MockCameraPlatform extends Mock Stream onCameraError(int cameraId) => Stream.value(mockOnCameraErrorEvent); + @override + Stream onDeviceOrientationChanged() => + Stream.value(mockOnDeviceOrientationChangedEvent); + @override Future takePicture(int cameraId) => mockPlatformException ? throw PlatformException(code: 'foo', message: 'bar') diff --git a/packages/camera/camera/test/camera_value_test.dart b/packages/camera/camera/test/camera_value_test.dart index eb7927b9eb6c..c365f6ddb9de 100644 --- a/packages/camera/camera/test/camera_value_test.dart +++ b/packages/camera/camera/test/camera_value_test.dart @@ -7,22 +7,27 @@ import 'dart:ui'; import 'package:camera/camera.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { group('camera_value', () { test('Can be created', () { var cameraValue = const CameraValue( - isInitialized: false, - errorDescription: null, - previewSize: Size(10, 10), - isRecordingPaused: false, - isRecordingVideo: false, - isTakingPicture: false, - isStreamingImages: false, - flashMode: FlashMode.auto, - exposureMode: ExposureMode.auto, - exposurePointSupported: true); + isInitialized: false, + errorDescription: null, + previewSize: Size(10, 10), + isRecordingPaused: false, + isRecordingVideo: false, + isTakingPicture: false, + isStreamingImages: false, + flashMode: FlashMode.auto, + exposureMode: ExposureMode.auto, + exposurePointSupported: true, + deviceOrientation: DeviceOrientation.portraitUp, + lockedCaptureOrientation: DeviceOrientation.portraitUp, + recordingOrientation: DeviceOrientation.portraitUp, + ); expect(cameraValue, isA()); expect(cameraValue.isInitialized, isFalse); @@ -35,6 +40,10 @@ void main() { expect(cameraValue.flashMode, FlashMode.auto); expect(cameraValue.exposureMode, ExposureMode.auto); expect(cameraValue.exposurePointSupported, true); + expect(cameraValue.deviceOrientation, DeviceOrientation.portraitUp); + expect( + cameraValue.lockedCaptureOrientation, DeviceOrientation.portraitUp); + expect(cameraValue.recordingOrientation, DeviceOrientation.portraitUp); }); test('Can be created as uninitialized', () { @@ -51,6 +60,9 @@ void main() { expect(cameraValue.flashMode, FlashMode.auto); expect(cameraValue.exposureMode, null); expect(cameraValue.exposurePointSupported, false); + expect(cameraValue.deviceOrientation, DeviceOrientation.portraitUp); + expect(cameraValue.lockedCaptureOrientation, null); + expect(cameraValue.recordingOrientation, null); }); test('Can be copied with isInitialized', () { @@ -68,6 +80,9 @@ void main() { expect(cameraValue.flashMode, FlashMode.auto); expect(cameraValue.exposureMode, null); expect(cameraValue.exposurePointSupported, false); + expect(cameraValue.deviceOrientation, DeviceOrientation.portraitUp); + expect(cameraValue.lockedCaptureOrientation, null); + expect(cameraValue.recordingOrientation, null); }); test('Has aspectRatio after setting size', () { @@ -75,7 +90,7 @@ void main() { var cameraValue = cv.copyWith(isInitialized: true, previewSize: Size(20, 10)); - expect(cameraValue.aspectRatio, 0.5); + expect(cameraValue.aspectRatio, 2.0); }); test('hasError is true after setting errorDescription', () { @@ -110,10 +125,13 @@ void main() { focusMode: FocusMode.auto, exposurePointSupported: true, focusPointSupported: true, + deviceOrientation: DeviceOrientation.portraitUp, + lockedCaptureOrientation: DeviceOrientation.portraitUp, + recordingOrientation: DeviceOrientation.portraitUp, ); expect(cameraValue.toString(), - 'CameraValue(isRecordingVideo: false, isInitialized: false, errorDescription: null, previewSize: Size(10.0, 10.0), isStreamingImages: false, flashMode: FlashMode.auto, exposureMode: ExposureMode.auto, focusMode: FocusMode.auto, exposurePointSupported: true, focusPointSupported: true)'); + 'CameraValue(isRecordingVideo: false, isInitialized: false, errorDescription: null, previewSize: Size(10.0, 10.0), isStreamingImages: false, flashMode: FlashMode.auto, exposureMode: ExposureMode.auto, focusMode: FocusMode.auto, exposurePointSupported: true, focusPointSupported: true, deviceOrientation: DeviceOrientation.portraitUp, lockedCaptureOrientation: DeviceOrientation.portraitUp, recordingOrientation: DeviceOrientation.portraitUp)'); }); }); } From 0434f0640052927f12f08439fc78d5afcaeb56c1 Mon Sep 17 00:00:00 2001 From: Aleksandr Yurkovskiy Date: Wed, 13 Jan 2021 23:29:06 +0300 Subject: [PATCH 0035/1565] [google_maps_flutter] Adds support for holes in polygon overlays to the Google Maps plugin (#1721) --- .../google_maps_flutter/CHANGELOG.md | 4 + .../flutter/plugins/googlemaps/Convert.java | 18 +- .../plugins/googlemaps/PolygonBuilder.java | 7 + .../plugins/googlemaps/PolygonController.java | 4 + .../googlemaps/PolygonOptionsSink.java | 2 + .../example/lib/place_polygon.dart | 60 ++++- .../ios/Classes/GoogleMapPolygonController.h | 1 + .../ios/Classes/GoogleMapPolygonController.m | 22 ++ .../ios/Classes/JsonConversions.h | 1 + .../ios/Classes/JsonConversions.m | 10 + .../lib/google_maps_flutter.dart | 1 - .../google_maps_flutter/pubspec.yaml | 4 +- .../test/fake_maps_controllers.dart | 10 + .../test/polygon_updates_test.dart | 221 ++++++++++++++++-- 14 files changed, 341 insertions(+), 24 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index b23ef79651e7..6dcb967f9cb4 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.0 + +* Add support for holes in Polygons. + ## 1.0.10 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java index 7222511a2a3b..4108a1d23bb5 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java @@ -468,6 +468,10 @@ static String interpretPolygonOptions(Object o, PolygonOptionsSink sink) { if (points != null) { sink.setPoints(toPoints(points)); } + final Object holes = data.get("holes"); + if (holes != null) { + sink.setHoles(toHoles(holes)); + } final String polygonId = (String) data.get("polygonId"); if (polygonId == null) { throw new IllegalArgumentException("polygonId was null"); @@ -576,13 +580,23 @@ private static List toPoints(Object o) { final List data = toList(o); final List points = new ArrayList<>(data.size()); - for (Object ob : data) { - final List point = toList(ob); + for (Object rawPoint : data) { + final List point = toList(rawPoint); points.add(new LatLng(toFloat(point.get(0)), toFloat(point.get(1)))); } return points; } + private static List> toHoles(Object o) { + final List data = toList(o); + final List> holes = new ArrayList<>(data.size()); + + for (Object rawHole : data) { + holes.add(toPoints(rawHole)); + } + return holes; + } + private static List toPattern(Object o) { final List data = toList(o); diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonBuilder.java index 600762afe4ee..7691e58e4ae6 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonBuilder.java @@ -41,6 +41,13 @@ public void setPoints(List points) { polygonOptions.addAll(points); } + @Override + public void setHoles(List> holes) { + for (List hole : holes) { + polygonOptions.addHole(hole); + } + } + @Override public void setConsumeTapEvents(boolean consumeTapEvents) { this.consumeTapEvents = consumeTapEvents; diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonController.java index adb01b8a490a..43f1bfd7ec4c 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonController.java @@ -52,6 +52,10 @@ public void setPoints(List points) { polygon.setPoints(points); } + public void setHoles(List> holes) { + polygon.setHoles(holes); + } + @Override public void setVisible(boolean visible) { polygon.setVisible(visible); diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonOptionsSink.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonOptionsSink.java index df4dae0fda4e..2985a7b762e5 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonOptionsSink.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonOptionsSink.java @@ -20,6 +20,8 @@ interface PolygonOptionsSink { void setPoints(List points); + void setHoles(List> holes); + void setVisible(boolean visible); void setStrokeWidth(float width); diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart index af5ca16bea17..5f2a0985b1b9 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart @@ -30,7 +30,8 @@ class PlacePolygonBodyState extends State { GoogleMapController controller; Map polygons = {}; - int _polygonIdCounter = 1; + Map polygonOffsets = {}; + int _polygonIdCounter = 0; PolygonId selectedPolygon; // Values when toggling polygon color @@ -79,7 +80,6 @@ class PlacePolygonBodyState extends State { } final String polygonIdVal = 'polygon_id_$_polygonIdCounter'; - _polygonIdCounter++; final PolygonId polygonId = PolygonId(polygonIdVal); final Polygon polygon = Polygon( @@ -96,6 +96,9 @@ class PlacePolygonBodyState extends State { setState(() { polygons[polygonId] = polygon; + polygonOffsets[polygonId] = _polygonIdCounter.ceilToDouble(); + // increment _polygonIdCounter to have unique polygon id each time + _polygonIdCounter++; }); } @@ -144,6 +147,22 @@ class PlacePolygonBodyState extends State { }); } + void _addHoles() { + final Polygon polygon = polygons[selectedPolygon]; + setState(() { + polygons[selectedPolygon] = polygon.copyWith(holesParam: _createHoles()); + }); + } + + void _removeHoles() { + final Polygon polygon = polygons[selectedPolygon]; + setState(() { + polygons[selectedPolygon] = polygon.copyWith( + holesParam: >[], + ); + }); + } + @override Widget build(BuildContext context) { return Column( @@ -196,6 +215,22 @@ class PlacePolygonBodyState extends State { ), Column( children: [ + TextButton( + child: const Text('add holes'), + onPressed: (selectedPolygon == null) + ? null + : ((polygons[selectedPolygon].holes.isNotEmpty) + ? null + : _addHoles), + ), + TextButton( + child: const Text('remove holes'), + onPressed: (selectedPolygon == null) + ? null + : ((polygons[selectedPolygon].holes.isEmpty) + ? null + : _removeHoles), + ), TextButton( child: const Text('change stroke width'), onPressed: @@ -235,6 +270,27 @@ class PlacePolygonBodyState extends State { return points; } + List> _createHoles() { + final List> holes = >[]; + final double offset = polygonOffsets[selectedPolygon]; + + final List hole1 = []; + hole1.add(_createLatLng(51.8395 + offset, -3.8814)); + hole1.add(_createLatLng(52.0234 + offset, -3.9914)); + hole1.add(_createLatLng(52.1351 + offset, -4.4435)); + hole1.add(_createLatLng(52.0231 + offset, -4.5829)); + holes.add(hole1); + + final List hole2 = []; + hole2.add(_createLatLng(52.2395 + offset, -3.6814)); + hole2.add(_createLatLng(52.4234 + offset, -3.7914)); + hole2.add(_createLatLng(52.5351 + offset, -4.2435)); + hole2.add(_createLatLng(52.4231 + offset, -4.3829)); + holes.add(hole2); + + return holes; + } + LatLng _createLatLng(double lat, double lng) { return LatLng(lat, lng); } diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h index c7613fde5f93..eb1735d134b8 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h @@ -13,6 +13,7 @@ - (void)setStrokeColor:(UIColor*)color; - (void)setStrokeWidth:(CGFloat)width; - (void)setPoints:(NSArray*)points; +- (void)setHoles:(NSArray*>*)holes; - (void)setZIndex:(int)zIndex; @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m index 678d40e3efec..1063a8cda990 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m @@ -45,6 +45,19 @@ - (void)setPoints:(NSArray*)points { } _polygon.path = path; } +- (void)setHoles:(NSArray*>*)rawHoles { + NSMutableArray* holes = [[NSMutableArray alloc] init]; + + for (NSArray* points in rawHoles) { + GMSMutablePath* path = [GMSMutablePath path]; + for (CLLocation* location in points) { + [path addCoordinate:location.coordinate]; + } + [holes addObject:path]; + } + + _polygon.holes = holes; +} - (void)setFillColor:(UIColor*)color { _polygon.fillColor = color; @@ -65,6 +78,10 @@ - (void)setStrokeWidth:(CGFloat)width { return [FLTGoogleMapJsonConversions toPoints:data]; } +static NSArray*>* ToHoles(NSArray* data) { + return [FLTGoogleMapJsonConversions toHoles:data]; +} + static UIColor* ToColor(NSNumber* data) { return [FLTGoogleMapJsonConversions toColor:data]; } static void InterpretPolygonOptions(NSDictionary* data, id sink, @@ -89,6 +106,11 @@ static void InterpretPolygonOptions(NSDictionary* data, id*)toPoints:(NSArray*)data; ++ (NSArray*>*)toHoles:(NSArray*)data; @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m index 6381beaee8d2..829f87791a07 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m @@ -58,4 +58,14 @@ + (UIColor*)toColor:(NSNumber*)numberColor { return points; } ++ (NSArray*>*)toHoles:(NSArray*)data { + NSMutableArray*>* holes = [[[NSMutableArray alloc] init] init]; + for (unsigned i = 0; i < [data count]; i++) { + NSArray* points = [FLTGoogleMapJsonConversions toPoints:data[i]]; + [holes addObject:points]; + } + + return holes; +} + @end diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart b/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart index b879f3d302cf..682c901f4d4a 100644 --- a/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart +++ b/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart @@ -13,7 +13,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; - import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; import 'package:google_maps_flutter_platform_interface/src/method_channel/method_channel_google_maps_flutter.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index 4faadf4c2166..c07d1899eba8 100644 --- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml @@ -1,13 +1,13 @@ name: google_maps_flutter description: A Flutter plugin for integrating Google Maps in iOS and Android applications. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter -version: 1.0.10 +version: 1.1.0 dependencies: flutter: sdk: flutter flutter_plugin_android_lifecycle: ^1.0.0 - google_maps_flutter_platform_interface: ^1.0.4 + google_maps_flutter_platform_interface: ^1.1.0 dev_dependencies: flutter_test: diff --git a/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart b/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart index adca8b4c2a0e..9a849bd94e70 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart @@ -202,12 +202,14 @@ class FakePlatformGoogleMap { final bool visible = polygonData['visible']; final bool geodesic = polygonData['geodesic']; final List points = _deserializePoints(polygonData['points']); + final List> holes = _deserializeHoles(polygonData['holes']); result.add(Polygon( polygonId: PolygonId(polygonId), visible: visible, geodesic: geodesic, points: points, + holes: holes, )); } @@ -220,6 +222,14 @@ class FakePlatformGoogleMap { }).toList(); } + List> _deserializeHoles(List holes) { + return holes.map>((dynamic hole) { + return hole.map((dynamic list) { + return LatLng(list[0], list[1]); + }).toList(); + }).toList(); + } + void updatePolylines(Map polylineUpdates) { if (polylineUpdates == null) { return; diff --git a/packages/google_maps_flutter/google_maps_flutter/test/polygon_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/polygon_updates_test.dart index 185c996113af..667c7d83644e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/polygon_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/polygon_updates_test.dart @@ -33,6 +33,29 @@ Widget _mapWithPolygons(Set polygons) { ); } +List _rectPoints({ + @required double size, + LatLng center = const LatLng(0, 0), +}) { + final halfSize = size / 2; + + return [ + LatLng(center.latitude + halfSize, center.longitude + halfSize), + LatLng(center.latitude - halfSize, center.longitude + halfSize), + LatLng(center.latitude - halfSize, center.longitude - halfSize), + LatLng(center.latitude + halfSize, center.longitude - halfSize), + ]; +} + +Polygon _polygonWithPointsAndHole(PolygonId polygonId) { + _rectPoints(size: 1); + return Polygon( + polygonId: polygonId, + points: _rectPoints(size: 1), + holes: [_rectPoints(size: 0.5)], + ); +} + void main() { TestWidgetsFlutterBinding.ensureInitialized(); @@ -113,23 +136,6 @@ void main() { expect(platformGoogleMap.polygonsToAdd.isEmpty, true); }); - testWidgets("Updating a polygon", (WidgetTester tester) async { - final Polygon p1 = Polygon(polygonId: PolygonId("polygon_1")); - final Polygon p2 = - Polygon(polygonId: PolygonId("polygon_1"), geodesic: true); - - await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); - await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p2))); - - final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; - expect(platformGoogleMap.polygonsToChange.length, 1); - - final Polygon update = platformGoogleMap.polygonsToChange.first; - expect(update, equals(p2)); - expect(update.geodesic, true); - }); - testWidgets("Mutate a polygon", (WidgetTester tester) async { final Polygon p1 = Polygon( polygonId: PolygonId("polygon_1"), @@ -228,4 +234,185 @@ void main() { expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true); expect(platformGoogleMap.polygonsToAdd.isEmpty, true); }); + + testWidgets('Initializing a polygon with points and hole', + (WidgetTester tester) async { + final Polygon p1 = _polygonWithPointsAndHole(PolygonId("polygon_1")); + await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); + + final FakePlatformGoogleMap platformGoogleMap = + fakePlatformViewsController.lastCreatedView; + expect(platformGoogleMap.polygonsToAdd.length, 1); + + final Polygon initializedPolygon = platformGoogleMap.polygonsToAdd.first; + expect(initializedPolygon, equals(p1)); + expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true); + expect(platformGoogleMap.polygonsToChange.isEmpty, true); + }); + + testWidgets("Adding a polygon with points and hole", + (WidgetTester tester) async { + final Polygon p1 = Polygon(polygonId: PolygonId("polygon_1")); + final Polygon p2 = _polygonWithPointsAndHole(PolygonId("polygon_2")); + + await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); + await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1, p2: p2))); + + final FakePlatformGoogleMap platformGoogleMap = + fakePlatformViewsController.lastCreatedView; + expect(platformGoogleMap.polygonsToAdd.length, 1); + + final Polygon addedPolygon = platformGoogleMap.polygonsToAdd.first; + expect(addedPolygon, equals(p2)); + + expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true); + + expect(platformGoogleMap.polygonsToChange.isEmpty, true); + }); + + testWidgets("Removing a polygon with points and hole", + (WidgetTester tester) async { + final Polygon p1 = _polygonWithPointsAndHole(PolygonId("polygon_1")); + + await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); + await tester.pumpWidget(_mapWithPolygons(null)); + + final FakePlatformGoogleMap platformGoogleMap = + fakePlatformViewsController.lastCreatedView; + expect(platformGoogleMap.polygonIdsToRemove.length, 1); + expect(platformGoogleMap.polygonIdsToRemove.first, equals(p1.polygonId)); + + expect(platformGoogleMap.polygonsToChange.isEmpty, true); + expect(platformGoogleMap.polygonsToAdd.isEmpty, true); + }); + + testWidgets("Updating a polygon by adding points and hole", + (WidgetTester tester) async { + final Polygon p1 = Polygon(polygonId: PolygonId("polygon_1")); + final Polygon p2 = _polygonWithPointsAndHole(PolygonId("polygon_1")); + + await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); + await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p2))); + + final FakePlatformGoogleMap platformGoogleMap = + fakePlatformViewsController.lastCreatedView; + expect(platformGoogleMap.polygonsToChange.length, 1); + expect(platformGoogleMap.polygonsToChange.first, equals(p2)); + + expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true); + expect(platformGoogleMap.polygonsToAdd.isEmpty, true); + }); + + testWidgets("Mutate a polygon with points and holes", + (WidgetTester tester) async { + final Polygon p1 = Polygon( + polygonId: PolygonId("polygon_1"), + points: _rectPoints(size: 1), + holes: [_rectPoints(size: 0.5)], + ); + await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); + + p1.points + ..clear() + ..addAll(_rectPoints(size: 2)); + p1.holes + ..clear() + ..addAll([_rectPoints(size: 1)]); + await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); + + final FakePlatformGoogleMap platformGoogleMap = + fakePlatformViewsController.lastCreatedView; + expect(platformGoogleMap.polygonsToChange.length, 1); + expect(platformGoogleMap.polygonsToChange.first, equals(p1)); + + expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true); + expect(platformGoogleMap.polygonsToAdd.isEmpty, true); + }); + + testWidgets("Multi Update polygons with points and hole", + (WidgetTester tester) async { + Polygon p1 = Polygon(polygonId: PolygonId("polygon_1")); + Polygon p2 = Polygon( + polygonId: PolygonId("polygon_2"), + points: _rectPoints(size: 2), + holes: [_rectPoints(size: 1)], + ); + final Set prev = _toSet(p1: p1, p2: p2); + p1 = Polygon(polygonId: PolygonId("polygon_1"), visible: false); + p2 = p2.copyWith( + pointsParam: _rectPoints(size: 5), + holesParam: [_rectPoints(size: 2)], + ); + final Set cur = _toSet(p1: p1, p2: p2); + + await tester.pumpWidget(_mapWithPolygons(prev)); + await tester.pumpWidget(_mapWithPolygons(cur)); + + final FakePlatformGoogleMap platformGoogleMap = + fakePlatformViewsController.lastCreatedView; + + expect(platformGoogleMap.polygonsToChange, cur); + expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true); + expect(platformGoogleMap.polygonsToAdd.isEmpty, true); + }); + + testWidgets("Multi Update polygons with points and hole", + (WidgetTester tester) async { + Polygon p2 = Polygon( + polygonId: PolygonId("polygon_2"), + points: _rectPoints(size: 2), + holes: [_rectPoints(size: 1)], + ); + final Polygon p3 = Polygon(polygonId: PolygonId("polygon_3")); + final Set prev = _toSet(p2: p2, p3: p3); + + // p1 is added, p2 is updated, p3 is removed. + final Polygon p1 = _polygonWithPointsAndHole(PolygonId("polygon_1")); + p2 = p2.copyWith( + pointsParam: _rectPoints(size: 5), + holesParam: [_rectPoints(size: 3)], + ); + final Set cur = _toSet(p1: p1, p2: p2); + + await tester.pumpWidget(_mapWithPolygons(prev)); + await tester.pumpWidget(_mapWithPolygons(cur)); + + final FakePlatformGoogleMap platformGoogleMap = + fakePlatformViewsController.lastCreatedView; + + expect(platformGoogleMap.polygonsToChange.length, 1); + expect(platformGoogleMap.polygonsToAdd.length, 1); + expect(platformGoogleMap.polygonIdsToRemove.length, 1); + + expect(platformGoogleMap.polygonsToChange.first, equals(p2)); + expect(platformGoogleMap.polygonsToAdd.first, equals(p1)); + expect(platformGoogleMap.polygonIdsToRemove.first, equals(p3.polygonId)); + }); + + testWidgets("Partial Update polygons with points and hole", + (WidgetTester tester) async { + final Polygon p1 = _polygonWithPointsAndHole(PolygonId("polygon_1")); + final Polygon p2 = Polygon(polygonId: PolygonId("polygon_2")); + Polygon p3 = Polygon( + polygonId: PolygonId("polygon_3"), + points: _rectPoints(size: 2), + holes: [_rectPoints(size: 1)], + ); + final Set prev = _toSet(p1: p1, p2: p2, p3: p3); + p3 = p3.copyWith( + pointsParam: _rectPoints(size: 5), + holesParam: [_rectPoints(size: 3)], + ); + final Set cur = _toSet(p1: p1, p2: p2, p3: p3); + + await tester.pumpWidget(_mapWithPolygons(prev)); + await tester.pumpWidget(_mapWithPolygons(cur)); + + final FakePlatformGoogleMap platformGoogleMap = + fakePlatformViewsController.lastCreatedView; + + expect(platformGoogleMap.polygonsToChange, _toSet(p3: p3)); + expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true); + expect(platformGoogleMap.polygonsToAdd.isEmpty, true); + }); } From edda73d0b876afc21c8d2d902f11ddba51a8f95f Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Wed, 13 Jan 2021 16:06:08 -0800 Subject: [PATCH 0036/1565] [file_selector_web] Add dummy ios directory. (#3416) This is required so the plugin is publishable. --- .../file_selector_web/CHANGELOG.md | 4 ++++ .../ios/file_selector_web.podspec | 21 +++++++++++++++++++ .../file_selector_web/pubspec.yaml | 2 +- 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 packages/file_selector/file_selector_web/ios/file_selector_web.podspec diff --git a/packages/file_selector/file_selector_web/CHANGELOG.md b/packages/file_selector/file_selector_web/CHANGELOG.md index cf87cfec36fd..619aa769d5f6 100644 --- a/packages/file_selector/file_selector_web/CHANGELOG.md +++ b/packages/file_selector/file_selector_web/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.7.0+1 + +- Add dummy `ios` dir, so flutter sdk can be lower than 1.20 + # 0.7.0 - Initial open-source release. diff --git a/packages/file_selector/file_selector_web/ios/file_selector_web.podspec b/packages/file_selector/file_selector_web/ios/file_selector_web.podspec new file mode 100644 index 000000000000..20656121029d --- /dev/null +++ b/packages/file_selector/file_selector_web/ios/file_selector_web.podspec @@ -0,0 +1,21 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# +Pod::Spec.new do |s| + s.name = 'file_selector_web' + s.version = '0.0.1' + s.summary = 'No-op implementation of file_selector_web web plugin to avoid build issues on iOS' + s.description = <<-DESC + temp fake file_selector_web plugin + DESC + s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/file_selector/file_selector_web' + s.license = { :file => '../LICENSE' } + s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.public_header_files = 'Classes/**/*.h' + s.dependency 'Flutter' + + s.ios.deployment_target = '8.0' + end + \ No newline at end of file diff --git a/packages/file_selector/file_selector_web/pubspec.yaml b/packages/file_selector/file_selector_web/pubspec.yaml index c8e0eef56276..a170d5f39607 100644 --- a/packages/file_selector/file_selector_web/pubspec.yaml +++ b/packages/file_selector/file_selector_web/pubspec.yaml @@ -1,7 +1,7 @@ name: file_selector_web description: Web platform implementation of file_selector homepage: https://github.com/flutter/plugins/tree/master/packages/file_selector/file_selector_web -version: 0.7.0 +version: 0.7.0+1 flutter: plugin: From 6d18db83f00f4861ffe485aba2d1f8aa08845ce6 Mon Sep 17 00:00:00 2001 From: Bodhi Mulders Date: Thu, 14 Jan 2021 06:45:47 +0100 Subject: [PATCH 0037/1565] [camera] Fix picture capture causing a crash on some Huawei devices. (#3414) --- packages/camera/camera/CHANGELOG.md | 4 ++ .../io/flutter/plugins/camera/Camera.java | 5 +- .../plugins/camera/PictureCaptureRequest.java | 43 +++++++++++++++- .../camera/PictureCaptureRequestTest.java | 51 +++++++++++++++++++ packages/camera/camera/pubspec.yaml | 2 +- 5 files changed, 102 insertions(+), 3 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 8525ad1e21d8..5fd62d2b716b 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.0+1 + +* Fixes picture captures causing a crash on some Huawei devices. + ## 0.7.0 * Added support for capture orientation locking on Android and iOS. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 10d58f5e8792..d5a5c5cfeb6b 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -458,17 +458,20 @@ public void onCaptureFailed( return; } String reason; + boolean fatalFailure = false; switch (failure.getReason()) { case CaptureFailure.REASON_ERROR: reason = "An error happened in the framework"; break; case CaptureFailure.REASON_FLUSHED: reason = "The capture has failed due to an abortCaptures() call"; + fatalFailure = true; break; default: reason = "Unknown reason"; } - pictureCaptureRequest.error("captureFailure", reason, null); + Log.w("Camera", "pictureCaptureCallback.onCaptureFailed(): " + reason); + if (fatalFailure) pictureCaptureRequest.error("captureFailure", reason, null); } private void processCapture(CaptureResult result) { diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java index 189f2f1490dc..396f782a2a08 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java @@ -4,6 +4,8 @@ package io.flutter.plugins.camera; +import android.os.Handler; +import android.os.Looper; import androidx.annotation.Nullable; import io.flutter.plugin.common.MethodChannel; @@ -19,17 +21,36 @@ enum State { error, } + private final Runnable timeoutCallback = + new Runnable() { + @Override + public void run() { + error("captureTimeout", "Picture capture request timed out", state.toString()); + } + }; + private final MethodChannel.Result result; + private final TimeoutHandler timeoutHandler; private State state; public PictureCaptureRequest(MethodChannel.Result result) { + this(result, new TimeoutHandler()); + } + + public PictureCaptureRequest(MethodChannel.Result result, TimeoutHandler timeoutHandler) { this.result = result; - state = State.idle; + this.state = State.idle; + this.timeoutHandler = timeoutHandler; } public void setState(State state) { if (isFinished()) throw new IllegalStateException("Request has already been finished"); this.state = state; + if (state != State.idle && state != State.finished && state != State.error) { + this.timeoutHandler.resetTimeout(timeoutCallback); + } else { + this.timeoutHandler.clearTimeout(timeoutCallback); + } } public State getState() { @@ -42,6 +63,7 @@ public boolean isFinished() { public void finish(String absolutePath) { if (isFinished()) throw new IllegalStateException("Request has already been finished"); + this.timeoutHandler.clearTimeout(timeoutCallback); result.success(absolutePath); state = State.finished; } @@ -49,7 +71,26 @@ public void finish(String absolutePath) { public void error( String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { if (isFinished()) throw new IllegalStateException("Request has already been finished"); + this.timeoutHandler.clearTimeout(timeoutCallback); result.error(errorCode, errorMessage, errorDetails); state = State.error; } + + static class TimeoutHandler { + private static final int REQUEST_TIMEOUT = 5000; + private final Handler handler; + + TimeoutHandler() { + this.handler = new Handler(Looper.getMainLooper()); + } + + public void resetTimeout(Runnable runnable) { + clearTimeout(runnable); + handler.postDelayed(runnable, REQUEST_TIMEOUT); + } + + public void clearTimeout(Runnable runnable) { + handler.removeCallbacks(runnable); + } + } } diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java index 3ede0b7abe3a..3252b3e111c4 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java @@ -7,7 +7,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import io.flutter.plugin.common.MethodChannel; @@ -38,6 +41,32 @@ public void setState_sets_state() { "State is awaitingPreCapture", req.getState(), PictureCaptureRequest.State.capturing); } + @Test + public void setState_resets_timeout() { + PictureCaptureRequest.TimeoutHandler mockTimeoutHandler = + mock(PictureCaptureRequest.TimeoutHandler.class); + PictureCaptureRequest req = new PictureCaptureRequest(null, mockTimeoutHandler); + req.setState(PictureCaptureRequest.State.focusing); + req.setState(PictureCaptureRequest.State.preCapture); + req.setState(PictureCaptureRequest.State.waitingPreCaptureReady); + req.setState(PictureCaptureRequest.State.capturing); + verify(mockTimeoutHandler, times(4)).resetTimeout(any()); + verify(mockTimeoutHandler, never()).clearTimeout(any()); + } + + @Test + public void setState_clears_timeout() { + PictureCaptureRequest.TimeoutHandler mockTimeoutHandler = + mock(PictureCaptureRequest.TimeoutHandler.class); + PictureCaptureRequest req = new PictureCaptureRequest(null, mockTimeoutHandler); + req.setState(PictureCaptureRequest.State.idle); + req.setState(PictureCaptureRequest.State.finished); + req = new PictureCaptureRequest(null, mockTimeoutHandler); + req.setState(PictureCaptureRequest.State.error); + verify(mockTimeoutHandler, never()).resetTimeout(any()); + verify(mockTimeoutHandler, times(3)).clearTimeout(any()); + } + @Test public void finish_sets_result_and_state() { // Setup @@ -50,6 +79,17 @@ public void finish_sets_result_and_state() { assertEquals("State is finished", req.getState(), PictureCaptureRequest.State.finished); } + @Test + public void finish_clears_timeout() { + PictureCaptureRequest.TimeoutHandler mockTimeoutHandler = + mock(PictureCaptureRequest.TimeoutHandler.class); + MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + PictureCaptureRequest req = new PictureCaptureRequest(mockResult, mockTimeoutHandler); + req.finish("/test/path"); + verify(mockTimeoutHandler, never()).resetTimeout(any()); + verify(mockTimeoutHandler).clearTimeout(any()); + } + @Test public void isFinished_is_true_When_state_is_finished_or_error() { // Setup @@ -90,6 +130,17 @@ public void error_sets_result_and_state() { assertEquals("State is error", req.getState(), PictureCaptureRequest.State.error); } + @Test + public void error_clears_timeout() { + PictureCaptureRequest.TimeoutHandler mockTimeoutHandler = + mock(PictureCaptureRequest.TimeoutHandler.class); + MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + PictureCaptureRequest req = new PictureCaptureRequest(mockResult, mockTimeoutHandler); + req.error("ERROR_CODE", "Error Message", null); + verify(mockTimeoutHandler, never()).resetTimeout(any()); + verify(mockTimeoutHandler).clearTimeout(any()); + } + @Test(expected = IllegalStateException.class) public void error_throws_When_already_finished() { // Setup diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index b0ebb9c16361..b406ce5ba64f 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.7.0 +version: 0.7.0+1 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From d0b7109f6b00a0eda03506fed2c74cc123ffc6f3 Mon Sep 17 00:00:00 2001 From: Bodhi Mulders Date: Thu, 14 Jan 2021 10:33:03 +0100 Subject: [PATCH 0038/1565] [camera] Fix initialization error in camera example on iOS (#3406) * Fix error on first camera initialize in example app * Improved error handling a bit & updated tests. * Updated pubspec and changelog Co-authored-by: Maurits van Beusekom --- packages/camera/camera/CHANGELOG.md | 4 + packages/camera/camera/example/lib/main.dart | 14 +- .../camera/lib/src/camera_controller.dart | 129 ++++---------- packages/camera/camera/pubspec.yaml | 2 +- .../camera/test/camera_image_stream_test.dart | 42 +++-- packages/camera/camera/test/camera_test.dart | 168 +++++++++++++----- 6 files changed, 195 insertions(+), 164 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 5fd62d2b716b..8d2c20108ed0 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.0+2 + +* Improved error feedback by differentiating between uninitialized and disposed camera controllers. + ## 0.7.0+1 * Fixes picture captures causing a crash on some Huawei devices. diff --git a/packages/camera/camera/example/lib/main.dart b/packages/camera/camera/example/lib/main.dart index 490cae6676d3..6244aa5a8e37 100644 --- a/packages/camera/camera/example/lib/main.dart +++ b/packages/camera/camera/example/lib/main.dart @@ -580,10 +580,16 @@ class _CameraExampleHomeState extends State try { await controller.initialize(); - _minAvailableExposureOffset = await controller.getMinExposureOffset(); - _maxAvailableExposureOffset = await controller.getMaxExposureOffset(); - _maxAvailableZoom = await controller.getMaxZoomLevel(); - _minAvailableZoom = await controller.getMinZoomLevel(); + await Future.wait([ + controller + .getMinExposureOffset() + .then((value) => _minAvailableExposureOffset = value), + controller + .getMaxExposureOffset() + .then((value) => _maxAvailableExposureOffset = value), + controller.getMaxZoomLevel().then((value) => _maxAvailableZoom = value), + controller.getMinZoomLevel().then((value) => _minAvailableZoom = value), + ]); } on CameraException catch (e) { _showCameraException(e); } diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index 807bec367256..80e83c867954 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -323,12 +323,7 @@ class CameraController extends ValueNotifier { /// /// Throws a [CameraException] if the capture fails. Future takePicture() async { - if (!value.isInitialized || _isDisposed) { - throw CameraException( - 'Uninitialized CameraController.', - 'takePicture was called on uninitialized CameraController', - ); - } + _throwIfNotInitialized("takePicture"); if (value.isTakingPicture) { throw CameraException( 'Previous capture has not returned yet.', @@ -366,13 +361,7 @@ class CameraController extends ValueNotifier { Future startImageStream(onLatestImageAvailable onAvailable) async { assert(defaultTargetPlatform == TargetPlatform.android || defaultTargetPlatform == TargetPlatform.iOS); - - if (!value.isInitialized || _isDisposed) { - throw CameraException( - 'Uninitialized CameraController', - 'startImageStream was called on uninitialized CameraController.', - ); - } + _throwIfNotInitialized("startImageStream"); if (value.isRecordingVideo) { throw CameraException( 'A video recording is already started.', @@ -412,13 +401,7 @@ class CameraController extends ValueNotifier { Future stopImageStream() async { assert(defaultTargetPlatform == TargetPlatform.android || defaultTargetPlatform == TargetPlatform.iOS); - - if (!value.isInitialized || _isDisposed) { - throw CameraException( - 'Uninitialized CameraController', - 'stopImageStream was called on uninitialized CameraController.', - ); - } + _throwIfNotInitialized("stopImageStream"); if (value.isRecordingVideo) { throw CameraException( 'A video recording is already started.', @@ -448,12 +431,7 @@ class CameraController extends ValueNotifier { /// The video is returned as a [XFile] after calling [stopVideoRecording]. /// Throws a [CameraException] if the capture fails. Future startVideoRecording() async { - if (!value.isInitialized || _isDisposed) { - throw CameraException( - 'Uninitialized CameraController', - 'startVideoRecording was called on uninitialized CameraController', - ); - } + _throwIfNotInitialized("startVideoRecording"); if (value.isRecordingVideo) { throw CameraException( 'A video recording is already started.', @@ -483,12 +461,7 @@ class CameraController extends ValueNotifier { /// /// Throws a [CameraException] if the capture failed. Future stopVideoRecording() async { - if (!value.isInitialized || _isDisposed) { - throw CameraException( - 'Uninitialized CameraController', - 'stopVideoRecording was called on uninitialized CameraController', - ); - } + _throwIfNotInitialized("stopVideoRecording"); if (!value.isRecordingVideo) { throw CameraException( 'No video is recording', @@ -511,12 +484,7 @@ class CameraController extends ValueNotifier { /// /// This feature is only available on iOS and Android sdk 24+. Future pauseVideoRecording() async { - if (!value.isInitialized || _isDisposed) { - throw CameraException( - 'Uninitialized CameraController', - 'pauseVideoRecording was called on uninitialized CameraController', - ); - } + _throwIfNotInitialized("pauseVideoRecording"); if (!value.isRecordingVideo) { throw CameraException( 'No video is recording', @@ -535,12 +503,7 @@ class CameraController extends ValueNotifier { /// /// This feature is only available on iOS and Android sdk 24+. Future resumeVideoRecording() async { - if (!value.isInitialized || _isDisposed) { - throw CameraException( - 'Uninitialized CameraController', - 'resumeVideoRecording was called on uninitialized CameraController', - ); - } + _throwIfNotInitialized("resumeVideoRecording"); if (!value.isRecordingVideo) { throw CameraException( 'No video is recording', @@ -557,12 +520,7 @@ class CameraController extends ValueNotifier { /// Returns a widget showing a live camera preview. Widget buildPreview() { - if (!value.isInitialized || _isDisposed) { - throw CameraException( - 'Uninitialized CameraController', - 'buildView() was called on uninitialized CameraController.', - ); - } + _throwIfNotInitialized("buildPreview"); try { return CameraPlatform.instance.buildPreview(_cameraId); } on PlatformException catch (e) { @@ -572,13 +530,7 @@ class CameraController extends ValueNotifier { /// Gets the maximum supported zoom level for the selected camera. Future getMaxZoomLevel() { - if (!value.isInitialized || _isDisposed) { - throw CameraException( - 'Uninitialized CameraController', - 'getMaxZoomLevel was called on uninitialized CameraController', - ); - } - + _throwIfNotInitialized("getMaxZoomLevel"); try { return CameraPlatform.instance.getMaxZoomLevel(_cameraId); } on PlatformException catch (e) { @@ -588,13 +540,7 @@ class CameraController extends ValueNotifier { /// Gets the minimum supported zoom level for the selected camera. Future getMinZoomLevel() { - if (!value.isInitialized || _isDisposed) { - throw CameraException( - 'Uninitialized CameraController', - 'getMinZoomLevel was called on uninitialized CameraController', - ); - } - + _throwIfNotInitialized("getMinZoomLevel"); try { return CameraPlatform.instance.getMinZoomLevel(_cameraId); } on PlatformException catch (e) { @@ -608,13 +554,7 @@ class CameraController extends ValueNotifier { /// zoom level returned by the `getMaxZoomLevel`. Throws an `CameraException` /// when an illegal zoom level is suplied. Future setZoomLevel(double zoom) { - if (!value.isInitialized || _isDisposed) { - throw CameraException( - 'Uninitialized CameraController', - 'setZoomLevel was called on uninitialized CameraController', - ); - } - + _throwIfNotInitialized("setZoomLevel"); try { return CameraPlatform.instance.setZoomLevel(_cameraId, zoom); } on PlatformException catch (e) { @@ -666,13 +606,7 @@ class CameraController extends ValueNotifier { /// Gets the minimum supported exposure offset for the selected camera in EV units. Future getMinExposureOffset() async { - if (!value.isInitialized || _isDisposed) { - throw CameraException( - 'Uninitialized CameraController', - 'getMinExposureOffset was called on uninitialized CameraController', - ); - } - + _throwIfNotInitialized("getMinExposureOffset"); try { return CameraPlatform.instance.getMinExposureOffset(_cameraId); } on PlatformException catch (e) { @@ -682,13 +616,7 @@ class CameraController extends ValueNotifier { /// Gets the maximum supported exposure offset for the selected camera in EV units. Future getMaxExposureOffset() async { - if (!value.isInitialized || _isDisposed) { - throw CameraException( - 'Uninitialized CameraController', - 'getMaxExposureOffset was called on uninitialized CameraController', - ); - } - + _throwIfNotInitialized("getMaxExposureOffset"); try { return CameraPlatform.instance.getMaxExposureOffset(_cameraId); } on PlatformException catch (e) { @@ -700,13 +628,7 @@ class CameraController extends ValueNotifier { /// /// Returns 0 when the camera supports using a free value without stepping. Future getExposureOffsetStepSize() async { - if (!value.isInitialized || _isDisposed) { - throw CameraException( - 'Uninitialized CameraController', - 'getExposureOffsetStepSize was called on uninitialized CameraController', - ); - } - + _throwIfNotInitialized("getExposureOffsetStepSize"); try { return CameraPlatform.instance.getExposureOffsetStepSize(_cameraId); } on PlatformException catch (e) { @@ -726,13 +648,7 @@ class CameraController extends ValueNotifier { /// /// Returns the (rounded) offset value that was set. Future setExposureOffset(double offset) async { - if (!value.isInitialized || _isDisposed) { - throw CameraException( - 'Uninitialized CameraController', - 'setExposureOffset was called on uninitialized CameraController', - ); - } - + _throwIfNotInitialized("setExposureOffset"); // Check if offset is in range List range = await Future.wait([getMinExposureOffset(), getMaxExposureOffset()]); @@ -834,4 +750,19 @@ class CameraController extends ValueNotifier { await CameraPlatform.instance.dispose(_cameraId); } } + + void _throwIfNotInitialized(String functionName) { + if (!value.isInitialized) { + throw CameraException( + 'Uninitialized CameraController', + '$functionName() was called on an uninitialized CameraController.', + ); + } + if (_isDisposed) { + throw CameraException( + 'Disposed CameraController', + '$functionName() was called on a disposed CameraController.', + ); + } + } } diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index b406ce5ba64f..2b6d163dfbeb 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.7.0+1 +version: 0.7.0+2 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: diff --git a/packages/camera/camera/test/camera_image_stream_test.dart b/packages/camera/camera/test/camera_image_stream_test.dart index be7047f2220f..57e3aeb36f3f 100644 --- a/packages/camera/camera/test/camera_image_stream_test.dart +++ b/packages/camera/camera/test/camera_image_stream_test.dart @@ -22,12 +22,21 @@ void main() { ResolutionPreset.max); expect( - () => cameraController.startImageStream((image) => null), - throwsA(isA().having( - (error) => error.description, - 'Uninitialized CameraController.', - 'startImageStream was called on uninitialized CameraController.', - ))); + () => cameraController.startImageStream((image) => null), + throwsA( + isA() + .having( + (error) => error.code, + 'code', + 'Uninitialized CameraController', + ) + .having( + (error) => error.description, + 'description', + 'startImageStream() was called on an uninitialized CameraController.', + ), + ), + ); }); test('startImageStream() throws $CameraException when recording videos', @@ -107,12 +116,21 @@ void main() { ResolutionPreset.max); expect( - cameraController.stopImageStream, - throwsA(isA().having( - (error) => error.description, - 'Uninitialized CameraController.', - 'stopImageStream was called on uninitialized CameraController.', - ))); + cameraController.stopImageStream, + throwsA( + isA() + .having( + (error) => error.code, + 'code', + 'Uninitialized CameraController', + ) + .having( + (error) => error.description, + 'description', + 'stopImageStream() was called on an uninitialized CameraController.', + ), + ), + ); }); test('stopImageStream() throws $CameraException when recording videos', diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index 2f53691217cb..d0b09fae1304 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -213,12 +213,21 @@ void main() { sensorOrientation: 90), ResolutionPreset.max); expect( - cameraController.takePicture(), - throwsA(isA().having( - (error) => error.description, - 'Uninitialized CameraController.', - 'takePicture was called on uninitialized CameraController', - ))); + cameraController.takePicture(), + throwsA( + isA() + .having( + (error) => error.code, + 'code', + 'Uninitialized CameraController', + ) + .having( + (error) => error.description, + 'description', + 'takePicture() was called on an uninitialized CameraController.', + ), + ), + ); }); test('takePicture() throws $CameraException when takePicture is true', @@ -286,12 +295,21 @@ void main() { ResolutionPreset.max); expect( - cameraController.startVideoRecording(), - throwsA(isA().having( - (error) => error.description, - 'Uninitialized CameraController', - 'startVideoRecording was called on uninitialized CameraController', - ))); + cameraController.startVideoRecording(), + throwsA( + isA() + .having( + (error) => error.code, + 'code', + 'Uninitialized CameraController', + ) + .having( + (error) => error.description, + 'description', + 'startVideoRecording() was called on an uninitialized CameraController.', + ), + ), + ); }); test('startVideoRecording() throws $CameraException when recording videos', () async { @@ -350,12 +368,21 @@ void main() { ResolutionPreset.max); expect( - cameraController.getMaxZoomLevel, - throwsA(isA().having( - (error) => error.description, - 'Uninitialized CameraController', - 'getMaxZoomLevel was called on uninitialized CameraController', - ))); + cameraController.getMaxZoomLevel, + throwsA( + isA() + .having( + (error) => error.code, + 'code', + 'Uninitialized CameraController', + ) + .having( + (error) => error.description, + 'description', + 'getMaxZoomLevel() was called on an uninitialized CameraController.', + ), + ), + ); }); test('getMaxZoomLevel() throws $CameraException when disposed', () async { @@ -370,12 +397,21 @@ void main() { await cameraController.dispose(); expect( - cameraController.getMaxZoomLevel, - throwsA(isA().having( - (error) => error.description, - 'Uninitialized CameraController', - 'getMaxZoomLevel was called on uninitialized CameraController', - ))); + cameraController.getMaxZoomLevel, + throwsA( + isA() + .having( + (error) => error.code, + 'code', + 'Disposed CameraController', + ) + .having( + (error) => error.description, + 'description', + 'getMaxZoomLevel() was called on a disposed CameraController.', + ), + ), + ); }); test( @@ -432,12 +468,21 @@ void main() { ResolutionPreset.max); expect( - cameraController.getMinZoomLevel, - throwsA(isA().having( - (error) => error.description, - 'Uninitialized CameraController', - 'getMinZoomLevel was called on uninitialized CameraController', - ))); + cameraController.getMinZoomLevel, + throwsA( + isA() + .having( + (error) => error.code, + 'code', + 'Uninitialized CameraController', + ) + .having( + (error) => error.description, + 'description', + 'getMinZoomLevel() was called on an uninitialized CameraController.', + ), + ), + ); }); test('getMinZoomLevel() throws $CameraException when disposed', () async { @@ -452,12 +497,21 @@ void main() { await cameraController.dispose(); expect( - cameraController.getMinZoomLevel, - throwsA(isA().having( - (error) => error.description, - 'Uninitialized CameraController', - 'getMinZoomLevel was called on uninitialized CameraController', - ))); + cameraController.getMinZoomLevel, + throwsA( + isA() + .having( + (error) => error.code, + 'code', + 'Disposed CameraController', + ) + .having( + (error) => error.description, + 'description', + 'getMinZoomLevel() was called on a disposed CameraController.', + ), + ), + ); }); test( @@ -513,12 +567,21 @@ void main() { ResolutionPreset.max); expect( - () => cameraController.setZoomLevel(42.0), - throwsA(isA().having( - (error) => error.description, - 'Uninitialized CameraController', - 'setZoomLevel was called on uninitialized CameraController', - ))); + () => cameraController.setZoomLevel(42.0), + throwsA( + isA() + .having( + (error) => error.code, + 'code', + 'Uninitialized CameraController', + ) + .having( + (error) => error.description, + 'description', + 'setZoomLevel() was called on an uninitialized CameraController.', + ), + ), + ); }); test('setZoomLevel() throws $CameraException when disposed', () async { @@ -533,12 +596,21 @@ void main() { await cameraController.dispose(); expect( - () => cameraController.setZoomLevel(42.0), - throwsA(isA().having( - (error) => error.description, - 'Uninitialized CameraController', - 'setZoomLevel was called on uninitialized CameraController', - ))); + () => cameraController.setZoomLevel(42.0), + throwsA( + isA() + .having( + (error) => error.code, + 'code', + 'Disposed CameraController', + ) + .having( + (error) => error.description, + 'description', + 'setZoomLevel() was called on a disposed CameraController.', + ), + ), + ); }); test( From 980b674cb4020c1927917426211a87e275346d5e Mon Sep 17 00:00:00 2001 From: najeira Date: Thu, 14 Jan 2021 20:29:03 +0900 Subject: [PATCH 0039/1565] [camera] Fixes crash with using inner camera on some Android devices. (#3419) --- packages/camera/camera/CHANGELOG.md | 4 ++++ .../src/main/java/io/flutter/plugins/camera/Camera.java | 3 ++- packages/camera/camera/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 8d2c20108ed0..6ce8737862f4 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.0+3 + +* Fixes crash with using inner camera on some Android devices. + ## 0.7.0+2 * Improved error feedback by differentiating between uninitialized and disposed camera controllers. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index d5a5c5cfeb6b..5dba68eed723 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -216,7 +216,6 @@ public void open(String imageFormatGroup) throws CameraAccessException { public void onOpened(@NonNull CameraDevice device) { cameraDevice = device; try { - cameraRegions = new CameraRegions(getRegionBoundaries()); startPreview(); dartMessenger.sendCameraInitializedEvent( previewSize.getWidth(), @@ -300,6 +299,8 @@ private void createCaptureSession( } } + cameraRegions = new CameraRegions(getRegionBoundaries()); + // Prepare the callback CameraCaptureSession.StateCallback callback = new CameraCaptureSession.StateCallback() { diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 2b6d163dfbeb..cebbb334c8f2 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.7.0+2 +version: 0.7.0+3 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From 5916f55664e1772a4c3f0c02c5c71fc11e491b76 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 14 Jan 2021 18:57:35 +0100 Subject: [PATCH 0040/1565] [camera] Copy zoom settings from preview to final capture builder on Android (#3413) * Copy SCALER_CROP_REGION from preview to final capture builder * Update version number * Fix formatting --- packages/camera/camera/CHANGELOG.md | 4 ++++ .../src/main/java/io/flutter/plugins/camera/Camera.java | 4 ++++ packages/camera/camera/pubspec.yaml | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 6ce8737862f4..972ca5a31503 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.0+4 + +* Make sure the configured zoom scale is copied over to the final capture builder on Android. Fixes the issue where the preview is zoomed but the final picture is not. + ## 0.7.0+3 * Fixes crash with using inner camera on some Android devices. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 5dba68eed723..1b6cce95d08c 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -543,11 +543,15 @@ private void runPictureCapture() { final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); captureBuilder.addTarget(pictureImageReader.getSurface()); + captureBuilder.set( + CaptureRequest.SCALER_CROP_REGION, + captureRequestBuilder.get(CaptureRequest.SCALER_CROP_REGION)); captureBuilder.set( CaptureRequest.JPEG_ORIENTATION, lockedCaptureOrientation == null ? deviceOrientationListener.getMediaOrientation() : deviceOrientationListener.getMediaOrientation(lockedCaptureOrientation)); + switch (flashMode) { case off: captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index cebbb334c8f2..5ac4b57a15ef 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.7.0+3 +version: 0.7.0+4 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From 1e90b58847c12252f6144160f975445804f1d05c Mon Sep 17 00:00:00 2001 From: klaes-ashford <36758008+klaes-ashford@users.noreply.github.com> Date: Fri, 15 Jan 2021 01:39:09 +0530 Subject: [PATCH 0041/1565] fix to properly place polyline at initial camera position in example app (#2941) --- packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md | 4 ++++ .../google_maps_flutter/example/lib/place_polyline.dart | 4 ++-- packages/google_maps_flutter/google_maps_flutter/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index 6dcb967f9cb4..3b6db09ea10b 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.1 + +* Fix in example app to properly place polyline at initial camera position. + ## 1.1.0 * Add support for holes in Polygons. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart index 65201d5d1839..fe22603853bc 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart @@ -31,7 +31,7 @@ class PlacePolylineBodyState extends State { GoogleMapController controller; Map polylines = {}; - int _polylineIdCounter = 1; + int _polylineIdCounter = 0; PolylineId selectedPolyline; // Values when toggling polyline color @@ -215,7 +215,7 @@ class PlacePolylineBodyState extends State { height: 300.0, child: GoogleMap( initialCameraPosition: const CameraPosition( - target: LatLng(52.4478, -3.5402), + target: LatLng(53.1721, -3.5402), zoom: 7.0, ), polylines: Set.of(polylines.values), diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index c07d1899eba8..ef3a06f5862c 100644 --- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: google_maps_flutter description: A Flutter plugin for integrating Google Maps in iOS and Android applications. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter -version: 1.1.0 +version: 1.1.1 dependencies: flutter: From 831344490984b1feec007afc9c8595d80b6c13f4 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Fri, 15 Jan 2021 00:00:49 +0100 Subject: [PATCH 0042/1565] [camera] Fixes crash when taking a picture on iOS devices without flash (#3411) --- packages/camera/camera/CHANGELOG.md | 4 ++++ packages/camera/camera/ios/Classes/CameraPlugin.m | 4 ++-- packages/camera/camera/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 972ca5a31503..66398996e053 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.0+5 + +* Fixes crash when taking a picture on iOS devices without flash. + ## 0.7.0+4 * Make sure the configured zoom scale is copied over to the final capture builder on Android. Fixes the issue where the preview is zoomed but the final picture is not. diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index 40d93fde7af6..d97ce88a58d8 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -365,12 +365,12 @@ - (instancetype)initWithCameraName:(NSString *)cameraName _enableAudio = enableAudio; _dispatchQueue = dispatchQueue; _captureSession = [[AVCaptureSession alloc] init]; - _flashMode = FlashModeAuto; + _captureDevice = [AVCaptureDevice deviceWithUniqueID:cameraName]; + _flashMode = _captureDevice.hasFlash ? FlashModeAuto : FlashModeOff; _exposureMode = ExposureModeAuto; _focusMode = FocusModeAuto; _lockedCaptureOrientation = UIDeviceOrientationUnknown; - _captureDevice = [AVCaptureDevice deviceWithUniqueID:cameraName]; NSError *localError = nil; _captureVideoInput = [AVCaptureDeviceInput deviceInputWithDevice:_captureDevice error:&localError]; diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 5ac4b57a15ef..406ff94ab1b9 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.7.0+4 +version: 0.7.0+5 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From cc234f6fddcef124f49a26c05351b1de333329f5 Mon Sep 17 00:00:00 2001 From: Juanjo Tugores Date: Thu, 14 Jan 2021 19:59:58 -0600 Subject: [PATCH 0043/1565] [file_selector_platform_interface] Bump the cross_file version (#3422) --- .../file_selector_platform_interface/CHANGELOG.md | 4 ++++ .../file_selector_platform_interface/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/file_selector/file_selector_platform_interface/CHANGELOG.md b/packages/file_selector/file_selector_platform_interface/CHANGELOG.md index 0d6d6d08c298..aafe4db278d8 100644 --- a/packages/file_selector/file_selector_platform_interface/CHANGELOG.md +++ b/packages/file_selector/file_selector_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.3+1 + +* Bump the [cross_file](https://pub.dev/packages/cross_file) package version. + ## 1.0.3 * Update Flutter SDK constraint. diff --git a/packages/file_selector/file_selector_platform_interface/pubspec.yaml b/packages/file_selector/file_selector_platform_interface/pubspec.yaml index 2d0b7c954ece..f1d0038a5062 100644 --- a/packages/file_selector/file_selector_platform_interface/pubspec.yaml +++ b/packages/file_selector/file_selector_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the file_selector plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/file_selector/file_selector_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.0.3 +version: 1.0.3+1 dependencies: flutter: @@ -11,7 +11,7 @@ dependencies: meta: ^1.0.5 http: ^0.12.0+1 plugin_platform_interface: ^1.0.1 - cross_file: ^0.1.0 + cross_file: ^0.2.0 dev_dependencies: test: ^1.15.0 From eccc3cd6440210c2fdec03b06d57f94ae454d479 Mon Sep 17 00:00:00 2001 From: Kenneth Jones Date: Thu, 14 Jan 2021 23:29:02 -0600 Subject: [PATCH 0044/1565] [local_auth] Allow device authentication (pin/pattern/passcode) (#2489) --- .../android/gradle.properties | 1 - packages/local_auth/CHANGELOG.md | 9 + packages/local_auth/README.md | 36 +- packages/local_auth/android/build.gradle | 2 +- .../android/src/main/AndroidManifest.xml | 2 + .../localauth/AuthenticationHelper.java | 54 +-- .../plugins/localauth/LocalAuthPlugin.java | 343 +++++++++++++----- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../local_auth/example/android/build.gradle | 2 +- .../example/android/gradle.properties | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 4 +- .../example/android/settings_aar.gradle | 1 + packages/local_auth/example/lib/main.dart | 144 ++++++-- .../integration_test/local_auth_test.dart | 5 +- .../ios/Classes/FLTLocalAuthPlugin.m | 54 ++- packages/local_auth/lib/auth_strings.dart | 84 +++-- packages/local_auth/lib/error_codes.dart | 2 +- packages/local_auth/lib/local_auth.dart | 63 +++- packages/local_auth/pubspec.yaml | 4 +- packages/local_auth/test/local_auth_test.dart | 178 ++++++--- 20 files changed, 727 insertions(+), 265 deletions(-) create mode 100644 packages/local_auth/example/android/settings_aar.gradle diff --git a/packages/integration_test/android/gradle.properties b/packages/integration_test/android/gradle.properties index 2bd6f4fda009..8bd86f680510 100644 --- a/packages/integration_test/android/gradle.properties +++ b/packages/integration_test/android/gradle.properties @@ -1,2 +1 @@ org.gradle.jvmargs=-Xmx1536M - diff --git a/packages/local_auth/CHANGELOG.md b/packages/local_auth/CHANGELOG.md index b27ec83d41a7..8bb043f52d8f 100644 --- a/packages/local_auth/CHANGELOG.md +++ b/packages/local_auth/CHANGELOG.md @@ -1,3 +1,12 @@ +## 1.1.0-nullsafety + +* Allow pin, passcode, and pattern authentication with `authenticate` method +* **Breaking change**. Parameter names refactored to use the generic `biometric` prefix in place of `fingerprint` in the `AndroidAuthMessages` class + * `fingerprintHint` is now `biometricHint` + * `fingerprintNotRecognized`is now `biometricNotRecognized` + * `fingerprintSuccess`is now `biometricSuccess` + * `fingerprintRequiredTitle` is now `biometricRequiredTitle` + ## 1.0.0-nullsafety.3 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. diff --git a/packages/local_auth/README.md b/packages/local_auth/README.md index 516561be4230..80820d759fec 100644 --- a/packages/local_auth/README.md +++ b/packages/local_auth/README.md @@ -23,8 +23,8 @@ bool canCheckBiometrics = Currently the following biometric types are implemented: -* BiometricType.face -* BiometricType.fingerprint +- BiometricType.face +- BiometricType.fingerprint To get a list of enrolled biometrics, call getAvailableBiometrics: @@ -44,10 +44,10 @@ if (Platform.isIOS) { We have default dialogs with an 'OK' button to show authentication error messages for the following 2 cases: -1. Passcode/PIN/Pattern Not Set. The user has not yet configured a passcode on - iOS or PIN/pattern on Android. -2. Touch ID/Fingerprint Not Enrolled. The user has not enrolled any - fingerprints on the device. +1. Passcode/PIN/Pattern Not Set. The user has not yet configured a passcode on + iOS or PIN/pattern on Android. +2. Touch ID/Fingerprint Not Enrolled. The user has not enrolled any + fingerprints on the device. Which means, if there's no fingerprint on the user's device, a dialog with instructions will pop up to let the user set up fingerprint. If the user clicks @@ -55,20 +55,33 @@ instructions will pop up to let the user set up fingerprint. If the user clicks Use the exported APIs to trigger local authentication with default dialogs: +The `authenticate()` method uses biometric authentication, but also allows +users to use pin, pattern, or passcode. + ```dart var localAuth = LocalAuthentication(); bool didAuthenticate = - await localAuth.authenticateWithBiometrics( + await localAuth.authenticate( localizedReason: 'Please authenticate to show account balance'); ``` +To authenticate using biometric authentication only, set `biometricOnly` to `true`. + +```dart +var localAuth = LocalAuthentication(); +bool didAuthenticate = + await localAuth.authenticate( + localizedReason: 'Please authenticate to show account balance', + biometricOnly: true); +``` + If you don't want to use the default dialogs, call this API with 'useErrorDialogs = false'. In this case, it will throw the error message back and you need to handle them in your dart code: ```dart bool didAuthenticate = - await localAuth.authenticateWithBiometrics( + await localAuth.authenticate( localizedReason: 'Please authenticate to show account balance', useErrorDialogs: false); ``` @@ -84,7 +97,7 @@ const iosStrings = const IOSAuthMessages( goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID'); -await localAuth.authenticateWithBiometrics( +await localAuth.authenticate( localizedReason: 'Please authenticate to show account balance', useErrorDialogs: false, iOSAuthStrings: iosStrings); @@ -112,7 +125,7 @@ import 'package:flutter/services.dart'; import 'package:local_auth/error_codes.dart' as auth_error; try { - bool didAuthenticate = await local_auth.authenticateWithBiometrics( + bool didAuthenticate = await local_auth.authenticate( localizedReason: 'Please authenticate to show account balance'); } on PlatformException catch (e) { if (e.code == auth_error.notAvailable) { @@ -134,7 +147,6 @@ you need to also add: to your Info.plist file. Failure to do so results in a dialog that tells the user your app has not been updated to use TouchID. - ## Android Integration Note that local_auth plugin requires the use of a FragmentActivity as @@ -191,7 +203,7 @@ Update your project's `AndroidManifest.xml` file to include the On Android, you can check only for existence of fingerprint hardware prior to API 29 (Android Q). Therefore, if you would like to support other biometrics types (such as face scanning) and you want to support SDKs lower than Q, -*do not* call `getAvailableBiometrics`. Simply call `authenticateWithBiometrics`. +_do not_ call `getAvailableBiometrics`. Simply call `authenticate` with `biometricOnly: true`. This will return an error if there was no hardware available. ## Sticky Auth diff --git a/packages/local_auth/android/build.gradle b/packages/local_auth/android/build.gradle index 0fc603c36867..ae8e6f2828a2 100644 --- a/packages/local_auth/android/build.gradle +++ b/packages/local_auth/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.3.0' + classpath 'com.android.tools.build:gradle:4.1.1' } } diff --git a/packages/local_auth/android/src/main/AndroidManifest.xml b/packages/local_auth/android/src/main/AndroidManifest.xml index b7da0caab6da..cb6cb985a986 100644 --- a/packages/local_auth/android/src/main/AndroidManifest.xml +++ b/packages/local_auth/android/src/main/AndroidManifest.xml @@ -1,3 +1,5 @@ + + diff --git a/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java b/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java index e907cc43f2b4..096c7efd6d3d 100644 --- a/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java +++ b/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java @@ -29,7 +29,7 @@ import java.util.concurrent.Executor; /** - * Authenticates the user with fingerprint and sends corresponding response back to Flutter. + * Authenticates the user with biometrics and sends corresponding response back to Flutter. * *

One instance per call is generated to ensure readable separation of executable paths across * method calls. @@ -37,10 +37,8 @@ @SuppressWarnings("deprecation") class AuthenticationHelper extends BiometricPrompt.AuthenticationCallback implements Application.ActivityLifecycleCallbacks, DefaultLifecycleObserver { - /** The callback that handles the result of this authentication process. */ interface AuthCompletionHandler { - /** Called when authentication was successful. */ void onSuccess(); @@ -75,24 +73,32 @@ interface AuthCompletionHandler { Lifecycle lifecycle, FragmentActivity activity, MethodCall call, - AuthCompletionHandler completionHandler) { + AuthCompletionHandler completionHandler, + boolean allowCredentials) { this.lifecycle = lifecycle; this.activity = activity; this.completionHandler = completionHandler; this.call = call; this.isAuthSticky = call.argument("stickyAuth"); this.uiThreadExecutor = new UiThreadExecutor(); - this.promptInfo = + + BiometricPrompt.PromptInfo.Builder promptBuilder = new BiometricPrompt.PromptInfo.Builder() .setDescription((String) call.argument("localizedReason")) .setTitle((String) call.argument("signInTitle")) - .setSubtitle((String) call.argument("fingerprintHint")) - .setNegativeButtonText((String) call.argument("cancelButton")) + .setSubtitle((String) call.argument("biometricHint")) .setConfirmationRequired((Boolean) call.argument("sensitiveTransaction")) - .build(); + .setConfirmationRequired((Boolean) call.argument("sensitiveTransaction")); + + if (allowCredentials) { + promptBuilder.setDeviceCredentialAllowed(true); + } else { + promptBuilder.setNegativeButtonText((String) call.argument("cancelButton")); + } + this.promptInfo = promptBuilder.build(); } - /** Start the fingerprint listener. */ + /** Start the biometric listener. */ void authenticate() { if (lifecycle != null) { lifecycle.addObserver(this); @@ -103,7 +109,7 @@ void authenticate() { biometricPrompt.authenticate(promptInfo); } - /** Cancels the fingerprint authentication. */ + /** Cancels the biometric authentication. */ void stopAuthentication() { if (biometricPrompt != null) { biometricPrompt.cancelAuthentication(); @@ -111,7 +117,7 @@ void stopAuthentication() { } } - /** Stops the fingerprint listener. */ + /** Stops the biometric listener. */ private void stop() { if (lifecycle != null) { lifecycle.removeObserver(this); @@ -125,21 +131,27 @@ private void stop() { public void onAuthenticationError(int errorCode, CharSequence errString) { switch (errorCode) { case BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL: - completionHandler.onError( - "PasscodeNotSet", - "Phone not secured by PIN, pattern or password, or SIM is currently locked."); - break; + if (call.argument("useErrorDialogs")) { + showGoToSettingsDialog( + (String) call.argument("deviceCredentialsRequired"), + (String) call.argument("deviceCredentialsSetupDescription")); + return; + } + completionHandler.onError("NotAvailable", "Security credentials not available."); case BiometricPrompt.ERROR_NO_SPACE: case BiometricPrompt.ERROR_NO_BIOMETRICS: + if (promptInfo.isDeviceCredentialAllowed()) return; if (call.argument("useErrorDialogs")) { - showGoToSettingsDialog(); + showGoToSettingsDialog( + (String) call.argument("biometricRequired"), + (String) call.argument("goToSettingDescription")); return; } completionHandler.onError("NotEnrolled", "No Biometrics enrolled on this device."); break; case BiometricPrompt.ERROR_HW_UNAVAILABLE: case BiometricPrompt.ERROR_HW_NOT_PRESENT: - completionHandler.onError("NotAvailable", "Biometrics is not available on this device."); + completionHandler.onError("NotAvailable", "Security credentials not available."); break; case BiometricPrompt.ERROR_LOCKOUT: completionHandler.onError( @@ -176,7 +188,7 @@ public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult resul public void onAuthenticationFailed() {} /** - * If the activity is paused, we keep track because fingerprint dialog simply returns "User + * If the activity is paused, we keep track because biometric dialog simply returns "User * cancelled" when the activity is paused. */ @Override @@ -215,12 +227,12 @@ public void onResume(@NonNull LifecycleOwner owner) { // Suppress inflateParams lint because dialogs do not need to attach to a parent view. @SuppressLint("InflateParams") - private void showGoToSettingsDialog() { + private void showGoToSettingsDialog(String title, String descriptionText) { View view = LayoutInflater.from(activity).inflate(R.layout.go_to_setting, null, false); TextView message = (TextView) view.findViewById(R.id.fingerprint_required); TextView description = (TextView) view.findViewById(R.id.go_to_setting_description); - message.setText((String) call.argument("fingerprintRequired")); - description.setText((String) call.argument("goToSettingDescription")); + message.setText(title); + description.setText(descriptionText); Context context = new ContextThemeWrapper(activity, R.style.AlertDialogCustom); OnClickListener goToSettingHandler = new OnClickListener() { diff --git a/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java b/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java index 0f93f40e947a..f4c6c168f54d 100644 --- a/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java +++ b/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java @@ -4,9 +4,18 @@ package io.flutter.plugins.localauth; +import static android.app.Activity.RESULT_OK; +import static android.content.Context.KEYGUARD_SERVICE; + import android.app.Activity; +import android.app.KeyguardManager; +import android.content.Context; +import android.content.Intent; import android.content.pm.PackageManager; +import android.hardware.fingerprint.FingerprintManager; import android.os.Build; +import androidx.annotation.NonNull; +import androidx.biometric.BiometricManager; import androidx.fragment.app.FragmentActivity; import androidx.lifecycle.Lifecycle; import io.flutter.embedding.engine.plugins.FlutterPlugin; @@ -17,6 +26,8 @@ import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; +import io.flutter.plugin.common.PluginRegistry; +import io.flutter.plugin.common.PluginRegistry.Registrar; import io.flutter.plugins.localauth.AuthenticationHelper.AuthCompletionHandler; import java.util.ArrayList; import java.util.concurrent.atomic.AtomicBoolean; @@ -29,14 +40,33 @@ @SuppressWarnings("deprecation") public class LocalAuthPlugin implements MethodCallHandler, FlutterPlugin, ActivityAware { private static final String CHANNEL_NAME = "plugins.flutter.io/local_auth"; - + private static final int LOCK_REQUEST_CODE = 221; private Activity activity; private final AtomicBoolean authInProgress = new AtomicBoolean(false); - private AuthenticationHelper authenticationHelper; + private AuthenticationHelper authHelper; // These are null when not using v2 embedding. private MethodChannel channel; private Lifecycle lifecycle; + private BiometricManager biometricManager; + private FingerprintManager fingerprintManager; + private KeyguardManager keyguardManager; + private Result lockRequestResult; + private final PluginRegistry.ActivityResultListener resultListener = + new PluginRegistry.ActivityResultListener() { + @Override + public boolean onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == LOCK_REQUEST_CODE) { + if (resultCode == RESULT_OK && lockRequestResult != null) { + authenticateSuccess(lockRequestResult); + } else { + authenticateFail(lockRequestResult); + } + lockRequestResult = null; + } + return false; + } + }; /** * Registers a plugin with the v1 embedding api {@code io.flutter.plugin.common}. @@ -49,13 +79,12 @@ public class LocalAuthPlugin implements MethodCallHandler, FlutterPlugin, Activi * io.flutter.plugin.common.BinaryMessenger}. */ @SuppressWarnings("deprecation") - public static void registerWith(io.flutter.plugin.common.PluginRegistry.Registrar registrar) { + public static void registerWith(Registrar registrar) { final MethodChannel channel = new MethodChannel(registrar.messenger(), CHANNEL_NAME); - channel.setMethodCallHandler(new LocalAuthPlugin(registrar.activity())); - } - - private LocalAuthPlugin(Activity activity) { - this.activity = activity; + final LocalAuthPlugin plugin = new LocalAuthPlugin(); + plugin.activity = registrar.activity(); + channel.setMethodCallHandler(plugin); + registrar.addActivityResultListener(plugin.resultListener); } /** @@ -66,118 +95,241 @@ private LocalAuthPlugin(Activity activity) { public LocalAuthPlugin() {} @Override - public void onMethodCall(MethodCall call, final Result result) { - if (call.method.equals("authenticateWithBiometrics")) { - if (authInProgress.get()) { - // Apps should not invoke another authentication request while one is in progress, - // so we classify this as an error condition. If we ever find a legitimate use case for - // this, we can try to cancel the ongoing auth and start a new one but for now, not worth - // the complexity. - result.error("auth_in_progress", "Authentication in progress", null); - return; - } + public void onMethodCall(MethodCall call, @NonNull final Result result) { + switch (call.method) { + case "authenticate": + authenticate(call, result); + break; + case "getAvailableBiometrics": + getAvailableBiometrics(result); + break; + case "isDeviceSupported": + isDeviceSupported(result); + break; + case "stopAuthentication": + stopAuthentication(result); + break; + default: + result.notImplemented(); + break; + } + } - if (activity == null || activity.isFinishing()) { - result.error("no_activity", "local_auth plugin requires a foreground activity", null); - return; - } + /* + * Starts authentication process + */ + private void authenticate(MethodCall call, final Result result) { + if (authInProgress.get()) { + result.error("auth_in_progress", "Authentication in progress", null); + return; + } - if (!(activity instanceof FragmentActivity)) { - result.error( - "no_fragment_activity", - "local_auth plugin requires activity to be a FragmentActivity.", - null); - return; - } - authInProgress.set(true); - authenticationHelper = - new AuthenticationHelper( - lifecycle, - (FragmentActivity) activity, - call, - new AuthCompletionHandler() { - @Override - public void onSuccess() { - if (authInProgress.compareAndSet(true, false)) { - result.success(true); - } - } - - @Override - public void onFailure() { - if (authInProgress.compareAndSet(true, false)) { - result.success(false); - } - } - - @Override - public void onError(String code, String error) { - if (authInProgress.compareAndSet(true, false)) { - result.error(code, error, null); - } - } - }); - authenticationHelper.authenticate(); - } else if (call.method.equals("getAvailableBiometrics")) { - try { - if (activity == null || activity.isFinishing()) { - result.error("no_activity", "local_auth plugin requires a foreground activity", null); - return; - } - ArrayList biometrics = new ArrayList(); - PackageManager packageManager = activity.getPackageManager(); - if (Build.VERSION.SDK_INT >= 23) { - if (packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) { - biometrics.add("fingerprint"); + if (activity == null || activity.isFinishing()) { + result.error("no_activity", "local_auth plugin requires a foreground activity", null); + return; + } + + if (!(activity instanceof FragmentActivity)) { + result.error( + "no_fragment_activity", + "local_auth plugin requires activity to be a FragmentActivity.", + null); + return; + } + + if (!isDeviceSupported()) { + authInProgress.set(false); + result.error("NotAvailable", "Required security features not enabled", null); + return; + } + + authInProgress.set(true); + AuthCompletionHandler completionHandler = + new AuthCompletionHandler() { + @Override + public void onSuccess() { + authenticateSuccess(result); } - } - if (Build.VERSION.SDK_INT >= 29) { - if (packageManager.hasSystemFeature(PackageManager.FEATURE_FACE)) { - biometrics.add("face"); + + @Override + public void onFailure() { + authenticateFail(result); } - if (packageManager.hasSystemFeature(PackageManager.FEATURE_IRIS)) { - biometrics.add("iris"); + + @Override + public void onError(String code, String error) { + if (authInProgress.compareAndSet(true, false)) { + result.error(code, error, null); + } } + }; + + // if is biometricOnly try biometric prompt - might not work + boolean isBiometricOnly = call.argument("biometricOnly"); + if (isBiometricOnly) { + if (!canAuthenticateWithBiometrics()) { + if (!hasBiometricHardware()) { + completionHandler.onError("NoHardware", "No biometric hardware found"); } - result.success(biometrics); - } catch (Exception e) { - result.error("no_biometrics_available", e.getMessage(), null); + completionHandler.onError("NotEnrolled", "No biometrics enrolled on this device."); + return; } - } else if (call.method.equals(("stopAuthentication"))) { - stopAuthentication(result); - } else { - result.notImplemented(); + authHelper = + new AuthenticationHelper( + lifecycle, (FragmentActivity) activity, call, completionHandler, false); + authHelper.authenticate(); + return; + } + + // API 29 and above + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + authHelper = + new AuthenticationHelper( + lifecycle, (FragmentActivity) activity, call, completionHandler, true); + authHelper.authenticate(); + return; + } + + // API 23 - 28 with fingerprint + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && fingerprintManager != null) { + if (fingerprintManager.hasEnrolledFingerprints()) { + authHelper = + new AuthenticationHelper( + lifecycle, (FragmentActivity) activity, call, completionHandler, false); + authHelper.authenticate(); + return; + } + } + + // API 23 or higher with device credentials + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M + && keyguardManager != null + && keyguardManager.isDeviceSecure()) { + String title = call.argument("signInTitle"); + String reason = call.argument("localizedReason"); + Intent authIntent = keyguardManager.createConfirmDeviceCredentialIntent(title, reason); + + // save result for async response + lockRequestResult = result; + activity.startActivityForResult(authIntent, LOCK_REQUEST_CODE); + return; + } + + // Unable to authenticate + result.error("NotSupported", "This device does not support required security features", null); + } + + private void authenticateSuccess(Result result) { + if (authInProgress.compareAndSet(true, false)) { + result.success(true); + } + } + + private void authenticateFail(Result result) { + if (authInProgress.compareAndSet(true, false)) { + result.success(false); } } /* - Stops the authentication if in progress. - */ + * Stops the authentication if in progress. + */ private void stopAuthentication(Result result) { try { - if (authenticationHelper != null && authInProgress.get()) { - authenticationHelper.stopAuthentication(); - authenticationHelper = null; - result.success(true); - return; + if (authHelper != null && authInProgress.get()) { + authHelper.stopAuthentication(); + authHelper = null; } - result.success(false); + authInProgress.set(false); + result.success(true); } catch (Exception e) { result.success(false); } } + /* + * Returns biometric types available on device + */ + private void getAvailableBiometrics(final Result result) { + try { + if (activity == null || activity.isFinishing()) { + result.error("no_activity", "local_auth plugin requires a foreground activity", null); + return; + } + ArrayList biometrics = getAvailableBiometrics(); + result.success(biometrics); + } catch (Exception e) { + result.error("no_biometrics_available", e.getMessage(), null); + } + } + + private ArrayList getAvailableBiometrics() { + ArrayList biometrics = new ArrayList<>(); + if (activity == null || activity.isFinishing()) { + return biometrics; + } + PackageManager packageManager = activity.getPackageManager(); + if (Build.VERSION.SDK_INT >= 23) { + if (packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) { + biometrics.add("fingerprint"); + } + } + if (Build.VERSION.SDK_INT >= 29) { + if (packageManager.hasSystemFeature(PackageManager.FEATURE_FACE)) { + biometrics.add("face"); + } + if (packageManager.hasSystemFeature(PackageManager.FEATURE_IRIS)) { + biometrics.add("iris"); + } + } + + return biometrics; + } + + private boolean isDeviceSupported() { + if (keyguardManager == null) return false; + return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && keyguardManager.isDeviceSecure()); + } + + private boolean canAuthenticateWithBiometrics() { + if (biometricManager == null) return false; + return biometricManager.canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS; + } + + private boolean hasBiometricHardware() { + if (biometricManager == null) return false; + return biometricManager.canAuthenticate() != BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE; + } + + private void isDeviceSupported(Result result) { + result.success(isDeviceSupported()); + } + @Override public void onAttachedToEngine(FlutterPluginBinding binding) { - channel = new MethodChannel(binding.getBinaryMessenger(), CHANNEL_NAME); + channel = new MethodChannel(binding.getFlutterEngine().getDartExecutor(), CHANNEL_NAME); + channel.setMethodCallHandler(this); } @Override - public void onDetachedFromEngine(FlutterPluginBinding binding) {} + public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {} + + private void setServicesFromActivity(Activity activity) { + if (activity == null) return; + this.activity = activity; + Context context = activity.getBaseContext(); + biometricManager = BiometricManager.from(activity); + keyguardManager = (KeyguardManager) context.getSystemService(KEYGUARD_SERVICE); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + fingerprintManager = + (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE); + } + } @Override public void onAttachedToActivity(ActivityPluginBinding binding) { - activity = binding.getActivity(); + binding.addActivityResultListener(resultListener); + setServicesFromActivity(binding.getActivity()); lifecycle = FlutterLifecycleAdapter.getActivityLifecycle(binding); channel.setMethodCallHandler(this); } @@ -185,18 +337,17 @@ public void onAttachedToActivity(ActivityPluginBinding binding) { @Override public void onDetachedFromActivityForConfigChanges() { lifecycle = null; - activity = null; } @Override public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) { - activity = binding.getActivity(); + binding.addActivityResultListener(resultListener); + setServicesFromActivity(binding.getActivity()); lifecycle = FlutterLifecycleAdapter.getActivityLifecycle(binding); } @Override public void onDetachedFromActivity() { - activity = null; lifecycle = null; channel.setMethodCallHandler(null); } diff --git a/packages/local_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/local_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties index 9a4163a4f5ee..186b71557c50 100644 --- a/packages/local_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ b/packages/local_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/packages/local_auth/example/android/build.gradle b/packages/local_auth/example/android/build.gradle index 541636cc492a..ea78cdf2c29c 100644 --- a/packages/local_auth/example/android/build.gradle +++ b/packages/local_auth/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.3.0' + classpath 'com.android.tools.build:gradle:4.1.1' } } diff --git a/packages/local_auth/example/android/gradle.properties b/packages/local_auth/example/android/gradle.properties index a6738207fd15..7fe61a74cee0 100644 --- a/packages/local_auth/example/android/gradle.properties +++ b/packages/local_auth/example/android/gradle.properties @@ -1,4 +1,4 @@ -org.gradle.jvmargs=-Xmx1536M +org.gradle.jvmargs=-Xmx1024m android.useAndroidX=true android.enableJetifier=true android.enableR8=true diff --git a/packages/local_auth/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/local_auth/example/android/gradle/wrapper/gradle-wrapper.properties index 562393332f6c..cd9fe1c68282 100644 --- a/packages/local_auth/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/local_auth/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu May 30 07:21:52 NPT 2019 +#Sun Jan 03 14:07:08 CST 2021 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip diff --git a/packages/local_auth/example/android/settings_aar.gradle b/packages/local_auth/example/android/settings_aar.gradle new file mode 100644 index 000000000000..e7b4def49cb5 --- /dev/null +++ b/packages/local_auth/example/android/settings_aar.gradle @@ -0,0 +1 @@ +include ':app' diff --git a/packages/local_auth/example/lib/main.dart b/packages/local_auth/example/lib/main.dart index 0a07e2c4437d..8cdad5b7eed3 100644 --- a/packages/local_auth/example/lib/main.dart +++ b/packages/local_auth/example/lib/main.dart @@ -21,11 +21,22 @@ class MyApp extends StatefulWidget { class _MyAppState extends State { final LocalAuthentication auth = LocalAuthentication(); - late bool _canCheckBiometrics; - late List _availableBiometrics; + _SupportState _supportState = _SupportState.unknown; + bool? _canCheckBiometrics; + List? _availableBiometrics; String _authorized = 'Not Authorized'; bool _isAuthenticating = false; + @override + void initState() { + super.initState(); + auth.isDeviceSupported().then( + (isSupported) => setState(() => _supportState = isSupported + ? _SupportState.supported + : _SupportState.unsupported), + ); + } + Future _checkBiometrics() async { late bool canCheckBiometrics; try { @@ -63,8 +74,8 @@ class _MyAppState extends State { _isAuthenticating = true; _authorized = 'Authenticating'; }); - authenticated = await auth.authenticateWithBiometrics( - localizedReason: 'Scan your fingerprint to authenticate', + authenticated = await auth.authenticate( + localizedReason: 'Let OS determine authentication method', useErrorDialogs: true, stickyAuth: true); setState(() { @@ -73,6 +84,42 @@ class _MyAppState extends State { }); } on PlatformException catch (e) { print(e); + setState(() { + _isAuthenticating = false; + _authorized = "Error - ${e.message}"; + }); + return; + } + if (!mounted) return; + + setState( + () => _authorized = authenticated ? 'Authorized' : 'Not Authorized'); + } + + Future _authenticateWithBiometrics() async { + bool authenticated = false; + try { + setState(() { + _isAuthenticating = true; + _authorized = 'Authenticating'; + }); + authenticated = await auth.authenticate( + localizedReason: + 'Scan your fingerprint (or face or whatever) to authenticate', + useErrorDialogs: true, + stickyAuth: true, + biometricOnly: true); + setState(() { + _isAuthenticating = false; + _authorized = 'Authenticating'; + }); + } on PlatformException catch (e) { + print(e); + setState(() { + _isAuthenticating = false; + _authorized = "Error - ${e.message}"; + }); + return; } if (!mounted) return; @@ -82,39 +129,92 @@ class _MyAppState extends State { }); } - void _cancelAuthentication() { - auth.stopAuthentication(); + void _cancelAuthentication() async { + await auth.stopAuthentication(); + setState(() => _isAuthenticating = false); } @override Widget build(BuildContext context) { return MaterialApp( - home: Scaffold( - appBar: AppBar( - title: const Text('Plugin example app'), - ), - body: ConstrainedBox( - constraints: const BoxConstraints.expand(), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ + home: Scaffold( + appBar: AppBar( + title: const Text('Plugin example app'), + ), + body: ListView( + padding: const EdgeInsets.only(top: 30), + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (_supportState == _SupportState.unknown) + CircularProgressIndicator() + else if (_supportState == _SupportState.supported) + Text("This device is supported") + else + Text("This device is not supported"), + Divider(height: 100), Text('Can check biometrics: $_canCheckBiometrics\n'), ElevatedButton( child: const Text('Check biometrics'), onPressed: _checkBiometrics, ), + Divider(height: 100), Text('Available biometrics: $_availableBiometrics\n'), ElevatedButton( child: const Text('Get available biometrics'), onPressed: _getAvailableBiometrics, ), + Divider(height: 100), Text('Current State: $_authorized\n'), - ElevatedButton( - child: Text(_isAuthenticating ? 'Cancel' : 'Authenticate'), - onPressed: - _isAuthenticating ? _cancelAuthentication : _authenticate, - ) - ])), - )); + (_isAuthenticating) + ? ElevatedButton( + onPressed: _cancelAuthentication, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text("Cancel Authentication"), + Icon(Icons.cancel), + ], + ), + ) + : Column( + children: [ + ElevatedButton( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text('Authenticate'), + Icon(Icons.perm_device_information), + ], + ), + onPressed: _authenticate, + ), + ElevatedButton( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text(_isAuthenticating + ? 'Cancel' + : 'Authenticate: biometrics only'), + Icon(Icons.fingerprint), + ], + ), + onPressed: _authenticateWithBiometrics, + ), + ], + ), + ], + ), + ], + ), + ), + ); } } + +enum _SupportState { + unknown, + supported, + unsupported, +} diff --git a/packages/local_auth/integration_test/local_auth_test.dart b/packages/local_auth/integration_test/local_auth_test.dart index c09810032461..d6527c7601e4 100644 --- a/packages/local_auth/integration_test/local_auth_test.dart +++ b/packages/local_auth/integration_test/local_auth_test.dart @@ -13,6 +13,9 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('canCheckBiometrics', (WidgetTester tester) async { - expect(LocalAuthentication().getAvailableBiometrics(), completion(isList)); + expect( + LocalAuthentication().getAvailableBiometrics(), + completion(isList), + ); }); } diff --git a/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m b/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m index aa0c217ef543..cda49a7d68c3 100644 --- a/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m +++ b/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m @@ -22,10 +22,17 @@ + (void)registerWithRegistrar:(NSObject *)registrar { } - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { - if ([@"authenticateWithBiometrics" isEqualToString:call.method]) { - [self authenticateWithBiometrics:call.arguments withFlutterResult:result]; + if ([@"authenticate" isEqualToString:call.method]) { + bool isBiometricOnly = [call.arguments[@"biometricOnly"] boolValue]; + if (isBiometricOnly) { + [self authenticateWithBiometrics:call.arguments withFlutterResult:result]; + } else { + [self authenticate:call.arguments withFlutterResult:result]; + } } else if ([@"getAvailableBiometrics" isEqualToString:call.method]) { [self getAvailableBiometrics:result]; + } else if ([@"isDeviceSupported" isEqualToString:call.method]) { + result(@YES); } else { result(FlutterMethodNotImplemented); } @@ -89,7 +96,6 @@ - (void)getAvailableBiometrics:(FlutterResult)result { } result(biometrics); } - - (void)authenticateWithBiometrics:(NSDictionary *)arguments withFlutterResult:(FlutterResult)result { LAContext *context = [[LAContext alloc] init]; @@ -130,6 +136,48 @@ - (void)authenticateWithBiometrics:(NSDictionary *)arguments } } +- (void)authenticate:(NSDictionary *)arguments withFlutterResult:(FlutterResult)result { + LAContext *context = [[LAContext alloc] init]; + NSError *authError = nil; + _lastCallArgs = nil; + _lastResult = nil; + context.localizedFallbackTitle = @""; + + if (@available(iOS 9.0, *)) { + if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&authError]) { + [context evaluatePolicy:kLAPolicyDeviceOwnerAuthentication + localizedReason:arguments[@"localizedReason"] + reply:^(BOOL success, NSError *error) { + if (success) { + result(@YES); + } else { + switch (error.code) { + case LAErrorPasscodeNotSet: + case LAErrorTouchIDNotAvailable: + case LAErrorTouchIDNotEnrolled: + case LAErrorTouchIDLockout: + [self handleErrors:error + flutterArguments:arguments + withFlutterResult:result]; + return; + case LAErrorSystemCancel: + if ([arguments[@"stickyAuth"] boolValue]) { + self->_lastCallArgs = arguments; + self->_lastResult = result; + return; + } + } + result(@NO); + } + }]; + } else { + [self handleErrors:authError flutterArguments:arguments withFlutterResult:result]; + } + } else { + // Fallback on earlier versions + } +} + - (void)handleErrors:(NSError *)authError flutterArguments:(NSDictionary *)arguments withFlutterResult:(FlutterResult)result { diff --git a/packages/local_auth/lib/auth_strings.dart b/packages/local_auth/lib/auth_strings.dart index 3afc23827d98..855098b6aba4 100644 --- a/packages/local_auth/lib/auth_strings.dart +++ b/packages/local_auth/lib/auth_strings.dart @@ -15,38 +15,46 @@ import 'package:intl/intl.dart'; /// Provides default values for all messages. class AndroidAuthMessages { const AndroidAuthMessages({ - this.fingerprintHint, - this.fingerprintNotRecognized, - this.fingerprintSuccess, + this.biometricHint, + this.biometricNotRecognized, + this.biometricRequiredTitle, + this.biometricSuccess, this.cancelButton, - this.signInTitle, - this.fingerprintRequiredTitle, + this.deviceCredentialsRequiredTitle, + this.deviceCredentialsSetupDescription, this.goToSettingsButton, this.goToSettingsDescription, + this.signInTitle, }); - final String? fingerprintHint; - final String? fingerprintNotRecognized; - final String? fingerprintSuccess; + final String? biometricHint; + final String? biometricNotRecognized; + final String? biometricRequiredTitle; + final String? biometricSuccess; final String? cancelButton; - final String? signInTitle; - final String? fingerprintRequiredTitle; + final String? deviceCredentialsRequiredTitle; + final String? deviceCredentialsSetupDescription; final String? goToSettingsButton; final String? goToSettingsDescription; + final String? signInTitle; Map get args { return { - 'fingerprintHint': fingerprintHint ?? androidFingerprintHint, - 'fingerprintNotRecognized': - fingerprintNotRecognized ?? androidFingerprintNotRecognized, - 'fingerprintSuccess': fingerprintSuccess ?? androidFingerprintSuccess, + 'biometricHint': biometricHint ?? androidBiometricHint, + 'biometricNotRecognized': + biometricNotRecognized ?? androidBiometricNotRecognized, + 'biometricSuccess': biometricSuccess ?? androidBiometricSuccess, + 'biometricRequired': + biometricRequiredTitle ?? androidBiometricRequiredTitle, 'cancelButton': cancelButton ?? androidCancelButton, - 'signInTitle': signInTitle ?? androidSignInTitle, - 'fingerprintRequired': - fingerprintRequiredTitle ?? androidFingerprintRequiredTitle, + 'deviceCredentialsRequired': deviceCredentialsRequiredTitle ?? + androidDeviceCredentialsRequiredTitle, + 'deviceCredentialsSetupDescription': deviceCredentialsSetupDescription ?? + androidDeviceCredentialsSetupDescription, 'goToSetting': goToSettingsButton ?? goToSettings, 'goToSettingDescription': goToSettingsDescription ?? androidGoToSettingsDescription, + 'signInTitle': signInTitle ?? androidSignInTitle, }; } } @@ -80,16 +88,17 @@ class IOSAuthMessages { // Strings for local_authentication plugin. Currently supports English. // Intl.message must be string literals. -String get androidFingerprintHint => Intl.message('Touch sensor', - desc: 'Hint message advising the user how to scan their fingerprint. It is ' +String get androidBiometricHint => Intl.message('Verify identity', + desc: + 'Hint message advising the user how to authenticate with biometrics. It is ' 'used on Android side. Maximum 60 characters.'); -String get androidFingerprintNotRecognized => - Intl.message('Fingerprint not recognized. Try again.', +String get androidBiometricNotRecognized => + Intl.message('Not recognized. Try again.', desc: 'Message to let the user know that authentication was failed. It ' 'is used on Android side. Maximum 60 characters.'); -String get androidFingerprintSuccess => Intl.message('Fingerprint recognized.', +String get androidBiometricSuccess => Intl.message('Success', desc: 'Message to let the user know that authentication was successful. It ' 'is used on Android side. Maximum 60 characters.'); @@ -97,17 +106,26 @@ String get androidCancelButton => Intl.message('Cancel', desc: 'Message showed on a button that the user can click to leave the ' 'current dialog. It is used on Android side. Maximum 30 characters.'); -String get androidSignInTitle => Intl.message('Fingerprint Authentication', +String get androidSignInTitle => Intl.message('Authentication required', desc: 'Message showed as a title in a dialog which indicates the user ' - 'that they need to scan fingerprint to continue. It is used on ' + 'that they need to scan biometric to continue. It is used on ' 'Android side. Maximum 60 characters.'); -String get androidFingerprintRequiredTitle { - return Intl.message('Fingerprint required', - desc: 'Message showed as a title in a dialog which indicates the user ' - 'fingerprint is not set up yet on their device. It is used on Android' - ' side. Maximum 60 characters.'); -} +String get androidBiometricRequiredTitle => Intl.message('Biometric required', + desc: 'Message showed as a title in a dialog which indicates the user ' + 'has not set up biometric authentication on their device. It is used on Android' + ' side. Maximum 60 characters.'); + +String get androidDeviceCredentialsRequiredTitle => Intl.message( + 'Device credentials required', + desc: 'Message showed as a title in a dialog which indicates the user ' + 'has not set up credentials authentication on their device. It is used on Android' + ' side. Maximum 60 characters.'); + +String get androidDeviceCredentialsSetupDescription => Intl.message( + 'Device credentials required', + desc: 'Message advising the user to go to the settings and configure ' + 'device credentials on their device. It shows in a dialog on Android side.'); String get goToSettings => Intl.message('Go to settings', desc: 'Message showed on a button that the user can click to go to ' @@ -115,10 +133,10 @@ String get goToSettings => Intl.message('Go to settings', 'and iOS side. Maximum 30 characters.'); String get androidGoToSettingsDescription => Intl.message( - 'Fingerprint is not set up on your device. Go to ' - '\'Settings > Security\' to add your fingerprint.', + 'Biometric authentication is not set up on your device. Go to ' + '\'Settings > Security\' to add biometric authentication.', desc: 'Message advising the user to go to the settings and configure ' - 'fingerprint on their device. It shows in a dialog on Android side.'); + 'biometric on their device. It shows in a dialog on Android side.'); String get iOSLockOut => Intl.message( 'Biometric authentication is disabled. Please lock and unlock your screen to ' diff --git a/packages/local_auth/lib/error_codes.dart b/packages/local_auth/lib/error_codes.dart index 3f6f298ba4f3..3b080c13baf7 100644 --- a/packages/local_auth/lib/error_codes.dart +++ b/packages/local_auth/lib/error_codes.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. // Exception codes for `PlatformException` returned by -// `authenticateWithBiometrics`. +// `authenticate`. /// Indicates that the user has not yet configured a passcode (iOS) or /// PIN/pattern/password (Android) on the device. diff --git a/packages/local_auth/lib/local_auth.dart b/packages/local_auth/lib/local_auth.dart index f1dbdd4840a8..f8a7228bcd8d 100644 --- a/packages/local_auth/lib/local_auth.dart +++ b/packages/local_auth/lib/local_auth.dart @@ -30,7 +30,29 @@ void setMockPathProviderPlatform(Platform platform) { /// A Flutter plugin for authenticating the user identity locally. class LocalAuthentication { - /// Authenticates the user with biometrics available on the device. + /// The `authenticateWithBiometrics` method has been deprecated. + /// Use `authenticate` with `biometricOnly: true` instead + @Deprecated("Use `authenticate` with `biometricOnly: true` instead") + Future authenticateWithBiometrics({ + required String localizedReason, + bool useErrorDialogs = true, + bool stickyAuth = false, + AndroidAuthMessages androidAuthStrings = const AndroidAuthMessages(), + IOSAuthMessages iOSAuthStrings = const IOSAuthMessages(), + bool sensitiveTransaction = true, + }) => + authenticate( + localizedReason: localizedReason, + useErrorDialogs: useErrorDialogs, + stickyAuth: stickyAuth, + androidAuthStrings: androidAuthStrings, + iOSAuthStrings: iOSAuthStrings, + sensitiveTransaction: sensitiveTransaction, + biometricOnly: true, + ); + + /// Authenticates the user with biometrics available on the device while also + /// allowing the user to use device authentication - pin, pattern, passcode. /// /// Returns a [Future] holding true, if the user successfully authenticated, /// false otherwise. @@ -62,17 +84,21 @@ class LocalAuthentication { /// dialog after the face is recognized to make sure the user meant to unlock /// their phone. /// + /// Setting [biometricOnly] to true prevents authenticates from using non-biometric + /// local authentication such as pin, passcode, and passcode. + /// /// Throws an [PlatformException] if there were technical problems with local /// authentication (e.g. lack of relevant hardware). This might throw /// [PlatformException] with error code [otherOperatingSystem] on the iOS /// simulator. - Future authenticateWithBiometrics({ + Future authenticate({ required String localizedReason, bool useErrorDialogs = true, bool stickyAuth = false, AndroidAuthMessages androidAuthStrings = const AndroidAuthMessages(), IOSAuthMessages iOSAuthStrings = const IOSAuthMessages(), bool sensitiveTransaction = true, + bool biometricOnly = false, }) async { assert(localizedReason != null); final Map args = { @@ -80,6 +106,7 @@ class LocalAuthentication { 'useErrorDialogs': useErrorDialogs, 'stickyAuth': stickyAuth, 'sensitiveTransaction': sensitiveTransaction, + 'biometricOnly': biometricOnly, }; if (_platform.isIOS) { args.addAll(iOSAuthStrings.args); @@ -87,14 +114,13 @@ class LocalAuthentication { args.addAll(androidAuthStrings.args); } else { throw PlatformException( - code: otherOperatingSystem, - message: 'Local authentication does not support non-Android/iOS ' - 'operating systems.', - details: 'Your operating system is ${_platform.operatingSystem}'); + code: otherOperatingSystem, + message: 'Local authentication does not support non-Android/iOS ' + 'operating systems.', + details: 'Your operating system is ${_platform.operatingSystem}', + ); } - final bool? result = - await _channel.invokeMethod('authenticateWithBiometrics', args); - return result!; + return (await _channel.invokeMethod('authenticate', args)) ?? false; } /// Returns true if auth was cancelled successfully. @@ -104,9 +130,7 @@ class LocalAuthentication { /// Returns [Future] bool true or false: Future stopAuthentication() async { if (_platform.isAndroid) { - final bool? result = - await _channel.invokeMethod('stopAuthentication'); - return result!; + return await _channel.invokeMethod('stopAuthentication') ?? false; } return true; } @@ -118,6 +142,13 @@ class LocalAuthentication { (await _channel.invokeListMethod('getAvailableBiometrics'))! .isNotEmpty; + /// Returns true if device is capable of checking biometrics or is able to + /// fail over to device credentials. + /// + /// Returns a [Future] bool true or false: + Future isDeviceSupported() async => + (await _channel.invokeMethod('isDeviceSupported')) ?? false; + /// Returns a list of enrolled biometrics /// /// Returns a [Future] List with the following possibilities: @@ -125,10 +156,12 @@ class LocalAuthentication { /// - BiometricType.fingerprint /// - BiometricType.iris (not yet implemented) Future> getAvailableBiometrics() async { - final List? result = - await _channel.invokeListMethod('getAvailableBiometrics'); + final List result = (await _channel.invokeListMethod( + 'getAvailableBiometrics', + )) ?? + []; final List biometrics = []; - result!.forEach((String value) { + result.forEach((String value) { switch (value) { case 'face': biometrics.add(BiometricType.face); diff --git a/packages/local_auth/pubspec.yaml b/packages/local_auth/pubspec.yaml index 050cedb5d7d0..0f5a58835c3c 100644 --- a/packages/local_auth/pubspec.yaml +++ b/packages/local_auth/pubspec.yaml @@ -1,6 +1,6 @@ name: local_auth -description: Flutter plugin for Android and iOS device authentication sensors - such as Fingerprint Reader and Touch ID. +description: Flutter plugin for Android and iOS devices to allow local + authentication via fingerprint, touch ID, face ID, passcode, pin, or pattern. homepage: https://github.com/flutter/plugins/tree/master/packages/local_auth version: 1.0.0-nullsafety.3 diff --git a/packages/local_auth/test/local_auth_test.dart b/packages/local_auth/test/local_auth_test.dart index 52b8dbf21f72..f4bf9fe0314d 100644 --- a/packages/local_auth/test/local_auth_test.dart +++ b/packages/local_auth/test/local_auth_test.dart @@ -30,61 +30,135 @@ void main() { log.clear(); }); - test('authenticate with no args on Android.', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'android')); - await localAuthentication.authenticateWithBiometrics( - localizedReason: 'Needs secure'); - expect( - log, - [ - isMethodCall('authenticateWithBiometrics', - arguments: { - 'localizedReason': 'Needs secure', - 'useErrorDialogs': true, - 'stickyAuth': false, - 'sensitiveTransaction': true, - }..addAll(const AndroidAuthMessages().args)), - ], - ); - }); + group("With device auth fail over", () { + test('authenticate with no args on Android.', () async { + setMockPathProviderPlatform(FakePlatform(operatingSystem: 'android')); + await localAuthentication.authenticate( + localizedReason: 'Needs secure', + biometricOnly: true, + ); + expect( + log, + [ + isMethodCall('authenticate', + arguments: { + 'localizedReason': 'Needs secure', + 'useErrorDialogs': true, + 'stickyAuth': false, + 'sensitiveTransaction': true, + 'biometricOnly': true, + }..addAll(const AndroidAuthMessages().args)), + ], + ); + }); - test('authenticate with no args on iOS.', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); - await localAuthentication.authenticateWithBiometrics( - localizedReason: 'Needs secure'); - expect( - log, - [ - isMethodCall('authenticateWithBiometrics', - arguments: { - 'localizedReason': 'Needs secure', - 'useErrorDialogs': true, - 'stickyAuth': false, - 'sensitiveTransaction': true, - }..addAll(const IOSAuthMessages().args)), - ], - ); + test('authenticate with no args on iOS.', () async { + setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); + await localAuthentication.authenticate( + localizedReason: 'Needs secure', + biometricOnly: true, + ); + expect( + log, + [ + isMethodCall('authenticate', + arguments: { + 'localizedReason': 'Needs secure', + 'useErrorDialogs': true, + 'stickyAuth': false, + 'sensitiveTransaction': true, + 'biometricOnly': true, + }..addAll(const IOSAuthMessages().args)), + ], + ); + }); + + test('authenticate with no sensitive transaction.', () async { + setMockPathProviderPlatform(FakePlatform(operatingSystem: 'android')); + await localAuthentication.authenticate( + localizedReason: 'Insecure', + sensitiveTransaction: false, + useErrorDialogs: false, + biometricOnly: true, + ); + expect( + log, + [ + isMethodCall('authenticate', + arguments: { + 'localizedReason': 'Insecure', + 'useErrorDialogs': false, + 'stickyAuth': false, + 'sensitiveTransaction': false, + 'biometricOnly': true, + }..addAll(const AndroidAuthMessages().args)), + ], + ); + }); }); - test('authenticate with no sensitive transaction.', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'android')); - await localAuthentication.authenticateWithBiometrics( - localizedReason: 'Insecure', - sensitiveTransaction: false, - useErrorDialogs: false, - ); - expect( - log, - [ - isMethodCall('authenticateWithBiometrics', - arguments: { - 'localizedReason': 'Insecure', - 'useErrorDialogs': false, - 'stickyAuth': false, - 'sensitiveTransaction': false, - }..addAll(const AndroidAuthMessages().args)), - ], - ); + group("With biometrics only", () { + test('authenticate with no args on Android.', () async { + setMockPathProviderPlatform(FakePlatform(operatingSystem: 'android')); + await localAuthentication.authenticate( + localizedReason: 'Needs secure', + ); + expect( + log, + [ + isMethodCall('authenticate', + arguments: { + 'localizedReason': 'Needs secure', + 'useErrorDialogs': true, + 'stickyAuth': false, + 'sensitiveTransaction': true, + 'biometricOnly': false, + }..addAll(const AndroidAuthMessages().args)), + ], + ); + }); + + test('authenticate with no args on iOS.', () async { + setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); + await localAuthentication.authenticate( + localizedReason: 'Needs secure', + ); + expect( + log, + [ + isMethodCall('authenticate', + arguments: { + 'localizedReason': 'Needs secure', + 'useErrorDialogs': true, + 'stickyAuth': false, + 'sensitiveTransaction': true, + 'biometricOnly': false, + }..addAll(const IOSAuthMessages().args)), + ], + ); + }); + + test('authenticate with no sensitive transaction.', () async { + setMockPathProviderPlatform(FakePlatform(operatingSystem: 'android')); + await localAuthentication.authenticate( + localizedReason: 'Insecure', + sensitiveTransaction: false, + useErrorDialogs: false, + ); + expect( + log, + [ + isMethodCall('authenticate', + arguments: { + 'localizedReason': 'Insecure', + 'useErrorDialogs': false, + 'stickyAuth': false, + 'sensitiveTransaction': false, + 'biometricOnly': false, + }..addAll(const AndroidAuthMessages().args)), + ], + ); + }); }); }); } From e113013247215446dd5c3a13cb7d69c852f1d330 Mon Sep 17 00:00:00 2001 From: Mehmet Fidanboylu Date: Fri, 15 Jan 2021 07:46:59 -0800 Subject: [PATCH 0045/1565] [google_sign_in] Migrate to nnbd (#3329) --- .../google_sign_in/CHANGELOG.md | 4 ++ .../integration_test/google_sign_in_test.dart | 2 + .../google_sign_in/lib/google_sign_in.dart | 56 +++++++++---------- .../google_sign_in/lib/src/common.dart | 4 +- .../google_sign_in/lib/testing.dart | 18 +++--- .../google_sign_in/lib/widgets.dart | 29 +++------- .../google_sign_in/pubspec.yaml | 18 ++---- .../test/google_sign_in_test.dart | 36 ++++++------ .../test_driver/integration_test.dart | 2 + .../CHANGELOG.md | 4 ++ .../google_sign_in_platform_interface.dart | 21 +++---- .../src/method_channel_google_sign_in.dart | 35 ++++++------ .../lib/src/types.dart | 28 ++++++---- .../lib/src/utils.dart | 9 +-- .../pubspec.yaml | 14 ++--- ...oogle_sign_in_platform_interface_test.dart | 12 ++-- .../method_channel_google_sign_in_test.dart | 9 ++- 17 files changed, 150 insertions(+), 151 deletions(-) diff --git a/packages/google_sign_in/google_sign_in/CHANGELOG.md b/packages/google_sign_in/google_sign_in/CHANGELOG.md index 7f5b4f2bdd17..d87df7466312 100644 --- a/packages/google_sign_in/google_sign_in/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.0.0-nullsafety + +* Migrate to nnbd. + ## 4.5.9 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. diff --git a/packages/google_sign_in/google_sign_in/integration_test/google_sign_in_test.dart b/packages/google_sign_in/google_sign_in/integration_test/google_sign_in_test.dart index 7b2b8d800778..a900bfbfdc2e 100644 --- a/packages/google_sign_in/google_sign_in/integration_test/google_sign_in_test.dart +++ b/packages/google_sign_in/google_sign_in/integration_test/google_sign_in_test.dart @@ -1,3 +1,5 @@ +// @dart = 2.9 + import 'package:integration_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:google_sign_in/google_sign_in.dart'; diff --git a/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart b/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart index 0f1f15bbb8c4..1317eb91ecfb 100644 --- a/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart +++ b/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart @@ -22,13 +22,13 @@ class GoogleSignInAuthentication { final GoogleSignInTokenData _data; /// An OpenID Connect ID token that identifies the user. - String get idToken => _data.idToken; + String? get idToken => _data.idToken; /// The OAuth2 access token to access Google services. - String get accessToken => _data.accessToken; + String? get accessToken => _data.accessToken; /// Server auth code used to access Google Login - String get serverAuthCode => _data.serverAuthCode; + String? get serverAuthCode => _data.serverAuthCode; @override String toString() => 'GoogleSignInAuthentication:$_data'; @@ -57,7 +57,7 @@ class GoogleSignInAccount implements GoogleIdentity { static const String kUserRecoverableAuthError = 'user_recoverable_auth'; @override - final String displayName; + final String? displayName; @override final String email; @@ -66,9 +66,9 @@ class GoogleSignInAccount implements GoogleIdentity { final String id; @override - final String photoUrl; + final String? photoUrl; - final String _idToken; + final String? _idToken; final GoogleSignIn _googleSignIn; /// Retrieve [GoogleSignInAuthentication] for this account. @@ -105,7 +105,7 @@ class GoogleSignInAccount implements GoogleIdentity { /// /// See also https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization. Future> get authHeaders async { - final String token = (await authentication).accessToken; + final String? token = (await authentication).accessToken; return { "Authorization": "Bearer $token", "X-Goog-AuthUser": "0", @@ -117,7 +117,7 @@ class GoogleSignInAccount implements GoogleIdentity { /// If client runs into 401 errors using a token, it is expected to call /// this method and grab `authHeaders` once again. Future clearAuthCache() async { - final String token = (await authentication).accessToken; + final String token = (await authentication).accessToken!; await GoogleSignInPlatform.instance.clearAuthCache(token: token); } @@ -174,7 +174,7 @@ class GoogleSignIn { /// Factory for creating default sign in user experience. factory GoogleSignIn.standard({ List scopes = const [], - String hostedDomain, + String? hostedDomain, }) { return GoogleSignIn( signInOption: SignInOption.standard, @@ -212,22 +212,22 @@ class GoogleSignIn { final List scopes; /// Domain to restrict sign-in to. - final String hostedDomain; + final String? hostedDomain; /// Client ID being used to connect to google sign-in. Only supported on web. - final String clientId; + final String? clientId; - StreamController _currentUserController = - StreamController.broadcast(); + StreamController _currentUserController = + StreamController.broadcast(); /// Subscribe to this stream to be notified when the current user changes. - Stream get onCurrentUserChanged => + Stream get onCurrentUserChanged => _currentUserController.stream; // Future that completes when we've finished calling `init` on the native side - Future _initialization; + Future? _initialization; - Future _callMethod(Function method) async { + Future _callMethod(Function method) async { await _ensureInitialized(); final dynamic response = await method(); @@ -237,7 +237,7 @@ class GoogleSignIn { : null); } - GoogleSignInAccount _setCurrentUser(GoogleSignInAccount currentUser) { + GoogleSignInAccount? _setCurrentUser(GoogleSignInAccount? currentUser) { if (currentUser != _currentUser) { _currentUser = currentUser; _currentUserController.add(_currentUser); @@ -258,7 +258,7 @@ class GoogleSignIn { } /// The most recently scheduled method call. - Future _lastMethodCall; + Future? _lastMethodCall; /// Returns a [Future] that completes with a success after [future], whether /// it completed with a value or an error. @@ -279,15 +279,15 @@ class GoogleSignIn { /// The optional, named parameter [canSkipCall] lets the plugin know that the /// method call may be skipped, if there's already [_currentUser] information. /// This is used from the [signIn] and [signInSilently] methods. - Future _addMethodCall( + Future _addMethodCall( Function method, { bool canSkipCall = false, }) async { - Future response; + Future response; if (_lastMethodCall == null) { response = _callMethod(method); } else { - response = _lastMethodCall.then((_) { + response = _lastMethodCall!.then((_) { // If after the last completed call `currentUser` is not `null` and requested // method can be skipped (`canSkipCall`), re-use the same authenticated user // instead of making extra call to the native side. @@ -303,8 +303,8 @@ class GoogleSignIn { } /// The currently signed in account, or null if the user is signed out. - GoogleSignInAccount get currentUser => _currentUser; - GoogleSignInAccount _currentUser; + GoogleSignInAccount? get currentUser => _currentUser; + GoogleSignInAccount? _currentUser; /// Attempts to sign in a previously authenticated user without interaction. /// @@ -323,7 +323,7 @@ class GoogleSignIn { /// one of [kSignInRequiredError] (when there is no authenticated user) , /// [kNetworkError] (when a network error occurred) or [kSignInFailedError] /// (when an unknown error occurred). - Future signInSilently({ + Future signInSilently({ bool suppressErrors = true, }) async { try { @@ -354,8 +354,8 @@ class GoogleSignIn { /// a Future which resolves to the same user instance. /// /// Re-authentication can be triggered only after [signOut] or [disconnect]. - Future signIn() { - final Future result = + Future signIn() { + final Future result = _addMethodCall(GoogleSignInPlatform.instance.signIn, canSkipCall: true); bool isCanceled(dynamic error) => error is PlatformException && error.code == kSignInCanceledError; @@ -363,12 +363,12 @@ class GoogleSignIn { } /// Marks current user as being in the signed out state. - Future signOut() => + Future signOut() => _addMethodCall(GoogleSignInPlatform.instance.signOut); /// Disconnects the current user from the app and revokes previous /// authentication. - Future disconnect() => + Future disconnect() => _addMethodCall(GoogleSignInPlatform.instance.disconnect); /// Requests the user grants additional Oauth [scopes]. diff --git a/packages/google_sign_in/google_sign_in/lib/src/common.dart b/packages/google_sign_in/google_sign_in/lib/src/common.dart index 14bed4fe114a..60c74ab4c6d5 100644 --- a/packages/google_sign_in/google_sign_in/lib/src/common.dart +++ b/packages/google_sign_in/google_sign_in/lib/src/common.dart @@ -28,10 +28,10 @@ abstract class GoogleIdentity { /// The display name of the signed in user. /// /// Not guaranteed to be present for all users, even when configured. - String get displayName; + String? get displayName; /// The photo url of the signed in user if the user has a profile picture. /// /// Not guaranteed to be present for all users, even when configured. - String get photoUrl; + String? get photoUrl; } diff --git a/packages/google_sign_in/google_sign_in/lib/testing.dart b/packages/google_sign_in/google_sign_in/lib/testing.dart index 8d62ff463ca6..ed0ca4f2de7c 100644 --- a/packages/google_sign_in/google_sign_in/lib/testing.dart +++ b/packages/google_sign_in/google_sign_in/lib/testing.dart @@ -32,7 +32,7 @@ class FakeSignInBackend { /// This does not represent the signed-in user, but rather an object that will /// be returned when [GoogleSignIn.signIn] or [GoogleSignIn.signInSilently] is /// called. - FakeUser user; + late FakeUser user; /// Handles method calls that would normally be sent to the native backend. /// Returns with the expected values based on the current [user]. @@ -42,7 +42,7 @@ class FakeSignInBackend { // do nothing return null; case 'getTokens': - return { + return { 'idToken': user.idToken, 'accessToken': user.accessToken, }; @@ -72,24 +72,24 @@ class FakeUser { }); /// Will be converted into [GoogleSignInUserData.id]. - final String id; + final String? id; /// Will be converted into [GoogleSignInUserData.email]. - final String email; + final String? email; /// Will be converted into [GoogleSignInUserData.displayName]. - final String displayName; + final String? displayName; /// Will be converted into [GoogleSignInUserData.photoUrl]. - final String photoUrl; + final String? photoUrl; /// Will be converted into [GoogleSignInTokenData.idToken]. - final String idToken; + final String? idToken; /// Will be converted into [GoogleSignInTokenData.accessToken]. - final String accessToken; + final String? accessToken; - Map get _asMap => { + Map get _asMap => { 'id': id, 'email': email, 'displayName': displayName, diff --git a/packages/google_sign_in/google_sign_in/lib/widgets.dart b/packages/google_sign_in/google_sign_in/lib/widgets.dart index 3375628f47b5..c9682930b089 100644 --- a/packages/google_sign_in/google_sign_in/lib/widgets.dart +++ b/packages/google_sign_in/google_sign_in/lib/widgets.dart @@ -4,7 +4,6 @@ import 'dart:typed_data'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'src/common.dart'; @@ -23,7 +22,7 @@ class GoogleUserCircleAvatar extends StatelessWidget { /// in place of a profile photo, or a default profile photo if the user's /// identity does not specify a `displayName`. const GoogleUserCircleAvatar({ - @required this.identity, + required this.identity, this.placeholderPhotoUrl, this.foregroundColor, this.backgroundColor, @@ -42,13 +41,13 @@ class GoogleUserCircleAvatar extends StatelessWidget { /// The color of the text to be displayed if photo is not available. /// /// If a foreground color is not specified, the theme's text color is used. - final Color foregroundColor; + final Color? foregroundColor; /// The color with which to fill the circle. Changing the background color /// will cause the avatar to animate to the new color. /// /// If a background color is not specified, the theme's primary color is used. - final Color backgroundColor; + final Color? backgroundColor; /// The URL of a photo to use if the user's [identity] does not specify a /// `photoUrl`. @@ -57,7 +56,7 @@ class GoogleUserCircleAvatar extends StatelessWidget { /// then this widget will attempt to display the user's first initial as /// determined from the identity's [displayName] field. If that is `null` a /// default (generic) Google profile photo will be displayed. - final String placeholderPhotoUrl; + final String? placeholderPhotoUrl; @override Widget build(BuildContext context) { @@ -68,38 +67,26 @@ class GoogleUserCircleAvatar extends StatelessWidget { ); } - /// Adds correct sizing information to [photoUrl]. - /// - /// Falls back to the default profile photo if [photoUrl] is [null]. - static String _sizedProfileImageUrl(String photoUrl, double size) { - if (photoUrl == null) { - // If the user has no profile photo and no display name, fall back to - // the default profile photo as a last resort. - return 'https://lh3.googleusercontent.com/a/default-user=s${size.round()}-c'; - } - return fife.addSizeDirectiveToUrl(photoUrl, size); - } - Widget _buildClippedImage(BuildContext context, BoxConstraints constraints) { assert(constraints.maxWidth == constraints.maxHeight); // Placeholder to use when there is no photo URL, and while the photo is // loading. Uses the first character of the display name (if it has one), // or the first letter of the email address if it does not. - final List placeholderCharSources = [ + final List placeholderCharSources = [ identity.displayName, identity.email, '-', ]; final String placeholderChar = placeholderCharSources - .firstWhere((String str) => str != null && str.trimLeft().isNotEmpty) + .firstWhere((String? str) => str != null && str.trimLeft().isNotEmpty)! .trimLeft()[0] .toUpperCase(); final Widget placeholder = Center( child: Text(placeholderChar, textAlign: TextAlign.center), ); - final String photoUrl = identity.photoUrl ?? placeholderPhotoUrl; + final String? photoUrl = identity.photoUrl ?? placeholderPhotoUrl; if (photoUrl == null) { return placeholder; } @@ -107,7 +94,7 @@ class GoogleUserCircleAvatar extends StatelessWidget { // Add a sizing directive to the profile photo URL. final double size = MediaQuery.of(context).devicePixelRatio * constraints.maxWidth; - final String sizedPhotoUrl = _sizedProfileImageUrl(photoUrl, size); + final String sizedPhotoUrl = fife.addSizeDirectiveToUrl(photoUrl, size); // Fade the photo in over the top of the placeholder. return SizedBox( diff --git a/packages/google_sign_in/google_sign_in/pubspec.yaml b/packages/google_sign_in/google_sign_in/pubspec.yaml index 6e0366c790bf..2a2506a38357 100644 --- a/packages/google_sign_in/google_sign_in/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/pubspec.yaml @@ -2,7 +2,7 @@ name: google_sign_in description: Flutter plugin for Google Sign-In, a secure authentication system for signing in with a Google account on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in -version: 4.5.9 +version: 5.0.0-nullsafety flutter: plugin: @@ -16,16 +16,10 @@ flutter: default_package: google_sign_in_web dependencies: - google_sign_in_platform_interface: ^1.1.1 + google_sign_in_platform_interface: ^2.0.0-nullsafety flutter: sdk: flutter - meta: ^1.0.4 - # The design on https://flutter.dev/go/federated-plugins was to leave - # this constraint as "any". We cannot do it right now as it fails pub publish - # validation, so we set a ^ constraint. - # TODO(amirh): Revisit this (either update this part in the design or the pub tool). - # https://github.com/flutter/flutter/issues/46264 - google_sign_in_web: ^0.9.1 + meta: ^1.3.0-nullsafety.6 dev_dependencies: http: ^0.12.0 @@ -33,10 +27,10 @@ dev_dependencies: sdk: flutter flutter_test: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0-nullsafety.1 integration_test: path: ../../integration_test environment: - sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.12.13+hotfix.4" + sdk: ">=2.12.0-0 <3.0.0" + flutter: ">=1.12.13+hotfix.5" diff --git a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart index 7305800296f9..2a8d65e32ffd 100755 --- a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart +++ b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart @@ -2,8 +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:async'; import 'package:flutter/services.dart'; @@ -43,8 +41,8 @@ void main() { }; final List log = []; - Map responses; - GoogleSignIn googleSignIn; + late Map responses; + late GoogleSignIn googleSignIn; setUp(() { responses = Map.from(kDefaultResponses); @@ -173,16 +171,16 @@ void main() { }); test('concurrent calls of the same method trigger sign in once', () async { - final List> futures = - >[ + final List> futures = + >[ googleSignIn.signInSilently(), googleSignIn.signInSilently(), ]; expect(futures.first, isNot(futures.last), reason: 'Must return new Future'); - final List users = await Future.wait(futures); + final List users = await Future.wait(futures); expect(googleSignIn.currentUser, isNotNull); - expect(users, [ + expect(users, [ googleSignIn.currentUser, googleSignIn.currentUser ]); @@ -218,13 +216,13 @@ void main() { }); test('concurrent calls of different signIn methods', () async { - final List> futures = - >[ + final List> futures = + >[ googleSignIn.signInSilently(), googleSignIn.signIn(), ]; expect(futures.first, isNot(futures.last)); - final List users = await Future.wait(futures); + final List users = await Future.wait(futures); expect( log, [ @@ -248,8 +246,8 @@ void main() { }); test('signOut/disconnect methods always trigger native calls', () async { - final List> futures = - >[ + final List> futures = + >[ googleSignIn.signOut(), googleSignIn.signOut(), googleSignIn.disconnect(), @@ -273,8 +271,8 @@ void main() { }); test('queue of many concurrent calls', () async { - final List> futures = - >[ + final List> futures = + >[ googleSignIn.signInSilently(), googleSignIn.signOut(), googleSignIn.signIn(), @@ -368,7 +366,7 @@ void main() { await googleSignIn.signIn(); log.clear(); - final GoogleSignInAccount user = googleSignIn.currentUser; + final GoogleSignInAccount user = googleSignIn.currentUser!; final GoogleSignInAuthentication auth = await user.authentication; expect(auth.accessToken, '456'); @@ -415,11 +413,11 @@ void main() { photoUrl: "https://lh5.googleusercontent.com/photo.jpg", ); - GoogleSignIn googleSignIn; + late GoogleSignIn googleSignIn; setUp(() { final MethodChannelGoogleSignIn platformInstance = - GoogleSignInPlatform.instance; + GoogleSignInPlatform.instance as MethodChannelGoogleSignIn; platformInstance.channel.setMockMethodCallHandler( (FakeSignInBackend()..user = kUserData).handleMethodCall); googleSignIn = GoogleSignIn(); @@ -432,7 +430,7 @@ void main() { test('can sign in and sign out', () async { await googleSignIn.signIn(); - final GoogleSignInAccount user = googleSignIn.currentUser; + final GoogleSignInAccount user = googleSignIn.currentUser!; expect(user.displayName, equals(kUserData.displayName)); expect(user.email, equals(kUserData.email)); diff --git a/packages/google_sign_in/google_sign_in/test_driver/integration_test.dart b/packages/google_sign_in/google_sign_in/test_driver/integration_test.dart index f07dba382187..4a27ac2f986b 100644 --- a/packages/google_sign_in/google_sign_in/test_driver/integration_test.dart +++ b/packages/google_sign_in/google_sign_in/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/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md b/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md index e69e912195bf..f01d03080af7 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Migration to nnbd. + ## 1.1.3 * Update Flutter SDK constraint. diff --git a/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart b/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart index 966e93551086..3499558f9114 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'dart:async'; -import 'package:meta/meta.dart' show required, visibleForTesting; +import 'package:meta/meta.dart' show visibleForTesting; import 'src/method_channel_google_sign_in.dart'; import 'src/types.dart'; @@ -78,27 +78,28 @@ abstract class GoogleSignInPlatform { /// /// See: /// https://developers.google.com/identity/sign-in/web/reference#gapiauth2initparams - Future init( - {@required String hostedDomain, - List scopes, - SignInOption signInOption, - String clientId}) async { + Future init({ + List scopes = const [], + SignInOption signInOption = SignInOption.standard, + String? hostedDomain, + String? clientId, + }) async { throw UnimplementedError('init() has not been implemented.'); } /// Attempts to reuse pre-existing credentials to sign in again, without user interaction. - Future signInSilently() async { + Future signInSilently() async { throw UnimplementedError('signInSilently() has not been implemented.'); } /// Signs in the user with the options specified to [init]. - Future signIn() async { + Future signIn() async { throw UnimplementedError('signIn() has not been implemented.'); } /// Returns the Tokens used to authenticate other API calls. Future getTokens( - {@required String email, bool shouldRecoverAuth}) async { + {required String email, bool? shouldRecoverAuth}) async { throw UnimplementedError('getTokens() has not been implemented.'); } @@ -118,7 +119,7 @@ abstract class GoogleSignInPlatform { } /// Clears any cached information that the plugin may be holding on to. - Future clearAuthCache({@required String token}) async { + Future clearAuthCache({required String token}) async { throw UnimplementedError('clearAuthCache() has not been implemented.'); } diff --git a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart index 4d2a34fe0fe7..b36676e2376d 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart @@ -5,7 +5,7 @@ import 'dart:async'; import 'package:flutter/services.dart'; -import 'package:meta/meta.dart' show required, visibleForTesting; +import 'package:meta/meta.dart' show visibleForTesting; import '../google_sign_in_platform_interface.dart'; import 'types.dart'; @@ -20,11 +20,12 @@ class MethodChannelGoogleSignIn extends GoogleSignInPlatform { const MethodChannel('plugins.flutter.io/google_sign_in'); @override - Future init( - {@required String hostedDomain, - List scopes = const [], - SignInOption signInOption = SignInOption.standard, - String clientId}) { + Future init({ + List scopes = const [], + SignInOption signInOption = SignInOption.standard, + String? hostedDomain, + String? clientId, + }) { return channel.invokeMethod('init', { 'signInOption': signInOption.toString(), 'scopes': scopes, @@ -33,14 +34,14 @@ class MethodChannelGoogleSignIn extends GoogleSignInPlatform { } @override - Future signInSilently() { + Future signInSilently() { return channel .invokeMapMethod('signInSilently') .then(getUserDataFromMap); } @override - Future signIn() { + Future signIn() { return channel .invokeMapMethod('signIn') .then(getUserDataFromMap); @@ -48,12 +49,12 @@ class MethodChannelGoogleSignIn extends GoogleSignInPlatform { @override Future getTokens( - {String email, bool shouldRecoverAuth = true}) { + {required String email, bool? shouldRecoverAuth = true}) { return channel .invokeMapMethod('getTokens', { 'email': email, 'shouldRecoverAuth': shouldRecoverAuth, - }).then(getTokenDataFromMap); + }).then((result) => getTokenDataFromMap(result!)); } @override @@ -67,23 +68,23 @@ class MethodChannelGoogleSignIn extends GoogleSignInPlatform { } @override - Future isSignedIn() { - return channel.invokeMethod('isSignedIn'); + Future isSignedIn() async { + return (await channel.invokeMethod('isSignedIn'))!; } @override - Future clearAuthCache({String token}) { + Future clearAuthCache({String? token}) { return channel.invokeMethod( 'clearAuthCache', - {'token': token}, + {'token': token}, ); } @override - Future requestScopes(List scopes) { - return channel.invokeMethod( + Future requestScopes(List scopes) async { + return (await channel.invokeMethod( 'requestScopes', >{'scopes': scopes}, - ); + ))!; } } diff --git a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/types.dart b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/types.dart index c60402200bdd..a4c5906723dd 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/types.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/types.dart @@ -24,15 +24,19 @@ enum SignInOption { /// Holds information about the signed in user. class GoogleSignInUserData { - /// Uses the given data to construct an instance. Any of these parameters - /// could be null. - GoogleSignInUserData( - {this.displayName, this.email, this.id, this.photoUrl, this.idToken}); + /// Uses the given data to construct an instance. + GoogleSignInUserData({ + required this.email, + required this.id, + this.displayName, + this.photoUrl, + this.idToken, + }); /// The display name of the signed in user. /// /// Not guaranteed to be present for all users, even when configured. - String displayName; + String? displayName; /// The email address of the signed in user. /// @@ -56,15 +60,15 @@ class GoogleSignInUserData { /// The photo url of the signed in user if the user has a profile picture. /// /// Not guaranteed to be present for all users, even when configured. - String photoUrl; + String? photoUrl; /// A token that can be sent to your own server to verify the authentication /// data. - String idToken; + String? idToken; @override int get hashCode => - hashObjects([displayName, email, id, photoUrl, idToken]); + hashObjects([displayName, email, id, photoUrl, idToken]); @override bool operator ==(dynamic other) { @@ -81,7 +85,7 @@ class GoogleSignInUserData { /// Holds authentication data after sign in. class GoogleSignInTokenData { - /// Either or both parameters may be null. + /// Build `GoogleSignInTokenData`. GoogleSignInTokenData({ this.idToken, this.accessToken, @@ -89,13 +93,13 @@ class GoogleSignInTokenData { }); /// An OpenID Connect ID token for the authenticated user. - String idToken; + String? idToken; /// The OAuth2 access token used to access Google services. - String accessToken; + String? accessToken; /// Server auth code used to access Google Login - String serverAuthCode; + String? serverAuthCode; @override int get hashCode => hash3(idToken, accessToken, serverAuthCode); diff --git a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/utils.dart b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/utils.dart index 1ae828604af6..f6236d4ca12e 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/utils.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/utils.dart @@ -5,23 +5,20 @@ import '../google_sign_in_platform_interface.dart'; /// Converts user data coming from native code into the proper platform interface type. -GoogleSignInUserData getUserDataFromMap(Map data) { +GoogleSignInUserData? getUserDataFromMap(Map? data) { if (data == null) { return null; } return GoogleSignInUserData( + email: data['email']!, + id: data['id']!, displayName: data['displayName'], - email: data['email'], - id: data['id'], photoUrl: data['photoUrl'], idToken: data['idToken']); } /// Converts token data coming from native code into the proper platform interface type. GoogleSignInTokenData getTokenDataFromMap(Map data) { - if (data == null) { - return null; - } return GoogleSignInTokenData( idToken: data['idToken'], accessToken: data['accessToken'], diff --git a/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml b/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml index 8edeba0072a8..4480debc9ba3 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml @@ -3,20 +3,20 @@ description: A common platform interface for the google_sign_in plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.1.3 +version: 2.0.0-nullsafety dependencies: flutter: sdk: flutter - meta: ^1.0.5 - quiver: ">=2.0.0 <3.0.0" + meta: ^1.3.0-nullsafety.6 + quiver: ^3.0.0-nullsafety.2 dev_dependencies: flutter_test: sdk: flutter - mockito: ^4.1.1 - pedantic: ^1.8.0 + mockito: ^5.0.0-nullsafety.1 + pedantic: ^1.10.0-nullsafety.1 environment: - sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.10.0" + sdk: ">=2.12.0-0 <3.0.0" + flutter: ">=1.12.13+hotfix.5" diff --git a/packages/google_sign_in/google_sign_in_platform_interface/test/google_sign_in_platform_interface_test.dart b/packages/google_sign_in/google_sign_in_platform_interface/test/google_sign_in_platform_interface_test.dart index f411b8992821..e2565d799e1f 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/test/google_sign_in_platform_interface_test.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/test/google_sign_in_platform_interface_test.dart @@ -15,7 +15,7 @@ void main() { test('Cannot be implemented with `implements`', () { expect(() { GoogleSignInPlatform.instance = ImplementsGoogleSignInPlatform(); - }, throwsAssertionError); + }, throwsA(isA())); }); test('Can be extended', () { @@ -23,14 +23,16 @@ void main() { }); test('Can be mocked with `implements`', () { - final ImplementsGoogleSignInPlatform mock = - ImplementsGoogleSignInPlatform(); - when(mock.isMock).thenReturn(true); - GoogleSignInPlatform.instance = mock; + GoogleSignInPlatform.instance = ImplementsWithIsMock(); }); }); } +class ImplementsWithIsMock extends Mock implements GoogleSignInPlatform { + @override + bool get isMock => true; +} + class ImplementsGoogleSignInPlatform extends Mock implements GoogleSignInPlatform {} diff --git a/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart b/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart index 5ac34ade1b8d..325f0c10a6ab 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart @@ -29,10 +29,12 @@ const Map kDefaultResponses = { 'disconnect': null, 'isSignedIn': true, 'getTokens': kTokenData, + 'requestScopes': true, }; -final GoogleSignInUserData kUser = getUserDataFromMap(kUserData); -final GoogleSignInTokenData kToken = getTokenDataFromMap(kTokenData); +final GoogleSignInUserData? kUser = getUserDataFromMap(kUserData); +final GoogleSignInTokenData? kToken = + getTokenDataFromMap(kTokenData as Map); void main() { TestWidgetsFlutterBinding.ensureInitialized(); @@ -42,7 +44,8 @@ void main() { final MethodChannel channel = googleSignIn.channel; final List log = []; - Map responses; // Some tests mutate some kDefaultResponses + late Map + responses; // Some tests mutate some kDefaultResponses setUp(() { responses = Map.from(kDefaultResponses); From d950dda867539370af8b79d9b921f569cb074390 Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Fri, 15 Jan 2021 15:49:23 -0800 Subject: [PATCH 0046/1565] [script] Update build_all_plugins_app to exclude some plugins in `master`. (#3432) --- script/build_all_plugins_app.sh | 4 ++++ script/nnbd_plugins.sh | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/script/build_all_plugins_app.sh b/script/build_all_plugins_app.sh index ca97c05f8ee4..72390c213da9 100755 --- a/script/build_all_plugins_app.sh +++ b/script/build_all_plugins_app.sh @@ -56,6 +56,10 @@ ALL_EXCLUDED=($EXCLUDED) if [ "$CHANNEL" == "stable" ]; then ALL_EXCLUDED=("$EXCLUDED,$EXCLUDED_PLUGINS_FROM_STABLE") fi +# Exclude non-nnbd plugins from master. +if [ "$CHANNEL" != "stable" ]; then + ALL_EXCLUDED=("$EXCLUDED,$EXCLUDED_PLUGINS_FROM_MASTER") +fi echo "Excluding the following plugins: $ALL_EXCLUDED" diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index 7bc5ac35a3a5..b2ca25bf6836 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -21,4 +21,22 @@ readonly NNBD_PLUGINS_LIST=( "webview_flutter" ) +# This list contains the list of plugins that have *not* been +# migrated to nnbd, and conflict with those that have when +# building the all plugins app. This list should be kept empty. + +readonly NON_NNBD_PLUGINS_LIST=( + # "android_alarm_manager" + "camera" + # "file_selector" + # "google_maps_flutter" + # "image_picker" + # "in_app_purchase" + # "quick_actions" + # "sensors" + # "shared_preferences" + # "wifi_info_flutter" +) + export EXCLUDED_PLUGINS_FROM_STABLE=$(IFS=, ; echo "${NNBD_PLUGINS_LIST[*]}") +export EXCLUDED_PLUGINS_FROM_MASTER=$(IFS=, ; echo "${NON_NNBD_PLUGINS_LIST[*]}") From 6ee63e8802d28ac1967b07332d413657529e974e Mon Sep 17 00:00:00 2001 From: Anton Borries Date: Sat, 16 Jan 2021 01:59:57 +0100 Subject: [PATCH 0047/1565] [google_maps_flutter_web] Support for Holes in Polygons (#3412) --- AUTHORS | 1 + .../google_maps_flutter_web/CHANGELOG.md | 5 ++ .../lib/src/convert.dart | 13 ++++- .../google_maps_flutter_web/pubspec.yaml | 4 +- .../google_maps_controller_integration.dart | 19 +++++++ .../test/test_driver/shapes_integration.dart | 55 +++++++++++++++++++ .../test/web/index.html | 2 +- 7 files changed, 94 insertions(+), 5 deletions(-) diff --git a/AUTHORS b/AUTHORS index 09bab9d34d02..dabc20108f28 100644 --- a/AUTHORS +++ b/AUTHORS @@ -60,3 +60,4 @@ Eitan Schwartz Chris Rutkowski Juan Alvarez Aleksandr Yurkovskiy +Anton Borries \ No newline at end of file diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md index 2d03ab254bc0..940419a215fc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.1.0+10 + +* Update `package:google_maps_flutter_platform_interface` to `^1.1.0`. +* Add support for Polygon Holes. + ## 0.1.0+9 * Update Flutter SDK constraint. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index 551c1572b1bb..c9fd1cd55d3b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -366,6 +366,11 @@ Set _rawOptionsToInitialPolygons(Map rawOptions) { points: rawPolygon['points'] ?.map((rawPoint) => LatLng.fromJson(rawPoint)) ?.toList(), + holes: rawPolygon['holes'] + ?.map>((List hole) => hole + ?.map((rawPoint) => LatLng.fromJson(rawPoint)) + ?.toList()) + ?.toList(), ); }) ?? []); @@ -473,9 +478,13 @@ gmaps.CircleOptions _circleOptionsFromCircle(Circle circle) { gmaps.PolygonOptions _polygonOptionsFromPolygon( gmaps.GMap googleMap, Polygon polygon) { - List paths = []; + List path = []; polygon.points.forEach((point) { - paths.add(_latLngToGmLatLng(point)); + path.add(_latLngToGmLatLng(point)); + }); + List> paths = [path]; + polygon.holes?.forEach((hole) { + paths.add(hole.map((point) => _latLngToGmLatLng(point)).toList()); }); return gmaps.PolygonOptions() ..paths = paths diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index b41e24c25357..bd879553a06d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -1,7 +1,7 @@ name: google_maps_flutter_web description: Web platform implementation of google_maps_flutter homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter -version: 0.1.0+9 +version: 0.1.0+10 flutter: plugin: @@ -16,7 +16,7 @@ dependencies: flutter_web_plugins: sdk: flutter meta: ^1.1.7 - google_maps_flutter_platform_interface: ^1.0.5 + google_maps_flutter_platform_interface: ^1.1.0 google_maps: ^3.4.5 stream_transform: ^1.2.0 sanitize_html: ^1.4.1 diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration.dart index 70d4452e411f..302057f0ea57 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration.dart @@ -166,6 +166,22 @@ void main() { [43.354762, -5.850824], ], }, + { + 'polygonId': 'polygon-2-with-holes', + 'points': [ + [43.355114, -5.851333], + [43.354797, -5.851860], + [43.354469, -5.851318], + [43.354762, -5.850824], + ], + 'holes': [ + [ + [41.354797, -6.851860], + [41.354469, -6.851318], + [41.354762, -6.850824], + ] + ] + }, ], 'polylinesToAdd': [ { @@ -202,6 +218,9 @@ void main() { expect(capturedMarkers.first.infoWindow.snippet, 'snippet for test'); expect(capturedMarkers.first.infoWindow.title, 'title for test'); expect(capturedPolygons.first.polygonId.value, 'polygon-1'); + expect(capturedPolygons.elementAt(1).polygonId.value, + 'polygon-2-with-holes'); + expect(capturedPolygons.elementAt(1).holes, isNot(null)); expect(capturedPolylines.first.polylineId.value, 'polyline-1'); }); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration.dart index 0c92c6a924e7..4d5c2b17cc56 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration.dart @@ -10,6 +10,8 @@ import 'dart:ui'; import 'package:integration_test/integration_test.dart'; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; +import 'package:google_maps/google_maps.dart' as gmaps; +import 'package:google_maps/google_maps_geometry.dart' as geometry; import 'package:flutter_test/flutter_test.dart'; // This value is used when comparing the results of @@ -190,6 +192,59 @@ void main() { expect(polygon.get('strokeColor'), '#c0ffee'); expect(polygon.get('strokeOpacity'), closeTo(1, _acceptableDelta)); }); + + testWidgets('Handle Polygons with holes', (WidgetTester tester) async { + final polygons = { + Polygon( + polygonId: PolygonId('BermudaTriangle'), + points: [ + LatLng(25.774, -80.19), + LatLng(18.466, -66.118), + LatLng(32.321, -64.757), + ], + holes: [ + [ + LatLng(28.745, -70.579), + LatLng(29.57, -67.514), + LatLng(27.339, -66.668), + ], + ], + ), + }; + + controller.addPolygons(polygons); + + expect(controller.polygons.length, 1); + expect(controller.polygons, contains(PolygonId('BermudaTriangle'))); + expect(controller.polygons, isNot(contains(PolygonId('66')))); + }); + + testWidgets('Polygon with hole has a hole', (WidgetTester tester) async { + final polygons = { + Polygon( + polygonId: PolygonId('BermudaTriangle'), + points: [ + LatLng(25.774, -80.19), + LatLng(18.466, -66.118), + LatLng(32.321, -64.757), + ], + holes: [ + [ + LatLng(28.745, -70.579), + LatLng(29.57, -67.514), + LatLng(27.339, -66.668), + ], + ], + ), + }; + + controller.addPolygons(polygons); + + final polygon = controller.polygons.values.first.polygon; + final pointInHole = gmaps.LatLng(28.632, -68.401); + + expect(geometry.poly.containsLocation(pointInHole, polygon), false); + }); }); group('PolylinesController', () { diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/web/index.html b/packages/google_maps_flutter/google_maps_flutter_web/test/web/index.html index 3b7e4edc3df1..03feba172d74 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/test/web/index.html +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/web/index.html @@ -5,7 +5,7 @@ Browser Tests - + From 5cff819332b13947c405cd6b8df306465df49829 Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Fri, 15 Jan 2021 18:39:53 -0800 Subject: [PATCH 0048/1565] [google_sign_in, url_launcher] Document unendorsement of web. (#3436) Add some documentation to the CHANGELOGs to mention that null-safety is still not supported by web plugins, so they're being un-endorsed. --- packages/google_sign_in/google_sign_in/CHANGELOG.md | 5 +++++ packages/google_sign_in/google_sign_in/pubspec.yaml | 6 +++--- packages/url_launcher/url_launcher/CHANGELOG.md | 5 +++++ packages/url_launcher/url_launcher/pubspec.yaml | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/google_sign_in/google_sign_in/CHANGELOG.md b/packages/google_sign_in/google_sign_in/CHANGELOG.md index d87df7466312..85c8cc491105 100644 --- a/packages/google_sign_in/google_sign_in/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in/CHANGELOG.md @@ -1,6 +1,11 @@ +## 5.0.0-nullsafety.1 + +* Document that the web plugin is not endorsed in the `nullsafety` prerelease for now. + ## 5.0.0-nullsafety * Migrate to nnbd. +* **Breaking change**: web plugins aren't endorsed in null-safe plugins yet. ## 4.5.9 diff --git a/packages/google_sign_in/google_sign_in/pubspec.yaml b/packages/google_sign_in/google_sign_in/pubspec.yaml index 2a2506a38357..ca1fe8d829b8 100644 --- a/packages/google_sign_in/google_sign_in/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/pubspec.yaml @@ -2,7 +2,7 @@ name: google_sign_in description: Flutter plugin for Google Sign-In, a secure authentication system for signing in with a Google account on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in -version: 5.0.0-nullsafety +version: 5.0.0-nullsafety.1 flutter: plugin: @@ -12,8 +12,8 @@ flutter: pluginClass: GoogleSignInPlugin ios: pluginClass: FLTGoogleSignInPlugin - web: - default_package: google_sign_in_web + #web: + # default_package: google_sign_in_web dependencies: google_sign_in_platform_interface: ^2.0.0-nullsafety diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index 73852cdfea12..fb66bcd99c1f 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.0.0-nullsafety.5 + +* Document that the web plugin is not endorsed in the `nullsafety` prerelease for now. + ## 6.0.0-nullsafety.4 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. @@ -17,6 +21,7 @@ ## 6.0.0-nullsafety * Migrate to null safety. +* **Breaking change**: web plugins aren't endorsed in null-safe plugins yet. ## 5.7.13 diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index 871c43ced733..2f9c38a22f36 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -2,7 +2,7 @@ name: url_launcher description: Flutter plugin for launching a URL on Android and iOS. Supports web, phone, SMS, and email schemes. homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher -version: 6.0.0-nullsafety.4 +version: 6.0.0-nullsafety.5 flutter: plugin: From faa26ec364cd6d3c738d73526ea55a95b7f4ab1a Mon Sep 17 00:00:00 2001 From: Emmanuel Garcia Date: Fri, 15 Jan 2021 19:14:03 -0800 Subject: [PATCH 0049/1565] [plugin_platform_interface] Use Mockito nnbd (#3437) --- packages/plugin_platform_interface/CHANGELOG.md | 4 ++++ .../lib/plugin_platform_interface.dart | 2 +- packages/plugin_platform_interface/pubspec.yaml | 4 ++-- .../test/plugin_platform_interface_test.dart | 2 -- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/plugin_platform_interface/CHANGELOG.md b/packages/plugin_platform_interface/CHANGELOG.md index 7df1834966dd..96533f01c10f 100644 --- a/packages/plugin_platform_interface/CHANGELOG.md +++ b/packages/plugin_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.0-nullsafety.2 + +* Use Mockito null safe. + ## 1.1.0-nullsafety.1 * Bump Dart SDK to support null safety. diff --git a/packages/plugin_platform_interface/lib/plugin_platform_interface.dart b/packages/plugin_platform_interface/lib/plugin_platform_interface.dart index cd87b04dc739..6e425a19a048 100644 --- a/packages/plugin_platform_interface/lib/plugin_platform_interface.dart +++ b/packages/plugin_platform_interface/lib/plugin_platform_interface.dart @@ -43,7 +43,7 @@ abstract class PlatformInterface { /// Pass a private, class-specific `const Object()` as the `token`. PlatformInterface({required Object token}) : _instanceToken = token; - final Object _instanceToken; + final Object? _instanceToken; /// Ensures that the platform instance has a token that matches the /// provided token and throws [AssertionError] if not. diff --git a/packages/plugin_platform_interface/pubspec.yaml b/packages/plugin_platform_interface/pubspec.yaml index 05fc918bf9b5..084e577dbf99 100644 --- a/packages/plugin_platform_interface/pubspec.yaml +++ b/packages/plugin_platform_interface/pubspec.yaml @@ -12,7 +12,7 @@ description: Reusable base class for Flutter plugin platform interfaces. # be done when absolutely necessary and after the ecosystem has already migrated to 1.X.Y version # that is forward compatible with 2.0.0 (ideally the ecosystem have migrated to depend on: # `plugin_platform_interface: >=1.X.Y <3.0.0`). -version: 1.1.0-nullsafety.1 +version: 1.1.0-nullsafety.2 repository: https://github.com/flutter/plugins/tree/master/packages/plugin_platform_interface @@ -23,6 +23,6 @@ dependencies: meta: ^1.3.0-nullsafety.3 dev_dependencies: - mockito: ^4.1.1 + mockito: ^5.0.0-nullsafety.2 test: ^1.10.0-nullsafety.1 pedantic: ^1.10.0-nullsafety.1 diff --git a/packages/plugin_platform_interface/test/plugin_platform_interface_test.dart b/packages/plugin_platform_interface/test/plugin_platform_interface_test.dart index b07dd4dcede1..0488c20f3efb 100644 --- a/packages/plugin_platform_interface/test/plugin_platform_interface_test.dart +++ b/packages/plugin_platform_interface/test/plugin_platform_interface_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(egarciad): Remove once Mockito is migrated to null safety. -// @dart = 2.9 import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; From 172338d02b177353bf517e5826cf6a25b5f0d887 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 19 Jan 2021 10:59:04 -0800 Subject: [PATCH 0050/1565] combine release messages and versions (#3435) --- packages/camera/camera/CHANGELOG.md | 47 +++++++++-------------------- packages/camera/camera/pubspec.yaml | 2 +- 2 files changed, 15 insertions(+), 34 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 66398996e053..55145ffc82e7 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,38 +1,19 @@ -## 0.7.0+5 - -* Fixes crash when taking a picture on iOS devices without flash. - -## 0.7.0+4 - -* Make sure the configured zoom scale is copied over to the final capture builder on Android. Fixes the issue where the preview is zoomed but the final picture is not. - -## 0.7.0+3 - -* Fixes crash with using inner camera on some Android devices. - -## 0.7.0+2 - -* Improved error feedback by differentiating between uninitialized and disposed camera controllers. - -## 0.7.0+1 - -* Fixes picture captures causing a crash on some Huawei devices. - ## 0.7.0 -* Added support for capture orientation locking on Android and iOS. -* Fixed camera preview not rotating correctly on Android and iOS. -* Fixed camera preview sometimes appearing stretched on Android and iOS. -* Fixed videos & photos saving with the incorrect rotation on iOS. -* BREAKING CHANGE: `CameraValue.aspectRatio` now returns `width / height` rather than `height / width`. - -## 0.6.6 - -* Adds auto focus support for Android and iOS implementations. - -## 0.6.5 - -* Adds ImageFormat selection for ImageStream and Video(iOS only). +* BREAKING CHANGE: `CameraValue.aspectRatio` now returns `width / height` rather than `height / width`. [(commit)](https://github.com/flutter/plugins/commit/100c7470d4066b1d0f8f7e4ec6d7c943e736f970) + * Added support for capture orientation locking on Android and iOS. + * Fixed camera preview not rotating correctly on Android and iOS. + * Fixed camera preview sometimes appearing stretched on Android and iOS. + * Fixed videos & photos saving with the incorrect rotation on iOS. +* New Features: + * Adds auto focus support for Android and iOS implementations. [(commmit)](https://github.com/flutter/plugins/commit/71a831790220f898bf8120c8a23840ac6e742db5) + * Adds ImageFormat selection for ImageStream and Video(iOS only). [(commit)](https://github.com/flutter/plugins/commit/da1b4638b750a5ff832d7be86a42831c42c6d6c0) +* Bug Fixes: + * Fixes crash when taking a picture on iOS devices without flash. [(commit)](https://github.com/flutter/plugins/commit/831344490984b1feec007afc9c8595d80b6c13f4) + * Make sure the configured zoom scale is copied over to the final capture builder on Android. Fixes the issue where the preview is zoomed but the final picture is not. [(commit)](https://github.com/flutter/plugins/commit/5916f55664e1772a4c3f0c02c5c71fc11e491b76) + * Fixes crash with using inner camera on some Android devices. [(commit)](https://github.com/flutter/plugins/commit/980b674cb4020c1927917426211a87e275346d5e) + * Improved error feedback by differentiating between uninitialized and disposed camera controllers. [(commit)](https://github.com/flutter/plugins/commit/d0b7109f6b00a0eda03506fed2c74cc123ffc6f3) + * Fixes picture captures causing a crash on some Huawei devices. [(commit)](https://github.com/flutter/plugins/commit/6d18db83f00f4861ffe485aba2d1f8aa08845ce6) ## 0.6.4+5 diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 406ff94ab1b9..b0ebb9c16361 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.7.0+5 +version: 0.7.0 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From bea4b14a6a6f41f503a0887b8e0504fa63778381 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Wed, 20 Jan 2021 07:16:20 -0800 Subject: [PATCH 0051/1565] Add Labeler Github Action (#3433) --- .github/labeler.yml | 86 ++++++++++++++++++++++++ .github/workflows/pull_request_label.yml | 20 ++++++ 2 files changed, 106 insertions(+) create mode 100644 .github/labeler.yml create mode 100644 .github/workflows/pull_request_label.yml diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 000000000000..66dc68f1fbbe --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,86 @@ +'p: android_alarm_manager': + - packages/android_alarm_manager/**/* + +'p: android_intent': + - packages/android_intent/**/* + +'p: battery': + - packages/battery/**/* + +'p: camera': + - packages/camera/**/* + +'p: connectivity': + - packages/connectivity/**/* + +'p: cross_file': + - packages/cross_file/**/* + +'p: device_info': + - packages/device_info/**/* + +'p: e2e': + - packages/e2e/**/* + +'p: espresso': + - packages/espresso/**/* + +'p: file_selector': + - packages/file_selector/**/* + +'p: flutter_plugin_android_lifecycle': + - packages/flutter_plugin_android_lifecycle/**/* + +'p: google_maps_flutter': + - packages/google_maps_flutter/**/* + +'p: google_sign_in': + - packages/google_sign_in/**/* + +'p: image_picker': + - packages/image_picker/**/* + +'p: in_app_purchase': + - packages/in_app_purchase/**/* + +'p: integration_test': + - packages/integration_test/**/* + +'p: ios_platform_images': + - packages/ios_platform_images/**/* + +'p: local_auth': + - packages/local_auth/**/* + +'p: package_info': + - packages/package_info/**/* + +'p: path_provider': + - packages/path_provider/**/* + +'p: plugin_platform_interface': + - packages/plugin_platform_interface/**/* + +'p: quick_actions': + - packages/quick_actions/**/* + +'p: sensors': + - packages/sensors/**/* + +'p: share': + - packages/share/**/* + +'p: shared_preferences': + - packages/shared_preferences/**/* + +'p: url_launcher': + - packages/url_launcher/**/* + +'p: video_player': + - packages/video_player/**/* + +'p: webview_flutter': + - packages/webview_flutter/**/* + +'p: wifi_info_flutter': + - packages/wifi_info_flutter/**/* diff --git a/.github/workflows/pull_request_label.yml b/.github/workflows/pull_request_label.yml new file mode 100644 index 000000000000..5016184d6d11 --- /dev/null +++ b/.github/workflows/pull_request_label.yml @@ -0,0 +1,20 @@ +# This workflow applies labels to pull requests based on the +# paths that are modified in the pull request. +# +# Edit `.github/labeler.yml` to configure labels. +# +# For more information, see: https://github.com/actions/labeler + +name: Pull Request Labeler + +on: + - pull_request_target + +jobs: + label: + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@main + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + sync-labels: true From f3024731b090659edaa92d01416549c690f65678 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Wed, 20 Jan 2021 14:07:43 -0800 Subject: [PATCH 0052/1565] Windows nullsafety prep (#3442) shared_preferences_windows depends on path_provider_windows, and both use 'ffi'. This relaxes the 'ffi' version constraint on shared_preferences_windows to allow path_provider_windows to be migrated to null-safety (which requires updating to the nullsafe version of ffi). Part of https://github.com/flutter/flutter/issues/70229 --- .../shared_preferences_windows/CHANGELOG.md | 4 ++++ .../shared_preferences_windows/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md b/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md index ecc790ef9bab..f6a199d52cb0 100644 --- a/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.2+2 + +* Relax 'ffi' version constraint. + ## 0.0.2+1 * Update Flutter SDK constraint. diff --git a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml index ce559d5ea3fb..2970b3ff053e 100644 --- a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml @@ -1,7 +1,7 @@ name: shared_preferences_windows description: Windows implementation of shared_preferences homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_windows -version: 0.0.2+1 +version: 0.0.2+2 flutter: plugin: @@ -18,7 +18,7 @@ dependencies: shared_preferences_platform_interface: ^1.0.0 flutter: sdk: flutter - ffi: ^0.1.3 + ffi: ">=0.1.3 < 0.3.0" file: ">=5.1.0 <7.0.0" meta: ^1.1.7 path: ^1.6.4 From 31923c805dbb03201fc9b3a97ca99c4c09838b1a Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Thu, 21 Jan 2021 08:54:52 -0800 Subject: [PATCH 0053/1565] [path_provider] Migrate path_provider_windows to nullsafety (#3410) Migrates path_provider_windows to null-safety. Part of flutter/flutter#70229 --- .../path_provider_windows/CHANGELOG.md | 4 ++ .../lib/src/path_provider_windows_real.dart | 36 ++++++++---------- .../lib/src/path_provider_windows_stub.dart | 2 +- .../path_provider_windows/pubspec.yaml | 16 ++++---- .../test/path_provider_windows_test.dart | 38 ++++++++++++------- 5 files changed, 54 insertions(+), 42 deletions(-) diff --git a/packages/path_provider/path_provider_windows/CHANGELOG.md b/packages/path_provider/path_provider_windows/CHANGELOG.md index ef1f5043a2b7..ea271681e63c 100644 --- a/packages/path_provider/path_provider_windows/CHANGELOG.md +++ b/packages/path_provider/path_provider_windows/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.0-nullsafety + +* Migrate to null safety + ## 0.0.4+4 * Update Flutter SDK constraint. diff --git a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart index e1063957879e..856249036b62 100644 --- a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart +++ b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart @@ -22,20 +22,19 @@ import 'folders.dart'; class VersionInfoQuerier { /// Returns the value for [key] in [versionInfo]s English strings section, or /// null if there is no such entry, or if versionInfo is null. - getStringValue(Pointer versionInfo, key) { + getStringValue(Pointer? versionInfo, key) { if (versionInfo == null) { return null; } const kEnUsLanguageCode = '040904e4'; final keyPath = TEXT('\\StringFileInfo\\$kEnUsLanguageCode\\$key'); final length = allocate(); - final valueAddress = allocate(); + final valueAddress = allocate>(); try { if (VerQueryValue(versionInfo, keyPath, valueAddress, length) == 0) { return null; } - return Pointer.fromAddress(valueAddress.value) - .unpackString(length.value); + return valueAddress.value.unpackString(length.value); } finally { free(keyPath); free(length); @@ -54,7 +53,7 @@ class PathProviderWindows extends PathProviderPlatform { /// This is typically the same as the TMP environment variable. @override - Future getTemporaryPath() async { + Future getTemporaryPath() async { final buffer = allocate(count: MAX_PATH + 1).cast(); String path; @@ -88,7 +87,7 @@ class PathProviderWindows extends PathProviderPlatform { } @override - Future getApplicationSupportPath() async { + Future getApplicationSupportPath() async { final appDataRoot = await getPath(WindowsKnownFolder.RoamingAppData); final directory = Directory( path.join(appDataRoot, _getApplicationSpecificSubdirectory())); @@ -105,25 +104,23 @@ class PathProviderWindows extends PathProviderPlatform { } @override - Future getApplicationDocumentsPath() => + Future getApplicationDocumentsPath() => getPath(WindowsKnownFolder.Documents); @override - Future getDownloadsPath() => getPath(WindowsKnownFolder.Downloads); + Future getDownloadsPath() => getPath(WindowsKnownFolder.Downloads); /// Retrieve any known folder from Windows. /// /// folderID is a GUID that represents a specific known folder ID, drawn from /// [WindowsKnownFolder]. Future getPath(String folderID) { - final pathPtrPtr = allocate(); - Pointer pathPtr; + final pathPtrPtr = allocate>(); + final Pointer knownFolderID = calloc()..setGUID(folderID); try { - GUID knownFolderID = GUID.fromString(folderID); - final hr = SHGetKnownFolderPath( - knownFolderID.addressOf, // ignore: deprecated_member_use + knownFolderID, KF_FLAG_DEFAULT, NULL, pathPtrPtr, @@ -135,12 +132,11 @@ class PathProviderWindows extends PathProviderPlatform { } } - pathPtr = Pointer.fromAddress(pathPtrPtr.value); - final path = pathPtr.unpackString(MAX_PATH); + final path = pathPtrPtr.value.unpackString(MAX_PATH); return Future.value(path); } finally { - CoTaskMemFree(pathPtr.cast()); free(pathPtrPtr); + free(knownFolderID); } } @@ -155,13 +151,13 @@ class PathProviderWindows extends PathProviderPlatform { /// - If the product name isn't there, it will use the exe's filename (without /// extension). String _getApplicationSpecificSubdirectory() { - String companyName; - String productName; + String? companyName; + String? productName; final Pointer moduleNameBuffer = allocate(count: MAX_PATH + 1).cast(); final Pointer unused = allocate(); - Pointer infoBuffer; + Pointer? infoBuffer; try { // Get the module name. final moduleNameLength = GetModuleFileName(0, moduleNameBuffer, MAX_PATH); @@ -207,7 +203,7 @@ class PathProviderWindows extends PathProviderPlatform { /// https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions /// /// If after sanitizing the string is empty, returns null. - String _sanitizedDirectoryName(String rawString) { + String? _sanitizedDirectoryName(String? rawString) { if (rawString == null) { return null; } diff --git a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_stub.dart b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_stub.dart index 11a946542f26..1a0e84e8f0da 100644 --- a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_stub.dart +++ b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_stub.dart @@ -19,7 +19,7 @@ class PathProviderWindows extends PathProviderPlatform { } /// Stub; see comment on VersionInfoQuerier. - VersionInfoQuerier versionInfoQuerier; + VersionInfoQuerier versionInfoQuerier = VersionInfoQuerier(); /// Match PathProviderWindows so that the analyzer won't report invalid /// overrides if tests provide fake PathProviderWindows implementations. diff --git a/packages/path_provider/path_provider_windows/pubspec.yaml b/packages/path_provider/path_provider_windows/pubspec.yaml index 62185f42e765..55c73c87ad19 100644 --- a/packages/path_provider/path_provider_windows/pubspec.yaml +++ b/packages/path_provider/path_provider_windows/pubspec.yaml @@ -1,7 +1,7 @@ name: path_provider_windows description: Windows implementation of the path_provider plugin homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_windows -version: 0.0.4+4 +version: 0.1.0-nullsafety flutter: plugin: @@ -11,19 +11,19 @@ flutter: pluginClass: none dependencies: - path_provider_platform_interface: ^1.0.3 - meta: ^1.0.5 - path: ^1.6.4 + path_provider_platform_interface: ^2.0.0-nullsafety + meta: ^1.3.0-nullsafety.6 + path: ^1.8.0-nullsafety.3 flutter: sdk: flutter - ffi: ^0.1.3 - win32: ^1.7.1 + ffi: ^0.2.0-nullsafety.1 + win32: ^2.0.0-nullsafety.8 dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0-nullsafety.3 environment: - sdk: ">=2.1.0 <3.0.0" + sdk: '>=2.12.0-0 <3.0.0' flutter: ">=1.12.13+hotfix.4" diff --git a/packages/path_provider/path_provider_windows/test/path_provider_windows_test.dart b/packages/path_provider/path_provider_windows/test/path_provider_windows_test.dart index 83ceea9cdf0c..989f3673ac63 100644 --- a/packages/path_provider/path_provider_windows/test/path_provider_windows_test.dart +++ b/packages/path_provider/path_provider_windows/test/path_provider_windows_test.dart @@ -13,7 +13,7 @@ class FakeVersionInfoQuerier implements VersionInfoQuerier { final Map responses; - getStringValue(Pointer versionInfo, key) => responses[key]; + getStringValue(Pointer? versionInfo, key) => responses[key]; } void main() { @@ -40,8 +40,11 @@ void main() { 'ProductName': 'Amazing App', }); final path = await pathProvider.getApplicationSupportPath(); - expect(path, endsWith(r'AppData\Roaming\A Company\Amazing App')); - expect(Directory(path).existsSync(), isTrue); + expect(path, isNotNull); + if (path != null) { + expect(path, endsWith(r'AppData\Roaming\A Company\Amazing App')); + expect(Directory(path).existsSync(), isTrue); + } }, skip: !Platform.isWindows); test('getApplicationSupportPath with missing company', () async { @@ -50,8 +53,11 @@ void main() { 'ProductName': 'Amazing App', }); final path = await pathProvider.getApplicationSupportPath(); - expect(path, endsWith(r'AppData\Roaming\Amazing App')); - expect(Directory(path).existsSync(), isTrue); + expect(path, isNotNull); + if (path != null) { + expect(path, endsWith(r'AppData\Roaming\Amazing App')); + expect(Directory(path).existsSync(), isTrue); + } }, skip: !Platform.isWindows); test('getApplicationSupportPath with problematic values', () async { @@ -61,12 +67,15 @@ void main() { 'ProductName': r'A"/Terrible\|App?*Name', }); final path = await pathProvider.getApplicationSupportPath(); - expect( - path, - endsWith(r'AppData\Roaming\' - r'A _Bad_ Company_ Name\' - r'A__Terrible__App__Name')); - expect(Directory(path).existsSync(), isTrue); + expect(path, isNotNull); + if (path != null) { + expect( + path, + endsWith(r'AppData\Roaming\' + r'A _Bad_ Company_ Name\' + r'A__Terrible__App__Name')); + expect(Directory(path).existsSync(), isTrue); + } }, skip: !Platform.isWindows); test('getApplicationSupportPath with a completely invalid company', () async { @@ -76,8 +85,11 @@ void main() { 'ProductName': r'Amazing App', }); final path = await pathProvider.getApplicationSupportPath(); - expect(path, endsWith(r'AppData\Roaming\Amazing App')); - expect(Directory(path).existsSync(), isTrue); + expect(path, isNotNull); + if (path != null) { + expect(path, endsWith(r'AppData\Roaming\Amazing App')); + expect(Directory(path).existsSync(), isTrue); + } }, skip: !Platform.isWindows); test('getApplicationSupportPath with very long app name', () async { From 07cf89a08b8800f3337049654bc5c1c19edd50d0 Mon Sep 17 00:00:00 2001 From: Sander Roest Date: Thu, 21 Jan 2021 19:09:06 +0100 Subject: [PATCH 0054/1565] [camera] Ensure that channel.invokeMethod runs on the main thread (#3444) --- packages/camera/camera/CHANGELOG.md | 4 ++++ .../flutter/plugins/camera/DartMessenger.java | 20 +++++++++++++++++-- packages/camera/camera/pubspec.yaml | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 55145ffc82e7..cc734737182f 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.0+1 + +* Ensure communication from JAVA to Dart is done on the main UI thread. + ## 0.7.0 * BREAKING CHANGE: `CameraValue.aspectRatio` now returns `width / height` rather than `height / width`. [(commit)](https://github.com/flutter/plugins/commit/100c7470d4066b1d0f8f7e4ec6d7c943e736f970) diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java index 5681f723ed80..3892452892d9 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java @@ -4,6 +4,8 @@ package io.flutter.plugins.camera; +import android.os.Handler; +import android.os.Looper; import android.text.TextUtils; import androidx.annotation.Nullable; import io.flutter.embedding.engine.systemchannels.PlatformChannel; @@ -104,7 +106,14 @@ void send(CameraEventType eventType, Map args) { if (cameraChannel == null) { return; } - cameraChannel.invokeMethod(eventType.method, args); + new Handler(Looper.getMainLooper()) + .post( + new Runnable() { + @Override + public void run() { + cameraChannel.invokeMethod(eventType.method, args); + } + }); } void send(DeviceEventType eventType) { @@ -115,6 +124,13 @@ void send(DeviceEventType eventType, Map args) { if (deviceChannel == null) { return; } - deviceChannel.invokeMethod(eventType.method, args); + new Handler(Looper.getMainLooper()) + .post( + new Runnable() { + @Override + public void run() { + deviceChannel.invokeMethod(eventType.method, args); + } + }); } } diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index b0ebb9c16361..b406ce5ba64f 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.7.0 +version: 0.7.0+1 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From c923ef857c5fd13b1543ffa40013b1ca70d81dde Mon Sep 17 00:00:00 2001 From: Anton Borries Date: Thu, 21 Jan 2021 23:51:09 +0100 Subject: [PATCH 0055/1565] [google_maps_flutter_web] Reverse Hole winding when needed (#3440) The Web Version needs the holes in a polygon to be defined in the opposite direction to their parent polygon. This change automatically reverses the definition of a hole, when needed. In debug mode, it'll let the user know that the holes need to be wound differently. Co-authored-by: Anton Borries --- .../google_maps_flutter_web/CHANGELOG.md | 4 +++ .../lib/src/convert.dart | 30 ++++++++++++++++- .../google_maps_flutter_web/pubspec.yaml | 2 +- .../test/test_driver/shapes_integration.dart | 33 +++++++++++++++++++ 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md index 940419a215fc..caa64ec73088 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.1 + +* Auto-reverse holes if they're the same direction as the polygon. [Issue](https://github.com/flutter/flutter/issues/74096). + ## 0.1.0+10 * Update `package:google_maps_flutter_platform_interface` to `^1.1.0`. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index c9fd1cd55d3b..95f481a9bdc5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -482,9 +482,23 @@ gmaps.PolygonOptions _polygonOptionsFromPolygon( polygon.points.forEach((point) { path.add(_latLngToGmLatLng(point)); }); + final polygonDirection = _isPolygonClockwise(path); List> paths = [path]; + int holeIndex = 0; polygon.holes?.forEach((hole) { - paths.add(hole.map((point) => _latLngToGmLatLng(point)).toList()); + List holePath = + hole.map((point) => _latLngToGmLatLng(point)).toList(); + if (_isPolygonClockwise(holePath) == polygonDirection) { + holePath = holePath.reversed.toList(); + if (kDebugMode) { + print( + 'Hole [$holeIndex] in Polygon [${polygon.polygonId.value}] has been reversed.' + ' Ensure holes in polygons are "wound in the opposite direction to the outer path."' + ' More info: https://github.com/flutter/flutter/issues/74096'); + } + } + paths.add(holePath); + holeIndex++; }); return gmaps.PolygonOptions() ..paths = paths @@ -498,6 +512,20 @@ gmaps.PolygonOptions _polygonOptionsFromPolygon( ..geodesic = polygon.geodesic; } +/// Calculates the direction of a given Polygon +/// based on: https://stackoverflow.com/a/1165943 +/// +/// returns [true] if clockwise [false] if counterclockwise +bool _isPolygonClockwise(List path) { + var direction = 0.0; + for (var i = 0; i < path.length; i++) { + direction = direction + + ((path[(i + 1) % path.length].lat - path[i].lat) * + (path[(i + 1) % path.length].lng + path[i].lng)); + } + return direction >= 0; +} + gmaps.PolylineOptions _polylineOptionsFromPolyline( gmaps.GMap googleMap, Polyline polyline) { List paths = []; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index bd879553a06d..099a1238be1c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -1,7 +1,7 @@ name: google_maps_flutter_web description: Web platform implementation of google_maps_flutter homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter -version: 0.1.0+10 +version: 0.1.1 flutter: plugin: diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration.dart index 4d5c2b17cc56..26db542c60fe 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration.dart @@ -245,6 +245,39 @@ void main() { expect(geometry.poly.containsLocation(pointInHole, polygon), false); }); + + testWidgets('Hole Path gets reversed to display correctly', + (WidgetTester tester) async { + final polygons = { + Polygon( + polygonId: PolygonId('BermudaTriangle'), + points: [ + LatLng(25.774, -80.19), + LatLng(18.466, -66.118), + LatLng(32.321, -64.757), + ], + holes: [ + [ + LatLng(27.339, -66.668), + LatLng(29.57, -67.514), + LatLng(28.745, -70.579), + ], + ], + ), + }; + + controller.addPolygons(polygons); + + expect( + controller.polygons.values.first.polygon.paths.getAt(1).getAt(0).lat, + 28.745); + expect( + controller.polygons.values.first.polygon.paths.getAt(1).getAt(1).lat, + 29.57); + expect( + controller.polygons.values.first.polygon.paths.getAt(1).getAt(2).lat, + 27.339); + }); }); group('PolylinesController', () { From 6fa2ead23e8d58de047f38c0f90ce5e218ef8ea5 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Thu, 21 Jan 2021 16:19:05 -0800 Subject: [PATCH 0056/1565] [google_maps_flutter_platform_interface] add custom tile support (#3418) --- .../CHANGELOG.md | 4 + .../method_channel_google_maps_flutter.dart | 61 +++++++ .../google_maps_flutter_platform.dart | 27 +++ .../lib/src/types/tile.dart | 42 +++++ .../lib/src/types/tile_overlay.dart | 161 ++++++++++++++++++ .../lib/src/types/tile_overlay_updates.dart | 122 +++++++++++++ .../lib/src/types/tile_provider.dart | 16 ++ .../lib/src/types/types.dart | 3 + .../lib/src/types/utils/tile_overlay.dart | 23 +++ .../google_maps_flutter_platform_test.dart | 3 - .../test/types/tile_overlay_test.dart | 107 ++++++++++++ .../test/types/tile_overlay_updates_test.dart | 125 ++++++++++++++ .../test/types/tile_test.dart | 28 +++ .../google_maps_flutter_web/CHANGELOG.md | 4 + .../google_maps_flutter_web/pubspec.yaml | 2 +- 15 files changed, 724 insertions(+), 4 deletions(-) create mode 100644 packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile.dart create mode 100644 packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart create mode 100644 packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay_updates.dart create mode 100644 packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_provider.dart create mode 100644 packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/tile_overlay.dart create mode 100644 packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart create mode 100644 packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart create mode 100644 packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md index 1e761681e543..4273f596cf39 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.2.0 + +* Add TileOverlay support. + ## 1.1.0 * Add support for holes in Polygons. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart index 31392354d946..0ebfad5b5137 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart @@ -12,6 +12,8 @@ import 'package:flutter/gestures.dart'; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; import 'package:stream_transform/stream_transform.dart'; +import '../types/tile_overlay_updates.dart'; +import '../types/utils/tile_overlay.dart'; /// An implementation of [GoogleMapsFlutterPlatform] that uses [MethodChannel] to communicate with the native code. /// @@ -33,6 +35,9 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { return _channels[mapId]; } + // Keep a collection of mapId to a map of TileOverlays. + final Map> _tileOverlays = {}; + /// Initializes the platform interface with [id]. /// /// This method is called when the plugin is first initialized. @@ -184,6 +189,18 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { LatLng.fromJson(call.arguments['position']), )); break; + case 'tileOverlay#getTile': + final Map tileOverlaysForThisMap = + _tileOverlays[mapId]; + final String tileOverlayId = call.arguments['tileOverlayId']; + final TileOverlay tileOverlay = tileOverlaysForThisMap[tileOverlayId]; + assert(tileOverlay.tileProvider.getTile != null); + final Tile tile = await tileOverlay.tileProvider.getTile( + call.arguments['x'], + call.arguments['y'], + call.arguments['zoom'], + ); + return tile.toJson(); default: throw MissingPluginException(); } @@ -281,6 +298,50 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { ); } + /// Updates tile overlay configuration. + /// + /// Change listeners are notified once the update has been made on the + /// platform side. + /// + /// The returned [Future] completes after listeners have been notified. + /// + /// If `newTileOverlays` is null, all the [TileOverlays] are removed for the Map with `mapId`. + @override + Future updateTileOverlays({ + Set newTileOverlays, + @required int mapId, + }) { + final Map currentTileOverlays = + _tileOverlays[mapId]; + Set previousSet = + currentTileOverlays != null ? currentTileOverlays.values.toSet() : null; + final TileOverlayUpdates updates = + TileOverlayUpdates.from(previousSet, newTileOverlays); + _tileOverlays[mapId] = keyTileOverlayId(newTileOverlays); + return channel(mapId).invokeMethod( + 'tileOverlays#update', + updates.toJson(), + ); + } + + /// Clears the tile cache so that all tiles will be requested again from the + /// [TileProvider]. + /// + /// The current tiles from this tile overlay will also be + /// cleared from the map after calling this method. The Google Map SDK maintains a small + /// in-memory cache of tiles. If you want to cache tiles for longer, you + /// should implement an on-disk cache. + @override + Future clearTileCache( + TileOverlayId tileOverlayId, { + @required int mapId, + }) { + return channel(mapId) + .invokeMethod('tileOverlays#clearTileCache', { + 'tileOverlayId': tileOverlayId.value, + }); + } + /// Starts an animated change of the map camera position. /// /// The returned [Future] completes after the change has been started on the diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart index a4f487740811..b9d3fecc0d0a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart @@ -115,6 +115,33 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { throw UnimplementedError('updateCircles() has not been implemented.'); } + /// Updates tile overlay configuration. + /// + /// Change listeners are notified once the update has been made on the + /// platform side. + /// + /// The returned [Future] completes after listeners have been notified. + Future updateTileOverlays({ + Set newTileOverlays, + @required int mapId, + }) { + throw UnimplementedError('updateTileOverlays() has not been implemented.'); + } + + /// Clears the tile cache so that all tiles will be requested again from the + /// [TileProvider]. + /// + /// The current tiles from this tile overlay will also be + /// cleared from the map after calling this method. The Google Maps SDK maintains a small + /// in-memory cache of tiles. If you want to cache tiles for longer, you + /// should implement an on-disk cache. + Future clearTileCache( + TileOverlayId tileOverlayId, { + @required int mapId, + }) { + throw UnimplementedError('clearTileCache() has not been implemented.'); + } + /// Starts an animated change of the map camera position. /// /// The returned [Future] completes after the change has been started on the diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile.dart new file mode 100644 index 000000000000..a992b41fb6c0 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile.dart @@ -0,0 +1,42 @@ +// Copyright 2018 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. + +import 'dart:typed_data'; +import 'package:meta/meta.dart' show immutable; + +/// Contains information about a Tile that is returned by a [TileProvider]. +@immutable +class Tile { + /// Creates an immutable representation of a [Tile] to draw by [TileProvider]. + const Tile(this.width, this.height, this.data); + + /// The width of the image encoded by data in logical pixels. + final int width; + + /// The height of the image encoded by data in logical pixels. + final int height; + + /// A byte array containing the image data. + /// + /// The image data format must be natively supported for decoding by the platform. + /// e.g on Android it can only be one of the [supported image formats for decoding](https://developer.android.com/guide/topics/media/media-formats#image-formats). + final Uint8List data; + + /// Converts this object to JSON. + Map toJson() { + final Map json = {}; + + void addIfPresent(String fieldName, dynamic value) { + if (value != null) { + json[fieldName] = value; + } + } + + addIfPresent('width', width); + addIfPresent('height', height); + addIfPresent('data', data); + + return json; + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart new file mode 100644 index 000000000000..3978f23f05f8 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart @@ -0,0 +1,161 @@ +// Copyright 2018 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. + +import 'dart:ui' show hashValues; +import 'package:flutter/foundation.dart'; + +import 'types.dart'; +import 'package:meta/meta.dart' show immutable, required; + +/// Uniquely identifies a [TileOverlay] among [GoogleMap] tile overlays. +@immutable +class TileOverlayId { + /// Creates an immutable identifier for a [TileOverlay]. + TileOverlayId(this.value) : assert(value != null); + + /// The value of the [TileOverlayId]. + final String value; + + @override + bool operator ==(Object other) { + if (other.runtimeType != runtimeType) { + return false; + } + return other is TileOverlayId && other.value == value; + } + + @override + int get hashCode => value.hashCode; + + @override + String toString() => '${objectRuntimeType(this, 'TileOverlayId')}($value)'; +} + +/// A set of images which are displayed on top of the base map tiles. +/// +/// These tiles may be transparent, allowing you to add features to existing maps. +/// +/// ## Tile Coordinates +/// +/// Note that the world is projected using the Mercator projection +/// (see [Wikipedia](https://en.wikipedia.org/wiki/Mercator_projection)) with the left (west) side +/// of the map corresponding to -180 degrees of longitude and the right (east) side of the map +/// corresponding to 180 degrees of longitude. To make the map square, the top (north) side of the +/// map corresponds to 85.0511 degrees of latitude and the bottom (south) side of the map +/// corresponds to -85.0511 degrees of latitude. Areas outside this latitude range are not rendered. +/// +/// At each zoom level, the map is divided into tiles and only the tiles that overlap the screen are +/// downloaded and rendered. Each tile is square and the map is divided into tiles as follows: +/// +/// * At zoom level 0, one tile represents the entire world. The coordinates of that tile are +/// (x, y) = (0, 0). +/// * At zoom level 1, the world is divided into 4 tiles arranged in a 2 x 2 grid. +/// * ... +/// * At zoom level N, the world is divided into 4N tiles arranged in a 2N x 2N grid. +/// +/// Note that the minimum zoom level that the camera supports (which can depend on various factors) +/// is GoogleMap.getMinZoomLevel and the maximum zoom level is GoogleMap.getMaxZoomLevel. +/// +/// The coordinates of the tiles are measured from the top left (northwest) corner of the map. +/// At zoom level N, the x values of the tile coordinates range from 0 to 2N - 1 and increase from +/// west to east and the y values range from 0 to 2N - 1 and increase from north to south. +/// +class TileOverlay { + /// Creates an immutable representation of a [TileOverlay] to draw on [GoogleMap]. + const TileOverlay({ + @required this.tileOverlayId, + this.fadeIn = true, + this.tileProvider, + this.transparency = 0.0, + this.zIndex, + this.visible = true, + this.tileSize = 256, + }) : assert(transparency >= 0.0 && transparency <= 1.0); + + /// Uniquely identifies a [TileOverlay]. + final TileOverlayId tileOverlayId; + + /// Whether the tiles should fade in. The default is true. + final bool fadeIn; + + /// The tile provider to use for this tile overlay. + final TileProvider tileProvider; + + /// The transparency of the tile overlay. The default transparency is 0 (opaque). + final double transparency; + + /// The tile overlay's zIndex, i.e., the order in which it will be drawn where + /// overlays with larger values are drawn above those with lower values + final int zIndex; + + /// The visibility for the tile overlay. The default visibility is true. + final bool visible; + + /// Specifies the number of logical pixels (not points) that the returned tile images will prefer + /// to display as. iOS only. + /// + /// Defaults to 256, which is the traditional size of Google Maps tiles. + /// As an example, an application developer may wish to provide retina tiles (512 pixel edge length) + /// on retina devices, to keep the same number of tiles per view as the default value of 256 + /// would give on a non-retina device. + final int tileSize; + + /// Creates a new [TileOverlay] object whose values are the same as this instance, + /// unless overwritten by the specified parameters. + TileOverlay copyWith({ + TileOverlayId tileOverlayId, + bool fadeInParam, + double transparencyParam, + int zIndexParam, + bool visibleParam, + int tileSizeParam, + }) { + return TileOverlay( + tileOverlayId: tileOverlayId, + fadeIn: fadeInParam ?? fadeIn, + transparency: transparencyParam ?? transparency, + zIndex: zIndexParam ?? zIndex, + visible: visibleParam ?? visible, + tileSize: tileSizeParam ?? tileSize, + ); + } + + /// Converts this object to JSON. + Map toJson() { + final Map json = {}; + + void addIfPresent(String fieldName, dynamic value) { + if (value != null) { + json[fieldName] = value; + } + } + + addIfPresent('tileOverlayId', tileOverlayId.value); + addIfPresent('fadeIn', fadeIn); + addIfPresent('transparency', transparency); + addIfPresent('zIndex', zIndex); + addIfPresent('visible', visible); + addIfPresent('tileSize', tileSize); + + return json; + } + + @override + bool operator ==(Object other) { + if (other.runtimeType != runtimeType) { + return false; + } + return other is TileOverlay && + tileOverlayId == other.tileOverlayId && + fadeIn == other.fadeIn && + transparency == other.transparency && + zIndex == other.zIndex && + visible == other.visible && + tileSize == other.tileSize; + } + + @override + int get hashCode => hashValues( + tileOverlayId, fadeIn, transparency, zIndex, visible, tileSize); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay_updates.dart new file mode 100644 index 000000000000..2910fc37d495 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay_updates.dart @@ -0,0 +1,122 @@ +// Copyright 2018 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. + +import 'package:flutter/foundation.dart' show objectRuntimeType, setEquals; +import 'dart:ui' show hashValues, hashList; + +import 'utils/tile_overlay.dart'; +import 'types.dart'; + +/// Update specification for a set of [TileOverlay]s. +class TileOverlayUpdates { + /// Computes [TileOverlayUpdates] given previous and current [TileOverlay]s. + TileOverlayUpdates.from(Set previous, Set current) { + if (previous == null) { + previous = Set.identity(); + } + + if (current == null) { + current = Set.identity(); + } + + final Map previousTileOverlays = + keyTileOverlayId(previous); + final Map currentTileOverlays = + keyTileOverlayId(current); + + final Set prevTileOverlayIds = + previousTileOverlays.keys.toSet(); + final Set currentTileOverlayIds = + currentTileOverlays.keys.toSet(); + + TileOverlay idToCurrentTileOverlay(TileOverlayId id) { + return currentTileOverlays[id]; + } + + _tileOverlayIdsToRemove = + prevTileOverlayIds.difference(currentTileOverlayIds); + + _tileOverlaysToAdd = currentTileOverlayIds + .difference(prevTileOverlayIds) + .map(idToCurrentTileOverlay) + .toSet(); + + // Returns `true` if [current] is not equals to previous one with the + // same id. + bool hasChanged(TileOverlay current) { + final TileOverlay previous = previousTileOverlays[current.tileOverlayId]; + return current != previous; + } + + _tileOverlaysToChange = currentTileOverlayIds + .intersection(prevTileOverlayIds) + .map(idToCurrentTileOverlay) + .where(hasChanged) + .toSet(); + } + + /// Set of TileOverlays to be added in this update. + Set get tileOverlaysToAdd { + return _tileOverlaysToAdd; + } + + Set _tileOverlaysToAdd; + + /// Set of TileOverlayIds to be removed in this update. + Set get tileOverlayIdsToRemove { + return _tileOverlayIdsToRemove; + } + + Set _tileOverlayIdsToRemove; + + /// Set of TileOverlays to be changed in this update. + Set get tileOverlaysToChange { + return _tileOverlaysToChange; + } + + Set _tileOverlaysToChange; + + /// Converts this object to JSON. + Map toJson() { + final Map updateMap = {}; + + void addIfNonNull(String fieldName, dynamic value) { + if (value != null) { + updateMap[fieldName] = value; + } + } + + addIfNonNull( + 'tileOverlaysToAdd', serializeTileOverlaySet(_tileOverlaysToAdd)); + addIfNonNull( + 'tileOverlaysToChange', serializeTileOverlaySet(_tileOverlaysToChange)); + addIfNonNull( + 'tileOverlayIdsToRemove', + _tileOverlayIdsToRemove + .map((TileOverlayId m) => m.value) + .toList()); + + return updateMap; + } + + @override + bool operator ==(Object other) { + if (other.runtimeType != runtimeType) { + return false; + } + return other is TileOverlayUpdates && + setEquals(_tileOverlaysToAdd, other._tileOverlaysToAdd) && + setEquals(_tileOverlayIdsToRemove, other._tileOverlayIdsToRemove) && + setEquals(_tileOverlaysToChange, other._tileOverlaysToChange); + } + + @override + int get hashCode => hashValues(hashList(_tileOverlaysToAdd), + hashList(_tileOverlayIdsToRemove), hashList(_tileOverlaysToChange)); + + @override + String toString() { + return '${objectRuntimeType(this, 'TileOverlayUpdates')}($_tileOverlaysToAdd, $_tileOverlayIdsToRemove, $_tileOverlaysToChange)'; + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_provider.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_provider.dart new file mode 100644 index 000000000000..c3c4f807e283 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_provider.dart @@ -0,0 +1,16 @@ +// Copyright 2018 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. + +import 'types.dart'; + +/// An interface for a class that provides the tile images for a TileOverlay. +abstract class TileProvider { + /// Stub tile that is used to indicate that no tile exists for a specific tile coordinate. + static const Tile noTile = Tile(-1, -1, null); + + /// Returns the tile to be used for this tile coordinate. + /// + /// See [TileOverlay] for the specification of tile coordinates. + Future getTile(int x, int y, int zoom); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart index e56c3a5dd646..e4b5c0bc3ab2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart @@ -19,6 +19,9 @@ export 'polygon.dart'; export 'polyline_updates.dart'; export 'polyline.dart'; export 'screen_coordinate.dart'; +export 'tile.dart'; +export 'tile_overlay.dart'; +export 'tile_provider.dart'; export 'ui.dart'; // Export the utils, they're used by the Widget diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/tile_overlay.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/tile_overlay.dart new file mode 100644 index 000000000000..0736c836481f --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/tile_overlay.dart @@ -0,0 +1,23 @@ +import '../types.dart'; + +/// Converts an [Iterable] of TileOverlay in a Map of TileOverlayId -> TileOverlay. +Map keyTileOverlayId( + Iterable tileOverlays) { + if (tileOverlays == null) { + return {}; + } + return Map.fromEntries(tileOverlays.map( + (TileOverlay tileOverlay) => MapEntry( + tileOverlay.tileOverlayId, tileOverlay))); +} + +/// Converts a Set of TileOverlays into something serializable in JSON. +List> serializeTileOverlaySet( + Set tileOverlays) { + if (tileOverlays == null) { + return null; + } + return tileOverlays + .map>((TileOverlay p) => p.toJson()) + .toList(); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart index a003b94d544c..582acea54dd1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart @@ -45,14 +45,11 @@ void main() { log.add(methodCall); }); -// final MethodChannelGoogleMapsFlutter map = MethodChannelGoogleMapsFlutter(0); - tearDown(() { log.clear(); }); test('foo', () async { -// await map.foo(); expect( log, [], diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart new file mode 100644 index 000000000000..bb0621d23ae3 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart @@ -0,0 +1,107 @@ +// 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. + +import 'dart:ui' show hashValues; +import 'package:flutter_test/flutter_test.dart'; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('tile overlay id tests', () { + test('equality', () async { + final TileOverlayId id1 = TileOverlayId('1'); + final TileOverlayId id2 = TileOverlayId('1'); + final TileOverlayId id3 = TileOverlayId('2'); + expect(id1, id2); + expect(id1, isNot(id3)); + }); + + test('toString', () async { + final TileOverlayId id1 = TileOverlayId('1'); + expect(id1.toString(), 'TileOverlayId(1)'); + }); + }); + + group('tile overlay tests', () { + test('toJson returns correct format', () async { + final TileOverlay tileOverlay = TileOverlay( + tileOverlayId: TileOverlayId('id'), + fadeIn: false, + tileProvider: null, + transparency: 0.1, + zIndex: 1, + visible: false, + tileSize: 128); + final Map json = tileOverlay.toJson(); + expect(json['tileOverlayId'], 'id'); + expect(json['fadeIn'], false); + expect(json['transparency'], moreOrLessEquals(0.1)); + expect(json['zIndex'], 1); + expect(json['visible'], false); + expect(json['tileSize'], 128); + }); + + test('invalid transparency throws', () async { + expect( + () => TileOverlay( + tileOverlayId: TileOverlayId('id1'), transparency: -0.1), + throwsAssertionError); + expect( + () => TileOverlay( + tileOverlayId: TileOverlayId('id2'), transparency: 1.2), + throwsAssertionError); + }); + + test('equality', () async { + final TileOverlay tileOverlay1 = TileOverlay( + tileOverlayId: TileOverlayId('id1'), + fadeIn: false, + tileProvider: null, + transparency: 0.1, + zIndex: 1, + visible: false, + tileSize: 128); + final TileOverlay tileOverlay2 = TileOverlay( + tileOverlayId: TileOverlayId('id1'), + fadeIn: false, + tileProvider: null, + transparency: 0.1, + zIndex: 1, + visible: false, + tileSize: 128); + final TileOverlay tileOverlay3 = TileOverlay( + tileOverlayId: TileOverlayId('id2'), + fadeIn: false, + tileProvider: null, + transparency: 0.1, + zIndex: 1, + visible: false, + tileSize: 128); + expect(tileOverlay1, tileOverlay2); + expect(tileOverlay1, isNot(tileOverlay3)); + }); + + test('hashCode', () async { + TileOverlayId id = TileOverlayId('id1'); + final TileOverlay tileOverlay = TileOverlay( + tileOverlayId: id, + fadeIn: false, + tileProvider: null, + transparency: 0.1, + zIndex: 1, + visible: false, + tileSize: 128); + expect( + tileOverlay.hashCode, + hashValues( + tileOverlay.tileOverlayId, + tileOverlay.fadeIn, + tileOverlay.transparency, + tileOverlay.zIndex, + tileOverlay.visible, + tileOverlay.tileSize)); + }); + }); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart new file mode 100644 index 000000000000..980a203f709e --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart @@ -0,0 +1,125 @@ +// 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. + +import 'dart:ui' show hashValues, hashList; +import 'package:flutter_test/flutter_test.dart'; +import 'package:google_maps_flutter_platform_interface/src/types/utils/tile_overlay.dart'; +import 'package:google_maps_flutter_platform_interface/src/types/tile_overlay_updates.dart'; +import 'package:google_maps_flutter_platform_interface/src/types/tile_overlay.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('tile overlay updates tests', () { + test('Correctly set toRemove, toAdd and toChange', () async { + final TileOverlay to1 = TileOverlay(tileOverlayId: TileOverlayId('id1')); + final TileOverlay to2 = TileOverlay(tileOverlayId: TileOverlayId('id2')); + final TileOverlay to3 = TileOverlay(tileOverlayId: TileOverlayId('id3')); + final TileOverlay to3Changed = + TileOverlay(tileOverlayId: TileOverlayId('id3'), transparency: 0.5); + final TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4')); + final Set previous = Set.from([to1, to2, to3]); + final Set current = + Set.from([to2, to3Changed, to4]); + final TileOverlayUpdates updates = + TileOverlayUpdates.from(previous, current); + + final Set toRemove = + Set.from([TileOverlayId('id1')]); + expect(updates.tileOverlayIdsToRemove, toRemove); + + final Set toAdd = Set.from([to4]); + expect(updates.tileOverlaysToAdd, toAdd); + + final Set toChange = Set.from([to3Changed]); + expect(updates.tileOverlaysToChange, toChange); + }); + + test('toJson', () async { + final TileOverlay to1 = TileOverlay(tileOverlayId: TileOverlayId('id1')); + final TileOverlay to2 = TileOverlay(tileOverlayId: TileOverlayId('id2')); + final TileOverlay to3 = TileOverlay(tileOverlayId: TileOverlayId('id3')); + final TileOverlay to3Changed = + TileOverlay(tileOverlayId: TileOverlayId('id3'), transparency: 0.5); + final TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4')); + final Set previous = Set.from([to1, to2, to3]); + final Set current = + Set.from([to2, to3Changed, to4]); + final TileOverlayUpdates updates = + TileOverlayUpdates.from(previous, current); + + final Map json = updates.toJson(); + expect(json, { + 'tileOverlaysToAdd': serializeTileOverlaySet(updates.tileOverlaysToAdd), + 'tileOverlaysToChange': + serializeTileOverlaySet(updates.tileOverlaysToChange), + 'tileOverlayIdsToRemove': updates.tileOverlayIdsToRemove + .map((TileOverlayId m) => m.value) + .toList() + }); + }); + + test('equality', () async { + final TileOverlay to1 = TileOverlay(tileOverlayId: TileOverlayId('id1')); + final TileOverlay to2 = TileOverlay(tileOverlayId: TileOverlayId('id2')); + final TileOverlay to3 = TileOverlay(tileOverlayId: TileOverlayId('id3')); + final TileOverlay to3Changed = + TileOverlay(tileOverlayId: TileOverlayId('id3'), transparency: 0.5); + final TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4')); + final Set previous = Set.from([to1, to2, to3]); + final Set current1 = + Set.from([to2, to3Changed, to4]); + final Set current2 = + Set.from([to2, to3Changed, to4]); + final Set current3 = Set.from([to2, to4]); + final TileOverlayUpdates updates1 = + TileOverlayUpdates.from(previous, current1); + final TileOverlayUpdates updates2 = + TileOverlayUpdates.from(previous, current2); + final TileOverlayUpdates updates3 = + TileOverlayUpdates.from(previous, current3); + expect(updates1, updates2); + expect(updates1, isNot(updates3)); + }); + + test('hashCode', () async { + final TileOverlay to1 = TileOverlay(tileOverlayId: TileOverlayId('id1')); + final TileOverlay to2 = TileOverlay(tileOverlayId: TileOverlayId('id2')); + final TileOverlay to3 = TileOverlay(tileOverlayId: TileOverlayId('id3')); + final TileOverlay to3Changed = + TileOverlay(tileOverlayId: TileOverlayId('id3'), transparency: 0.5); + final TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4')); + final Set previous = Set.from([to1, to2, to3]); + final Set current = + Set.from([to2, to3Changed, to4]); + final TileOverlayUpdates updates = + TileOverlayUpdates.from(previous, current); + expect( + updates.hashCode, + hashValues( + hashList(updates.tileOverlaysToAdd), + hashList(updates.tileOverlayIdsToRemove), + hashList(updates.tileOverlaysToChange))); + }); + + test('toString', () async { + final TileOverlay to1 = TileOverlay(tileOverlayId: TileOverlayId('id1')); + final TileOverlay to2 = TileOverlay(tileOverlayId: TileOverlayId('id2')); + final TileOverlay to3 = TileOverlay(tileOverlayId: TileOverlayId('id3')); + final TileOverlay to3Changed = + TileOverlay(tileOverlayId: TileOverlayId('id3'), transparency: 0.5); + final TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4')); + final Set previous = Set.from([to1, to2, to3]); + final Set current = + Set.from([to2, to3Changed, to4]); + final TileOverlayUpdates updates = + TileOverlayUpdates.from(previous, current); + expect( + updates.toString(), + 'TileOverlayUpdates(${updates.tileOverlaysToAdd}, ' + '${updates.tileOverlayIdsToRemove}, ' + '${updates.tileOverlaysToChange})'); + }); + }); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart new file mode 100644 index 000000000000..0be9a7cea8f0 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart @@ -0,0 +1,28 @@ +// 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. + +import 'dart:typed_data'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('tile tests', () { + test('toJson returns correct format', () async { + final Uint8List data = Uint8List.fromList([0, 1]); + final Tile tile = Tile(100, 200, data); + final Map json = tile.toJson(); + expect(json['width'], 100); + expect(json['height'], 200); + expect(json['data'], data); + }); + + test('toJson returns empty if nothing presents', () async { + final Tile tile = Tile(null, null, null); + final Map json = tile.toJson(); + expect(json.isEmpty, true); + }); + }); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md index caa64ec73088..f5e289cb19ae 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.2 + +* Add support for Custom Tiles. + ## 0.1.1 * Auto-reverse holes if they're the same direction as the polygon. [Issue](https://github.com/flutter/flutter/issues/74096). diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index 099a1238be1c..83ac0fbdde5f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -1,7 +1,7 @@ name: google_maps_flutter_web description: Web platform implementation of google_maps_flutter homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter -version: 0.1.1 +version: 0.1.2 flutter: plugin: From 6783cd5ebd54e034a77e2404f5565b48bd19e121 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Fri, 22 Jan 2021 11:04:03 -0800 Subject: [PATCH 0057/1565] [google_maps_flutter_platform_interface] Fixes for custom tiles (#3449) --- .../method_channel_google_maps_flutter.dart | 10 +++++++--- .../lib/src/types/types.dart | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart index 0ebfad5b5137..8b7af2cc3515 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart @@ -193,9 +193,13 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { final Map tileOverlaysForThisMap = _tileOverlays[mapId]; final String tileOverlayId = call.arguments['tileOverlayId']; - final TileOverlay tileOverlay = tileOverlaysForThisMap[tileOverlayId]; - assert(tileOverlay.tileProvider.getTile != null); - final Tile tile = await tileOverlay.tileProvider.getTile( + final TileOverlay tileOverlay = + tileOverlaysForThisMap[TileOverlayId(tileOverlayId)]; + Tile tile; + if (tileOverlay == null || tileOverlay.tileProvider == null) { + return TileProvider.noTile.toJson(); + } + tile = await tileOverlay.tileProvider.getTile( call.arguments['x'], call.arguments['y'], call.arguments['zoom'], diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart index e4b5c0bc3ab2..3e2002f80ae3 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart @@ -29,3 +29,4 @@ export 'utils/circle.dart'; export 'utils/marker.dart'; export 'utils/polygon.dart'; export 'utils/polyline.dart'; +export 'utils/tile_overlay.dart'; From 712dcc184380188522ca80b56e9b5b11651541ce Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Sat, 23 Jan 2021 10:54:06 -0800 Subject: [PATCH 0058/1565] [ci][image_picker]enable xcode 12/iOS 14 for all tasks except lint (#3304) --- .cirrus.yml | 50 +++++++++++++------ .../image_picker/image_picker/CHANGELOG.md | 4 ++ .../ImagePickerFromGalleryUITests.m | 20 ++++++-- .../image_picker/image_picker/pubspec.yaml | 2 +- 4 files changed, 58 insertions(+), 18 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 4ec73ea3f24c..aa56ca26d82b 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -117,6 +117,7 @@ task: env: INTEGRATION_TEST_PATH: "./packages/integration_test" upgrade_script: + - sudo gem install cocoapods - flutter channel stable - flutter upgrade - flutter channel master @@ -134,13 +135,14 @@ task: - xvfb-run ./script/incremental_build.sh drive-examples --linux task: + # Xcode 11 task + # TODO(cyanglaz): merge Xcode 11 task to Xcode 12 task when all the matrix can be run in Xcode 12. # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins only_if: $CIRRUS_TAG == '' use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' osx_instance: image: catalina-xcode-11.3.1-flutter upgrade_script: - - sudo gem install cocoapods - flutter channel stable - flutter upgrade - flutter channel master @@ -151,17 +153,6 @@ task: - xcrun simctl list - 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 - - if [[ "$CHANNEL" -eq "stable" ]]; then find . | grep _web$ | xargs rm -rf; fi - - flutter channel $CHANNEL - - ./script/build_all_plugins_app.sh ios --no-codesign - name: lint_darwin_plugins env: matrix: @@ -173,6 +164,37 @@ task: # Skip the dummy podspecs used to placate the tool. - find . -name "*_web*.podspec" -o -name "*_mac*.podspec" | xargs rm - ./script/incremental_build.sh podspecs + +task: + # Xcode 12 task + # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins + only_if: $CIRRUS_TAG == '' + use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' + osx_instance: + image: big-sur-xcode-12.3 + upgrade_script: + - sudo gem install cocoapods + - flutter channel stable + - flutter upgrade + - flutter channel master + - flutter upgrade + - git fetch origin master + activate_script: pub global activate flutter_plugin_tools + create_simulator_script: + - xcrun simctl list + - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-11 com.apple.CoreSimulator.SimRuntime.iOS-14-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 + - if [[ "$CHANNEL" -eq "stable" ]]; then find . | grep _web$ | xargs rm -rf; fi + - flutter channel $CHANNEL + - ./script/build_all_plugins_app.sh ios --no-codesign - name: build-ipas+drive-examples env: PATH: $PATH:/usr/local/bin @@ -193,13 +215,13 @@ task: - flutter channel $CHANNEL - ./script/incremental_build.sh build-examples --ipa - ./script/incremental_build.sh drive-examples - - ./script/incremental_build.sh xctest --target RunnerUITests --skip $PLUGINS_TO_SKIP_XCTESTS + - ./script/incremental_build.sh xctest --target RunnerUITests --skip $PLUGINS_TO_SKIP_XCTESTS --ios-destination "platform=iOS Simulator,name=iPhone 11,OS=14.3" task: # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins only_if: $CIRRUS_TAG == '' use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' osx_instance: - image: catalina-xcode-11.3.1-flutter + image: big-sur-xcode-12.3 setup_script: - flutter config --enable-macos-desktop upgrade_script: diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md index 1b3146d532fa..1a09758d13ef 100644 --- a/packages/image_picker/image_picker/CHANGELOG.md +++ b/packages/image_picker/image_picker/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.7+22 + +* iOS: update XCUITests to separate each test session. + ## 0.6.7+21 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. diff --git a/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m b/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m index 74df795a3df3..e30fabd2d071 100644 --- a/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m +++ b/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m @@ -16,6 +16,7 @@ @interface ImagePickerFromGalleryUITests : XCTestCase @implementation ImagePickerFromGalleryUITests - (void)setUp { + [super setUp]; // Delete the app if already exists, to test permission popups self.continueAfterFailure = NO; @@ -31,7 +32,7 @@ - (void)setUp { if (![allPhotoPermission waitForExistenceWithTimeout: kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", - self.app.debugDescription); + weakSelf.app.debugDescription); XCTFail(@"Failed due to not able to find " @"allPhotoPermission button with %@ seconds", @(kElementWaitingTime)); @@ -42,7 +43,7 @@ - (void)setUp { if (![ok waitForExistenceWithTimeout: kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", - self.app.debugDescription); + weakSelf.app.debugDescription); XCTFail(@"Failed due to not able to find ok button " @"with %@ seconds", @(kElementWaitingTime)); @@ -53,11 +54,19 @@ - (void)setUp { }]; } +- (void)tearDown { + [super tearDown]; + [self.app terminate]; +} + - (void)testPickingFromGallery { - [self launchPickerAndCancel]; [self launchPickerAndPick]; } +- (void)testCancel { + [self launchPickerAndCancel]; +} + - (void)launchPickerAndCancel { // Find and tap on the pick from gallery button. NSPredicate* predicateToFindImageFromGalleryButton = @@ -160,6 +169,10 @@ - (void)launchPickerAndPick { XCTAssertTrue(pickButton.exists); [pickButton tap]; + // There is a known bug where the permission popups interruption won't get fired until a tap + // happened in the app. We expect a permission popup so we do a tap here. + [self.app tap]; + // Find an image and tap on it. (IOS 14 UI, images are showing directly) XCUIElement* aImage; if (@available(iOS 14, *)) { @@ -177,6 +190,7 @@ - (void)launchPickerAndPick { identifier:@"PhotosGridView"] .cells.firstMatch; } + os_log_error(OS_LOG_DEFAULT, "description before picking image %@", self.app.debugDescription); if (![aImage waitForExistenceWithTimeout:kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTFail(@"Failed due to not able to find an image with %@ seconds", @(kElementWaitingTime)); diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index 789ca13d5bcb..075c90627bf4 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker description: Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker -version: 0.6.7+21 +version: 0.6.7+22 flutter: plugin: From 18124285feeba5f62e2e0deafab3ef93e5895426 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 25 Jan 2021 10:21:11 -0800 Subject: [PATCH 0059/1565] Revert "[ci][image_picker]enable xcode 12/iOS 14 for all tasks except lint (#3304)" (#3459) This reverts commit 712dcc184380188522ca80b56e9b5b11651541ce. --- .cirrus.yml | 50 ++++++------------- .../image_picker/image_picker/CHANGELOG.md | 4 -- .../ImagePickerFromGalleryUITests.m | 20 ++------ .../image_picker/image_picker/pubspec.yaml | 2 +- 4 files changed, 18 insertions(+), 58 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index aa56ca26d82b..4ec73ea3f24c 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -117,7 +117,6 @@ task: env: INTEGRATION_TEST_PATH: "./packages/integration_test" upgrade_script: - - sudo gem install cocoapods - flutter channel stable - flutter upgrade - flutter channel master @@ -135,43 +134,11 @@ task: - xvfb-run ./script/incremental_build.sh drive-examples --linux task: - # Xcode 11 task - # TODO(cyanglaz): merge Xcode 11 task to Xcode 12 task when all the matrix can be run in Xcode 12. # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins only_if: $CIRRUS_TAG == '' use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' osx_instance: image: catalina-xcode-11.3.1-flutter - upgrade_script: - - flutter channel stable - - flutter upgrade - - flutter channel master - - flutter upgrade - - git fetch origin master - activate_script: pub global activate flutter_plugin_tools - create_simulator_script: - - xcrun simctl list - - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-X com.apple.CoreSimulator.SimRuntime.iOS-13-3 | xargs xcrun simctl boot - matrix: - - name: lint_darwin_plugins - env: - matrix: - PLUGIN_SHARDING: "--shardIndex 0 --shardCount 2" - PLUGIN_SHARDING: "--shardIndex 1 --shardCount 2" - script: - # TODO(jmagman): Lint macOS podspecs but skip any that fail library validation. - - find . -name "*.podspec" | xargs grep -l "osx" | xargs rm - # Skip the dummy podspecs used to placate the tool. - - find . -name "*_web*.podspec" -o -name "*_mac*.podspec" | xargs rm - - ./script/incremental_build.sh podspecs - -task: - # Xcode 12 task - # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins - only_if: $CIRRUS_TAG == '' - use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' - osx_instance: - image: big-sur-xcode-12.3 upgrade_script: - sudo gem install cocoapods - flutter channel stable @@ -182,7 +149,7 @@ task: activate_script: pub global activate flutter_plugin_tools create_simulator_script: - xcrun simctl list - - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-11 com.apple.CoreSimulator.SimRuntime.iOS-14-3 | xargs xcrun simctl boot + - 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: @@ -195,6 +162,17 @@ task: - if [[ "$CHANNEL" -eq "stable" ]]; then find . | grep _web$ | xargs rm -rf; fi - flutter channel $CHANNEL - ./script/build_all_plugins_app.sh ios --no-codesign + - name: lint_darwin_plugins + env: + matrix: + PLUGIN_SHARDING: "--shardIndex 0 --shardCount 2" + PLUGIN_SHARDING: "--shardIndex 1 --shardCount 2" + script: + # TODO(jmagman): Lint macOS podspecs but skip any that fail library validation. + - find . -name "*.podspec" | xargs grep -l "osx" | xargs rm + # Skip the dummy podspecs used to placate the tool. + - find . -name "*_web*.podspec" -o -name "*_mac*.podspec" | xargs rm + - ./script/incremental_build.sh podspecs - name: build-ipas+drive-examples env: PATH: $PATH:/usr/local/bin @@ -215,13 +193,13 @@ task: - flutter channel $CHANNEL - ./script/incremental_build.sh build-examples --ipa - ./script/incremental_build.sh drive-examples - - ./script/incremental_build.sh xctest --target RunnerUITests --skip $PLUGINS_TO_SKIP_XCTESTS --ios-destination "platform=iOS Simulator,name=iPhone 11,OS=14.3" + - ./script/incremental_build.sh xctest --target RunnerUITests --skip $PLUGINS_TO_SKIP_XCTESTS task: # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins only_if: $CIRRUS_TAG == '' use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' osx_instance: - image: big-sur-xcode-12.3 + image: catalina-xcode-11.3.1-flutter setup_script: - flutter config --enable-macos-desktop upgrade_script: diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md index 1a09758d13ef..1b3146d532fa 100644 --- a/packages/image_picker/image_picker/CHANGELOG.md +++ b/packages/image_picker/image_picker/CHANGELOG.md @@ -1,7 +1,3 @@ -## 0.6.7+22 - -* iOS: update XCUITests to separate each test session. - ## 0.6.7+21 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. diff --git a/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m b/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m index e30fabd2d071..74df795a3df3 100644 --- a/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m +++ b/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m @@ -16,7 +16,6 @@ @interface ImagePickerFromGalleryUITests : XCTestCase @implementation ImagePickerFromGalleryUITests - (void)setUp { - [super setUp]; // Delete the app if already exists, to test permission popups self.continueAfterFailure = NO; @@ -32,7 +31,7 @@ - (void)setUp { if (![allPhotoPermission waitForExistenceWithTimeout: kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", - weakSelf.app.debugDescription); + self.app.debugDescription); XCTFail(@"Failed due to not able to find " @"allPhotoPermission button with %@ seconds", @(kElementWaitingTime)); @@ -43,7 +42,7 @@ - (void)setUp { if (![ok waitForExistenceWithTimeout: kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", - weakSelf.app.debugDescription); + self.app.debugDescription); XCTFail(@"Failed due to not able to find ok button " @"with %@ seconds", @(kElementWaitingTime)); @@ -54,17 +53,9 @@ - (void)setUp { }]; } -- (void)tearDown { - [super tearDown]; - [self.app terminate]; -} - - (void)testPickingFromGallery { - [self launchPickerAndPick]; -} - -- (void)testCancel { [self launchPickerAndCancel]; + [self launchPickerAndPick]; } - (void)launchPickerAndCancel { @@ -169,10 +160,6 @@ - (void)launchPickerAndPick { XCTAssertTrue(pickButton.exists); [pickButton tap]; - // There is a known bug where the permission popups interruption won't get fired until a tap - // happened in the app. We expect a permission popup so we do a tap here. - [self.app tap]; - // Find an image and tap on it. (IOS 14 UI, images are showing directly) XCUIElement* aImage; if (@available(iOS 14, *)) { @@ -190,7 +177,6 @@ - (void)launchPickerAndPick { identifier:@"PhotosGridView"] .cells.firstMatch; } - os_log_error(OS_LOG_DEFAULT, "description before picking image %@", self.app.debugDescription); if (![aImage waitForExistenceWithTimeout:kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTFail(@"Failed due to not able to find an image with %@ seconds", @(kElementWaitingTime)); diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index 075c90627bf4..789ca13d5bcb 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker description: Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker -version: 0.6.7+22 +version: 0.6.7+21 flutter: plugin: From 207d129aefb53890223912974db1efcbcae4ca48 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 25 Jan 2021 16:04:57 -0800 Subject: [PATCH 0060/1565] bump vmservice (#3463) --- packages/integration_test/CHANGELOG.md | 4 ++++ packages/integration_test/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/integration_test/CHANGELOG.md b/packages/integration_test/CHANGELOG.md index 4bbfe591d6cc..5ae0883ed081 100644 --- a/packages/integration_test/CHANGELOG.md +++ b/packages/integration_test/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.2+1 + +* Update vm_service constraint + ## 1.0.2 * Update Flutter SDK constraint. diff --git a/packages/integration_test/pubspec.yaml b/packages/integration_test/pubspec.yaml index 997faa79e1ca..a233f066ea37 100644 --- a/packages/integration_test/pubspec.yaml +++ b/packages/integration_test/pubspec.yaml @@ -1,6 +1,6 @@ name: integration_test description: Runs tests that use the flutter_test API as integration tests. -version: 1.0.2 +version: 1.0.2+1 homepage: https://github.com/flutter/plugins/tree/master/packages/integration_test environment: @@ -18,7 +18,7 @@ dependencies: # TODO(dnfield): This is a problem - flutter_driver and flutter_tools depend # on this packkage, and so does integration_test. When this gets rev'd in the # SDK, it has to be rev'd here too so integration tests in the SDK can use it. - vm_service: ">= 4.2.0 <6.0.0" + vm_service: ">= 4.2.0 <7.0.0" dev_dependencies: pedantic: ^1.8.0 From 919eaef4dcc7b3e272850b74e9995a87d7b5ab39 Mon Sep 17 00:00:00 2001 From: Gary Roumanis Date: Mon, 25 Jan 2021 17:33:19 -0800 Subject: [PATCH 0061/1565] [cross_file] Use Uri when calling package:http methods (#3462) The next version of package:http expects URIs. See dart-lang/http#507 --- packages/cross_file/CHANGELOG.md | 6 +++++- packages/cross_file/lib/src/types/html.dart | 6 +++--- packages/cross_file/pubspec.yaml | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/cross_file/CHANGELOG.md b/packages/cross_file/CHANGELOG.md index 5ad91979dc89..45f516ad334d 100644 --- a/packages/cross_file/CHANGELOG.md +++ b/packages/cross_file/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.1 + +* Prepare for breaking `package:http` change. + ## 0.2.0 * **breaking change** Make sure the `saveTo` method returns a `Future` so it can be awaited and users are sure the file has been written to disk. @@ -12,4 +16,4 @@ ## 0.1.0 -- Initial open-source release \ No newline at end of file +- Initial open-source release diff --git a/packages/cross_file/lib/src/types/html.dart b/packages/cross_file/lib/src/types/html.dart index 646939612d75..527d5e6911f6 100644 --- a/packages/cross_file/lib/src/types/html.dart +++ b/packages/cross_file/lib/src/types/html.dart @@ -3,14 +3,14 @@ // found in the LICENSE file. import 'dart:convert'; +import 'dart:html'; import 'dart:typed_data'; import 'package:http/http.dart' as http show readBytes; import 'package:meta/meta.dart'; -import 'dart:html'; -import '../web_helpers/web_helpers.dart'; import './base.dart'; +import '../web_helpers/web_helpers.dart'; /// A CrossFile that works on web. /// @@ -82,7 +82,7 @@ class XFile extends XFileBase { if (_data != null) { return Future.value(UnmodifiableUint8ListView(_data)); } - return http.readBytes(path); + return http.readBytes(Uri.parse(path)); } @override diff --git a/packages/cross_file/pubspec.yaml b/packages/cross_file/pubspec.yaml index 4c9acf9b008a..2228674baf40 100644 --- a/packages/cross_file/pubspec.yaml +++ b/packages/cross_file/pubspec.yaml @@ -1,7 +1,7 @@ name: cross_file description: An abstraction to allow working with files across multiple platforms. homepage: https://github.com/flutter/plugins/tree/master/packages/cross_file -version: 0.2.0 +version: 0.2.1 dependencies: flutter: From ced7fd696bba11cd0aabeb14a47b68b1fa5ed0c4 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 25 Jan 2021 20:59:24 -0800 Subject: [PATCH 0062/1565] [path_provider] drop uuid (#3465) --- packages/path_provider/path_provider/CHANGELOG.md | 4 ++++ packages/path_provider/path_provider/pubspec.yaml | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/path_provider/path_provider/CHANGELOG.md b/packages/path_provider/path_provider/CHANGELOG.md index bd6c0bc651f5..43e765aaf0b4 100644 --- a/packages/path_provider/path_provider/CHANGELOG.md +++ b/packages/path_provider/path_provider/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.28 + +* Drop unused UUID dependency for tests. + ## 1.6.27 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. diff --git a/packages/path_provider/path_provider/pubspec.yaml b/packages/path_provider/path_provider/pubspec.yaml index 649b3420d72f..065c53fec9fd 100644 --- a/packages/path_provider/path_provider/pubspec.yaml +++ b/packages/path_provider/path_provider/pubspec.yaml @@ -1,7 +1,7 @@ name: path_provider description: Flutter plugin for getting commonly used locations on host platform file systems, such as the temp and app data directories. homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider -version: 1.6.27 +version: 1.6.28 flutter: plugin: @@ -33,7 +33,6 @@ dev_dependencies: sdk: flutter flutter_driver: sdk: flutter - uuid: "^1.0.0" pedantic: ^1.8.0 mockito: ^4.1.1 plugin_platform_interface: ^1.0.0 From ca9921196a7ae96edad91a9cd7b7d8fe9f5689ff Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Tue, 26 Jan 2021 11:16:40 -0800 Subject: [PATCH 0063/1565] [cross_file] Migrate to null-safety. (#3452) Also: skip some packages from the all_plugins app so CI passes. --- packages/cross_file/CHANGELOG.md | 12 ++- packages/cross_file/lib/src/types/base.dart | 10 +-- packages/cross_file/lib/src/types/html.dart | 79 +++++++++---------- .../cross_file/lib/src/types/interface.dart | 26 +++--- packages/cross_file/lib/src/types/io.dart | 32 ++++---- .../lib/src/web_helpers/web_helpers.dart | 2 +- packages/cross_file/pubspec.yaml | 9 +-- .../cross_file/test/x_file_html_test.dart | 18 ++--- packages/cross_file/test/x_file_io_test.dart | 2 +- script/build_all_plugins_app.sh | 3 +- script/nnbd_plugins.sh | 1 + 11 files changed, 99 insertions(+), 95 deletions(-) diff --git a/packages/cross_file/CHANGELOG.md b/packages/cross_file/CHANGELOG.md index 45f516ad334d..c9b3d1ab2522 100644 --- a/packages/cross_file/CHANGELOG.md +++ b/packages/cross_file/CHANGELOG.md @@ -1,6 +1,12 @@ +## 0.3.0-nullsafety + +* Migrated package to null-safety. +* **breaking change** According to our unit tests, the API should be backwards-compatible. Some relevant changes were made, however: + * Web: `lastModified` returns the epoch time as a default value, to maintain the `Future` return type (and not `null`) + ## 0.2.1 -* Prepare for breaking `package:http` change. +* Prepare for breaking `package:http` change. ## 0.2.0 @@ -12,8 +18,8 @@ ## 0.1.0+1 -- Update Flutter SDK constraint. +* Update Flutter SDK constraint. ## 0.1.0 -- Initial open-source release +* Initial open-source release. diff --git a/packages/cross_file/lib/src/types/base.dart b/packages/cross_file/lib/src/types/base.dart index 1a1b5694d58f..2a59c1c2b246 100644 --- a/packages/cross_file/lib/src/types/base.dart +++ b/packages/cross_file/lib/src/types/base.dart @@ -15,7 +15,7 @@ import 'dart:typed_data'; /// the methods should seem familiar. abstract class XFileBase { /// Construct a CrossFile - XFileBase(String path); + XFileBase(String? path); /// Save the CrossFile at the indicated file path. Future saveTo(String path) { @@ -31,19 +31,19 @@ abstract class XFileBase { /// Accessing the data contained in the picked file by its path /// is platform-dependant (and won't work on web), so use the /// byte getters in the CrossFile instance instead. - String get path { + String? get path { throw UnimplementedError('.path has not been implemented.'); } /// The name of the file as it was selected by the user in their device. /// /// Use only for cosmetic reasons, do not try to use this as a path. - String get name { + String? get name { throw UnimplementedError('.name has not been implemented.'); } /// For web, it may be necessary for a file to know its MIME type. - String get mimeType { + String? get mimeType { throw UnimplementedError('.mimeType has not been implemented.'); } @@ -75,7 +75,7 @@ abstract class XFileBase { /// If `end` is present, only up to byte-index `end` will be read. Otherwise, until end of file. /// /// In order to make sure that system resources are freed, the stream must be read to completion or the subscription on the stream must be cancelled. - Stream openRead([int start, int end]) { + Stream openRead([int? start, int? end]) { throw UnimplementedError('openRead() has not been implemented.'); } diff --git a/packages/cross_file/lib/src/types/html.dart b/packages/cross_file/lib/src/types/html.dart index 527d5e6911f6..203ab5d82e12 100644 --- a/packages/cross_file/lib/src/types/html.dart +++ b/packages/cross_file/lib/src/types/html.dart @@ -6,7 +6,6 @@ import 'dart:convert'; import 'dart:html'; import 'dart:typed_data'; -import 'package:http/http.dart' as http show readBytes; import 'package:meta/meta.dart'; import './base.dart'; @@ -16,16 +15,17 @@ import '../web_helpers/web_helpers.dart'; /// /// It wraps the bytes of a selected file. class XFile extends XFileBase { - String path; + late String path; - final String mimeType; - final Uint8List _data; - final int _length; + final String? mimeType; + final Uint8List? _data; + final int? _length; final String name; - final DateTime _lastModified; - Element _target; + final DateTime? _lastModified; - final CrossFileTestOverrides _overrides; + late Element _target; + + final CrossFileTestOverrides? _overrides; bool get _hasTestOverrides => _overrides != null; @@ -39,56 +39,58 @@ class XFile extends XFileBase { XFile( this.path, { this.mimeType, - this.name, - int length, - Uint8List bytes, - DateTime lastModified, - @visibleForTesting CrossFileTestOverrides overrides, + String? name, + int? length, + Uint8List? bytes, + DateTime? lastModified, + @visibleForTesting CrossFileTestOverrides? overrides, }) : _data = bytes, _length = length, _overrides = overrides, - _lastModified = lastModified, + _lastModified = lastModified ?? DateTime.fromMillisecondsSinceEpoch(0), + name = name ?? '', super(path); /// Construct an CrossFile from its data XFile.fromData( Uint8List bytes, { this.mimeType, - this.name, - int length, - DateTime lastModified, - this.path, - @visibleForTesting CrossFileTestOverrides overrides, + String? name, + int? length, + DateTime? lastModified, + String? path, + @visibleForTesting CrossFileTestOverrides? overrides, }) : _data = bytes, _length = length, _overrides = overrides, - _lastModified = lastModified, + _lastModified = lastModified ?? DateTime.fromMillisecondsSinceEpoch(0), + name = name ?? '', super(path) { if (path == null) { final blob = (mimeType == null) ? Blob([bytes]) : Blob([bytes], mimeType); this.path = Url.createObjectUrl(blob); + } else { + this.path = path; } } @override - Future lastModified() async { - if (_lastModified != null) { - return Future.value(_lastModified); - } - return null; - } + Future lastModified() async => Future.value(_lastModified); Future get _bytes async { if (_data != null) { - return Future.value(UnmodifiableUint8ListView(_data)); + return Future.value(UnmodifiableUint8ListView(_data!)); } - return http.readBytes(Uri.parse(path)); + + // We can force 'response' to be a byte buffer by passing responseType: + ByteBuffer? response = + (await HttpRequest.request(path, responseType: 'arraybuffer')).response; + + return response?.asUint8List() ?? Uint8List(0); } @override - Future length() async { - return _length ?? (await _bytes).length; - } + Future length() async => _length ?? (await _bytes).length; @override Future readAsString({Encoding encoding = utf8}) async { @@ -96,12 +98,10 @@ class XFile extends XFileBase { } @override - Future readAsBytes() async { - return Future.value(await _bytes); - } + Future readAsBytes() async => Future.value(await _bytes); @override - Stream openRead([int start, int end]) async* { + Stream openRead([int? start, int? end]) async* { final bytes = await _bytes; yield bytes.sublist(start ?? 0, end ?? bytes.length); } @@ -114,10 +114,9 @@ class XFile extends XFileBase { // Create an tag with the appropriate download attributes and click it // May be overridden with CrossFileTestOverrides - final AnchorElement element = - (_hasTestOverrides && _overrides.createAnchorElement != null) - ? _overrides.createAnchorElement(this.path, this.name) - : createAnchorElement(this.path, this.name); + final AnchorElement element = _hasTestOverrides + ? _overrides!.createAnchorElement(this.path, this.name) as AnchorElement + : createAnchorElement(this.path, this.name); // Clear the children in our container so we can add an element to click _target.children.clear(); @@ -132,5 +131,5 @@ class CrossFileTestOverrides { Element Function(String href, String suggestedName) createAnchorElement; /// Default constructor for overrides - CrossFileTestOverrides({this.createAnchorElement}); + CrossFileTestOverrides({required this.createAnchorElement}); } diff --git a/packages/cross_file/lib/src/types/interface.dart b/packages/cross_file/lib/src/types/interface.dart index e30bc63b4c92..122f3d1d9364 100644 --- a/packages/cross_file/lib/src/types/interface.dart +++ b/packages/cross_file/lib/src/types/interface.dart @@ -21,12 +21,12 @@ class XFile extends XFileBase { /// (like in web) XFile( String path, { - String mimeType, - String name, - int length, - Uint8List bytes, - DateTime lastModified, - @visibleForTesting CrossFileTestOverrides overrides, + String? mimeType, + String? name, + int? length, + Uint8List? bytes, + DateTime? lastModified, + @visibleForTesting CrossFileTestOverrides? overrides, }) : super(path) { throw UnimplementedError( 'CrossFile is not available in your current platform.'); @@ -35,12 +35,12 @@ class XFile extends XFileBase { /// Construct a CrossFile object from its data XFile.fromData( Uint8List bytes, { - String mimeType, - String name, - int length, - DateTime lastModified, - String path, - @visibleForTesting CrossFileTestOverrides overrides, + String? mimeType, + String? name, + int? length, + DateTime? lastModified, + String? path, + @visibleForTesting CrossFileTestOverrides? overrides, }) : super(path) { throw UnimplementedError( 'CrossFile is not available in your current platform.'); @@ -54,5 +54,5 @@ class CrossFileTestOverrides { dynamic Function(String href, String suggestedName) createAnchorElement; /// Default constructor for overrides - CrossFileTestOverrides({this.createAnchorElement}); + CrossFileTestOverrides({required this.createAnchorElement}); } diff --git a/packages/cross_file/lib/src/types/io.dart b/packages/cross_file/lib/src/types/io.dart index d9a93559b507..6eafaf0ce0cc 100644 --- a/packages/cross_file/lib/src/types/io.dart +++ b/packages/cross_file/lib/src/types/io.dart @@ -11,20 +11,20 @@ import './base.dart'; /// A CrossFile backed by a dart:io File. class XFile extends XFileBase { final File _file; - final String mimeType; - final DateTime _lastModified; - int _length; + final String? mimeType; + final DateTime? _lastModified; + int? _length; - final Uint8List _bytes; + final Uint8List? _bytes; /// Construct a CrossFile object backed by a dart:io File. XFile( String path, { this.mimeType, - String name, - int length, - Uint8List bytes, - DateTime lastModified, + String? name, + int? length, + Uint8List? bytes, + DateTime? lastModified, }) : _file = File(path), _bytes = null, _lastModified = lastModified, @@ -34,10 +34,10 @@ class XFile extends XFileBase { XFile.fromData( Uint8List bytes, { this.mimeType, - String path, - String name, - int length, - DateTime lastModified, + String? path, + String? name, + int? length, + DateTime? lastModified, }) : _bytes = bytes, _file = File(path ?? ''), _length = length, @@ -84,7 +84,7 @@ class XFile extends XFileBase { @override Future readAsString({Encoding encoding = utf8}) { if (_bytes != null) { - return Future.value(String.fromCharCodes(_bytes)); + return Future.value(String.fromCharCodes(_bytes!)); } return _file.readAsString(encoding: encoding); } @@ -97,13 +97,13 @@ class XFile extends XFileBase { return _file.readAsBytes(); } - Stream _getBytes(int start, int end) async* { - final bytes = _bytes; + Stream _getBytes(int? start, int? end) async* { + final bytes = _bytes!; yield bytes.sublist(start ?? 0, end ?? bytes.length); } @override - Stream openRead([int start, int end]) { + Stream openRead([int? start, int? end]) { if (_bytes != null) { return _getBytes(start, end); } else { diff --git a/packages/cross_file/lib/src/web_helpers/web_helpers.dart b/packages/cross_file/lib/src/web_helpers/web_helpers.dart index 813f5f975561..a963e9933f99 100644 --- a/packages/cross_file/lib/src/web_helpers/web_helpers.dart +++ b/packages/cross_file/lib/src/web_helpers/web_helpers.dart @@ -31,7 +31,7 @@ Element ensureInitialized(String id) { if (target == null) { final Element targetElement = Element.tag('flt-x-file')..id = id; - querySelector('body').children.add(targetElement); + querySelector('body')!.children.add(targetElement); target = targetElement; } return target; diff --git a/packages/cross_file/pubspec.yaml b/packages/cross_file/pubspec.yaml index 2228674baf40..af1b7e7d4c0f 100644 --- a/packages/cross_file/pubspec.yaml +++ b/packages/cross_file/pubspec.yaml @@ -1,19 +1,18 @@ name: cross_file description: An abstraction to allow working with files across multiple platforms. homepage: https://github.com/flutter/plugins/tree/master/packages/cross_file -version: 0.2.1 +version: 0.3.0-nullsafety dependencies: flutter: sdk: flutter - http: ^0.12.0+1 - meta: ^1.0.5 + meta: ^1.3.0-nullsafety.3 dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0-nullsafety.3 environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.22.0" diff --git a/packages/cross_file/test/x_file_html_test.dart b/packages/cross_file/test/x_file_html_test.dart index fadba96b3c6c..a271aa1f1525 100644 --- a/packages/cross_file/test/x_file_html_test.dart +++ b/packages/cross_file/test/x_file_html_test.dart @@ -11,10 +11,8 @@ import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; import 'package:cross_file/cross_file.dart'; -import 'dart:html'; - final String expectedStringContents = 'Hello, world!'; -final Uint8List bytes = utf8.encode(expectedStringContents); +final Uint8List bytes = Uint8List.fromList(utf8.encode(expectedStringContents)); final html.File textFile = html.File([bytes], 'hello.txt'); final String textFileUrl = html.Url.createObjectUrl(textFile); @@ -66,7 +64,7 @@ void main() { await file.saveTo(''); - final container = querySelector('#${CrossFileDomElementId}'); + final container = html.querySelector('#${CrossFileDomElementId}'); expect(container, isNotNull); }); @@ -76,18 +74,18 @@ void main() { await file.saveTo('path'); - final container = querySelector('#${CrossFileDomElementId}'); - final AnchorElement element = container?.children?.firstWhere( - (element) => element.tagName == 'A', - orElse: () => null); + final container = html.querySelector('#${CrossFileDomElementId}'); + final html.AnchorElement element = + container?.children.firstWhere((element) => element.tagName == 'A') + as html.AnchorElement; - expect(element, isNotNull); + // if element is not found, the `firstWhere` call will throw StateError. expect(element.href, file.path); expect(element.download, file.name); }); test('anchor element is clicked', () async { - final mockAnchor = AnchorElement(); + final mockAnchor = html.AnchorElement(); CrossFileTestOverrides overrides = CrossFileTestOverrides( createAnchorElement: (_, __) => mockAnchor, diff --git a/packages/cross_file/test/x_file_io_test.dart b/packages/cross_file/test/x_file_io_test.dart index 65edea1ea45d..25f46a4edad9 100644 --- a/packages/cross_file/test/x_file_io_test.dart +++ b/packages/cross_file/test/x_file_io_test.dart @@ -24,7 +24,7 @@ import 'package:cross_file/cross_file.dart'; final pathPrefix = './assets/'; final path = pathPrefix + 'hello.txt'; final String expectedStringContents = 'Hello, world!'; -final Uint8List bytes = utf8.encode(expectedStringContents); +final Uint8List bytes = Uint8List.fromList(utf8.encode(expectedStringContents)); final File textFile = File(path); final String textFilePath = textFile.path; diff --git a/script/build_all_plugins_app.sh b/script/build_all_plugins_app.sh index 72390c213da9..3e08b914ff86 100755 --- a/script/build_all_plugins_app.sh +++ b/script/build_all_plugins_app.sh @@ -23,14 +23,15 @@ readonly EXCLUDED_PLUGINS_LIST=( "connectivity_platform_interface" "connectivity_web" "extension_google_sign_in_as_googleapis_auth" + "file_selector" # currently out of sync with camera "flutter_plugin_android_lifecycle" "google_maps_flutter_platform_interface" "google_maps_flutter_web" "google_sign_in_platform_interface" "google_sign_in_web" "image_picker_platform_interface" - "local_auth" # flutter_plugin_android_lifecycle conflict "instrumentation_adapter" + "local_auth" # flutter_plugin_android_lifecycle conflict "path_provider_linux" "path_provider_macos" "path_provider_platform_interface" diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index b2ca25bf6836..44e5df9e95ef 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -8,6 +8,7 @@ readonly NNBD_PLUGINS_LIST=( "android_intent" "battery" "connectivity" + "cross_file" "device_info" "flutter_plugin_android_lifecycle" "flutter_webview" From 98d87d0589b2895d0e027cedc98fd88baf6ab2ed Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 26 Jan 2021 14:17:07 -0800 Subject: [PATCH 0064/1565] [image_picker_platform_interface] fix test asset file location (#3467) --- packages/cross_file/test/x_file_io_test.dart | 15 +++------------ .../image_picker_platform_interface/CHANGELOG.md | 4 ++++ .../image_picker_platform_interface/pubspec.yaml | 2 +- .../test/picked_file_io_test.dart | 9 ++++++--- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/packages/cross_file/test/x_file_io_test.dart b/packages/cross_file/test/x_file_io_test.dart index 25f46a4edad9..94ac81c4cac4 100644 --- a/packages/cross_file/test/x_file_io_test.dart +++ b/packages/cross_file/test/x_file_io_test.dart @@ -11,17 +11,8 @@ import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; import 'package:cross_file/cross_file.dart'; -// Please note that executing this test with command -// `flutter test test/x_file_io_test.dart` will set the directory -// to ./file_selector_platform_interface. -// -// This will cause our hello.txt file to be not be found. Please -// execute this test with `flutter test` or change the path prefix -// to ./test/assets/ -// -// https://github.com/flutter/flutter/issues/20907 - -final pathPrefix = './assets/'; +final pathPrefix = + Directory.current.path.endsWith('test') ? './assets/' : './test/assets/'; final path = pathPrefix + 'hello.txt'; final String expectedStringContents = 'Hello, world!'; final Uint8List bytes = Uint8List.fromList(utf8.encode(expectedStringContents)); @@ -30,7 +21,7 @@ final String textFilePath = textFile.path; void main() { group('Create with a path', () { - final file = XFile(textFilePath); + final XFile file = XFile(textFilePath); test('Can be read as a string', () async { expect(await file.readAsString(), equals(expectedStringContents)); diff --git a/packages/image_picker/image_picker_platform_interface/CHANGELOG.md b/packages/image_picker/image_picker_platform_interface/CHANGELOG.md index efcef0146cdc..581cf1830610 100644 --- a/packages/image_picker/image_picker_platform_interface/CHANGELOG.md +++ b/packages/image_picker/image_picker_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.6 + +* Fix test asset file location. + ## 1.1.5 * Update Flutter SDK constraint. diff --git a/packages/image_picker/image_picker_platform_interface/pubspec.yaml b/packages/image_picker/image_picker_platform_interface/pubspec.yaml index 7943a2a3eccd..b9ad12a50eb6 100644 --- a/packages/image_picker/image_picker_platform_interface/pubspec.yaml +++ b/packages/image_picker/image_picker_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the image_picker plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.1.5 +version: 1.1.6 dependencies: flutter: diff --git a/packages/image_picker/image_picker_platform_interface/test/picked_file_io_test.dart b/packages/image_picker/image_picker_platform_interface/test/picked_file_io_test.dart index 94ff759a2fb2..28c0886b864e 100644 --- a/packages/image_picker/image_picker_platform_interface/test/picked_file_io_test.dart +++ b/packages/image_picker/image_picker_platform_interface/test/picked_file_io_test.dart @@ -11,14 +11,17 @@ import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; +final pathPrefix = + Directory.current.path.endsWith('test') ? './assets/' : './test/assets/'; +final path = pathPrefix + 'hello.txt'; final String expectedStringContents = 'Hello, world!'; -final Uint8List bytes = utf8.encode(expectedStringContents); -final File textFile = File('./assets/hello.txt'); +final Uint8List bytes = Uint8List.fromList(utf8.encode(expectedStringContents)); +final File textFile = File(path); final String textFilePath = textFile.path; void main() { group('Create with an objectUrl', () { - final pickedFile = PickedFile(textFilePath); + final PickedFile pickedFile = PickedFile(textFilePath); test('Can be read as a string', () async { expect(await pickedFile.readAsString(), equals(expectedStringContents)); From 4aacf970f3891c9cf23c768ca1c8bec04c42b35a Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Tue, 26 Jan 2021 17:33:26 -0800 Subject: [PATCH 0065/1565] Revert "[cross_file] Migrate to null-safety. (#3452)" (#3468) This reverts commit ca9921196a7ae96edad91a9cd7b7d8fe9f5689ff. --- packages/cross_file/CHANGELOG.md | 12 +-- packages/cross_file/lib/src/types/base.dart | 10 +-- packages/cross_file/lib/src/types/html.dart | 79 ++++++++++--------- .../cross_file/lib/src/types/interface.dart | 26 +++--- packages/cross_file/lib/src/types/io.dart | 32 ++++---- .../lib/src/web_helpers/web_helpers.dart | 2 +- packages/cross_file/pubspec.yaml | 9 ++- .../cross_file/test/x_file_html_test.dart | 18 +++-- packages/cross_file/test/x_file_io_test.dart | 2 +- script/build_all_plugins_app.sh | 3 +- script/nnbd_plugins.sh | 1 - 11 files changed, 95 insertions(+), 99 deletions(-) diff --git a/packages/cross_file/CHANGELOG.md b/packages/cross_file/CHANGELOG.md index c9b3d1ab2522..45f516ad334d 100644 --- a/packages/cross_file/CHANGELOG.md +++ b/packages/cross_file/CHANGELOG.md @@ -1,12 +1,6 @@ -## 0.3.0-nullsafety - -* Migrated package to null-safety. -* **breaking change** According to our unit tests, the API should be backwards-compatible. Some relevant changes were made, however: - * Web: `lastModified` returns the epoch time as a default value, to maintain the `Future` return type (and not `null`) - ## 0.2.1 -* Prepare for breaking `package:http` change. +* Prepare for breaking `package:http` change. ## 0.2.0 @@ -18,8 +12,8 @@ ## 0.1.0+1 -* Update Flutter SDK constraint. +- Update Flutter SDK constraint. ## 0.1.0 -* Initial open-source release. +- Initial open-source release diff --git a/packages/cross_file/lib/src/types/base.dart b/packages/cross_file/lib/src/types/base.dart index 2a59c1c2b246..1a1b5694d58f 100644 --- a/packages/cross_file/lib/src/types/base.dart +++ b/packages/cross_file/lib/src/types/base.dart @@ -15,7 +15,7 @@ import 'dart:typed_data'; /// the methods should seem familiar. abstract class XFileBase { /// Construct a CrossFile - XFileBase(String? path); + XFileBase(String path); /// Save the CrossFile at the indicated file path. Future saveTo(String path) { @@ -31,19 +31,19 @@ abstract class XFileBase { /// Accessing the data contained in the picked file by its path /// is platform-dependant (and won't work on web), so use the /// byte getters in the CrossFile instance instead. - String? get path { + String get path { throw UnimplementedError('.path has not been implemented.'); } /// The name of the file as it was selected by the user in their device. /// /// Use only for cosmetic reasons, do not try to use this as a path. - String? get name { + String get name { throw UnimplementedError('.name has not been implemented.'); } /// For web, it may be necessary for a file to know its MIME type. - String? get mimeType { + String get mimeType { throw UnimplementedError('.mimeType has not been implemented.'); } @@ -75,7 +75,7 @@ abstract class XFileBase { /// If `end` is present, only up to byte-index `end` will be read. Otherwise, until end of file. /// /// In order to make sure that system resources are freed, the stream must be read to completion or the subscription on the stream must be cancelled. - Stream openRead([int? start, int? end]) { + Stream openRead([int start, int end]) { throw UnimplementedError('openRead() has not been implemented.'); } diff --git a/packages/cross_file/lib/src/types/html.dart b/packages/cross_file/lib/src/types/html.dart index 203ab5d82e12..527d5e6911f6 100644 --- a/packages/cross_file/lib/src/types/html.dart +++ b/packages/cross_file/lib/src/types/html.dart @@ -6,6 +6,7 @@ import 'dart:convert'; import 'dart:html'; import 'dart:typed_data'; +import 'package:http/http.dart' as http show readBytes; import 'package:meta/meta.dart'; import './base.dart'; @@ -15,17 +16,16 @@ import '../web_helpers/web_helpers.dart'; /// /// It wraps the bytes of a selected file. class XFile extends XFileBase { - late String path; + String path; - final String? mimeType; - final Uint8List? _data; - final int? _length; + final String mimeType; + final Uint8List _data; + final int _length; final String name; - final DateTime? _lastModified; + final DateTime _lastModified; + Element _target; - late Element _target; - - final CrossFileTestOverrides? _overrides; + final CrossFileTestOverrides _overrides; bool get _hasTestOverrides => _overrides != null; @@ -39,58 +39,56 @@ class XFile extends XFileBase { XFile( this.path, { this.mimeType, - String? name, - int? length, - Uint8List? bytes, - DateTime? lastModified, - @visibleForTesting CrossFileTestOverrides? overrides, + this.name, + int length, + Uint8List bytes, + DateTime lastModified, + @visibleForTesting CrossFileTestOverrides overrides, }) : _data = bytes, _length = length, _overrides = overrides, - _lastModified = lastModified ?? DateTime.fromMillisecondsSinceEpoch(0), - name = name ?? '', + _lastModified = lastModified, super(path); /// Construct an CrossFile from its data XFile.fromData( Uint8List bytes, { this.mimeType, - String? name, - int? length, - DateTime? lastModified, - String? path, - @visibleForTesting CrossFileTestOverrides? overrides, + this.name, + int length, + DateTime lastModified, + this.path, + @visibleForTesting CrossFileTestOverrides overrides, }) : _data = bytes, _length = length, _overrides = overrides, - _lastModified = lastModified ?? DateTime.fromMillisecondsSinceEpoch(0), - name = name ?? '', + _lastModified = lastModified, super(path) { if (path == null) { final blob = (mimeType == null) ? Blob([bytes]) : Blob([bytes], mimeType); this.path = Url.createObjectUrl(blob); - } else { - this.path = path; } } @override - Future lastModified() async => Future.value(_lastModified); + Future lastModified() async { + if (_lastModified != null) { + return Future.value(_lastModified); + } + return null; + } Future get _bytes async { if (_data != null) { - return Future.value(UnmodifiableUint8ListView(_data!)); + return Future.value(UnmodifiableUint8ListView(_data)); } - - // We can force 'response' to be a byte buffer by passing responseType: - ByteBuffer? response = - (await HttpRequest.request(path, responseType: 'arraybuffer')).response; - - return response?.asUint8List() ?? Uint8List(0); + return http.readBytes(Uri.parse(path)); } @override - Future length() async => _length ?? (await _bytes).length; + Future length() async { + return _length ?? (await _bytes).length; + } @override Future readAsString({Encoding encoding = utf8}) async { @@ -98,10 +96,12 @@ class XFile extends XFileBase { } @override - Future readAsBytes() async => Future.value(await _bytes); + Future readAsBytes() async { + return Future.value(await _bytes); + } @override - Stream openRead([int? start, int? end]) async* { + Stream openRead([int start, int end]) async* { final bytes = await _bytes; yield bytes.sublist(start ?? 0, end ?? bytes.length); } @@ -114,9 +114,10 @@ class XFile extends XFileBase { // Create an tag with the appropriate download attributes and click it // May be overridden with CrossFileTestOverrides - final AnchorElement element = _hasTestOverrides - ? _overrides!.createAnchorElement(this.path, this.name) as AnchorElement - : createAnchorElement(this.path, this.name); + final AnchorElement element = + (_hasTestOverrides && _overrides.createAnchorElement != null) + ? _overrides.createAnchorElement(this.path, this.name) + : createAnchorElement(this.path, this.name); // Clear the children in our container so we can add an element to click _target.children.clear(); @@ -131,5 +132,5 @@ class CrossFileTestOverrides { Element Function(String href, String suggestedName) createAnchorElement; /// Default constructor for overrides - CrossFileTestOverrides({required this.createAnchorElement}); + CrossFileTestOverrides({this.createAnchorElement}); } diff --git a/packages/cross_file/lib/src/types/interface.dart b/packages/cross_file/lib/src/types/interface.dart index 122f3d1d9364..e30bc63b4c92 100644 --- a/packages/cross_file/lib/src/types/interface.dart +++ b/packages/cross_file/lib/src/types/interface.dart @@ -21,12 +21,12 @@ class XFile extends XFileBase { /// (like in web) XFile( String path, { - String? mimeType, - String? name, - int? length, - Uint8List? bytes, - DateTime? lastModified, - @visibleForTesting CrossFileTestOverrides? overrides, + String mimeType, + String name, + int length, + Uint8List bytes, + DateTime lastModified, + @visibleForTesting CrossFileTestOverrides overrides, }) : super(path) { throw UnimplementedError( 'CrossFile is not available in your current platform.'); @@ -35,12 +35,12 @@ class XFile extends XFileBase { /// Construct a CrossFile object from its data XFile.fromData( Uint8List bytes, { - String? mimeType, - String? name, - int? length, - DateTime? lastModified, - String? path, - @visibleForTesting CrossFileTestOverrides? overrides, + String mimeType, + String name, + int length, + DateTime lastModified, + String path, + @visibleForTesting CrossFileTestOverrides overrides, }) : super(path) { throw UnimplementedError( 'CrossFile is not available in your current platform.'); @@ -54,5 +54,5 @@ class CrossFileTestOverrides { dynamic Function(String href, String suggestedName) createAnchorElement; /// Default constructor for overrides - CrossFileTestOverrides({required this.createAnchorElement}); + CrossFileTestOverrides({this.createAnchorElement}); } diff --git a/packages/cross_file/lib/src/types/io.dart b/packages/cross_file/lib/src/types/io.dart index 6eafaf0ce0cc..d9a93559b507 100644 --- a/packages/cross_file/lib/src/types/io.dart +++ b/packages/cross_file/lib/src/types/io.dart @@ -11,20 +11,20 @@ import './base.dart'; /// A CrossFile backed by a dart:io File. class XFile extends XFileBase { final File _file; - final String? mimeType; - final DateTime? _lastModified; - int? _length; + final String mimeType; + final DateTime _lastModified; + int _length; - final Uint8List? _bytes; + final Uint8List _bytes; /// Construct a CrossFile object backed by a dart:io File. XFile( String path, { this.mimeType, - String? name, - int? length, - Uint8List? bytes, - DateTime? lastModified, + String name, + int length, + Uint8List bytes, + DateTime lastModified, }) : _file = File(path), _bytes = null, _lastModified = lastModified, @@ -34,10 +34,10 @@ class XFile extends XFileBase { XFile.fromData( Uint8List bytes, { this.mimeType, - String? path, - String? name, - int? length, - DateTime? lastModified, + String path, + String name, + int length, + DateTime lastModified, }) : _bytes = bytes, _file = File(path ?? ''), _length = length, @@ -84,7 +84,7 @@ class XFile extends XFileBase { @override Future readAsString({Encoding encoding = utf8}) { if (_bytes != null) { - return Future.value(String.fromCharCodes(_bytes!)); + return Future.value(String.fromCharCodes(_bytes)); } return _file.readAsString(encoding: encoding); } @@ -97,13 +97,13 @@ class XFile extends XFileBase { return _file.readAsBytes(); } - Stream _getBytes(int? start, int? end) async* { - final bytes = _bytes!; + Stream _getBytes(int start, int end) async* { + final bytes = _bytes; yield bytes.sublist(start ?? 0, end ?? bytes.length); } @override - Stream openRead([int? start, int? end]) { + Stream openRead([int start, int end]) { if (_bytes != null) { return _getBytes(start, end); } else { diff --git a/packages/cross_file/lib/src/web_helpers/web_helpers.dart b/packages/cross_file/lib/src/web_helpers/web_helpers.dart index a963e9933f99..813f5f975561 100644 --- a/packages/cross_file/lib/src/web_helpers/web_helpers.dart +++ b/packages/cross_file/lib/src/web_helpers/web_helpers.dart @@ -31,7 +31,7 @@ Element ensureInitialized(String id) { if (target == null) { final Element targetElement = Element.tag('flt-x-file')..id = id; - querySelector('body')!.children.add(targetElement); + querySelector('body').children.add(targetElement); target = targetElement; } return target; diff --git a/packages/cross_file/pubspec.yaml b/packages/cross_file/pubspec.yaml index af1b7e7d4c0f..2228674baf40 100644 --- a/packages/cross_file/pubspec.yaml +++ b/packages/cross_file/pubspec.yaml @@ -1,18 +1,19 @@ name: cross_file description: An abstraction to allow working with files across multiple platforms. homepage: https://github.com/flutter/plugins/tree/master/packages/cross_file -version: 0.3.0-nullsafety +version: 0.2.1 dependencies: flutter: sdk: flutter - meta: ^1.3.0-nullsafety.3 + http: ^0.12.0+1 + meta: ^1.0.5 dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.10.0-nullsafety.3 + pedantic: ^1.8.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.1.0 <3.0.0" flutter: ">=1.22.0" diff --git a/packages/cross_file/test/x_file_html_test.dart b/packages/cross_file/test/x_file_html_test.dart index a271aa1f1525..fadba96b3c6c 100644 --- a/packages/cross_file/test/x_file_html_test.dart +++ b/packages/cross_file/test/x_file_html_test.dart @@ -11,8 +11,10 @@ import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; import 'package:cross_file/cross_file.dart'; +import 'dart:html'; + final String expectedStringContents = 'Hello, world!'; -final Uint8List bytes = Uint8List.fromList(utf8.encode(expectedStringContents)); +final Uint8List bytes = utf8.encode(expectedStringContents); final html.File textFile = html.File([bytes], 'hello.txt'); final String textFileUrl = html.Url.createObjectUrl(textFile); @@ -64,7 +66,7 @@ void main() { await file.saveTo(''); - final container = html.querySelector('#${CrossFileDomElementId}'); + final container = querySelector('#${CrossFileDomElementId}'); expect(container, isNotNull); }); @@ -74,18 +76,18 @@ void main() { await file.saveTo('path'); - final container = html.querySelector('#${CrossFileDomElementId}'); - final html.AnchorElement element = - container?.children.firstWhere((element) => element.tagName == 'A') - as html.AnchorElement; + final container = querySelector('#${CrossFileDomElementId}'); + final AnchorElement element = container?.children?.firstWhere( + (element) => element.tagName == 'A', + orElse: () => null); - // if element is not found, the `firstWhere` call will throw StateError. + expect(element, isNotNull); expect(element.href, file.path); expect(element.download, file.name); }); test('anchor element is clicked', () async { - final mockAnchor = html.AnchorElement(); + final mockAnchor = AnchorElement(); CrossFileTestOverrides overrides = CrossFileTestOverrides( createAnchorElement: (_, __) => mockAnchor, diff --git a/packages/cross_file/test/x_file_io_test.dart b/packages/cross_file/test/x_file_io_test.dart index 94ac81c4cac4..d45ff599fec1 100644 --- a/packages/cross_file/test/x_file_io_test.dart +++ b/packages/cross_file/test/x_file_io_test.dart @@ -15,7 +15,7 @@ final pathPrefix = Directory.current.path.endsWith('test') ? './assets/' : './test/assets/'; final path = pathPrefix + 'hello.txt'; final String expectedStringContents = 'Hello, world!'; -final Uint8List bytes = Uint8List.fromList(utf8.encode(expectedStringContents)); +final Uint8List bytes = utf8.encode(expectedStringContents); final File textFile = File(path); final String textFilePath = textFile.path; diff --git a/script/build_all_plugins_app.sh b/script/build_all_plugins_app.sh index 3e08b914ff86..72390c213da9 100755 --- a/script/build_all_plugins_app.sh +++ b/script/build_all_plugins_app.sh @@ -23,15 +23,14 @@ readonly EXCLUDED_PLUGINS_LIST=( "connectivity_platform_interface" "connectivity_web" "extension_google_sign_in_as_googleapis_auth" - "file_selector" # currently out of sync with camera "flutter_plugin_android_lifecycle" "google_maps_flutter_platform_interface" "google_maps_flutter_web" "google_sign_in_platform_interface" "google_sign_in_web" "image_picker_platform_interface" - "instrumentation_adapter" "local_auth" # flutter_plugin_android_lifecycle conflict + "instrumentation_adapter" "path_provider_linux" "path_provider_macos" "path_provider_platform_interface" diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index 44e5df9e95ef..b2ca25bf6836 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -8,7 +8,6 @@ readonly NNBD_PLUGINS_LIST=( "android_intent" "battery" "connectivity" - "cross_file" "device_info" "flutter_plugin_android_lifecycle" "flutter_webview" From 16f3281b04b0db12e609352b1c9544901392e428 Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Tue, 26 Jan 2021 18:14:52 -0800 Subject: [PATCH 0066/1565] Reland "[cross_file] Migrate to null-safety. (#3452)" (#3469) This reverts commit 4aacf970f3891c9cf23c768ca1c8bec04c42b35a. --- packages/cross_file/CHANGELOG.md | 12 ++- packages/cross_file/lib/src/types/base.dart | 10 +-- packages/cross_file/lib/src/types/html.dart | 79 +++++++++---------- .../cross_file/lib/src/types/interface.dart | 26 +++--- packages/cross_file/lib/src/types/io.dart | 32 ++++---- .../lib/src/web_helpers/web_helpers.dart | 2 +- packages/cross_file/pubspec.yaml | 9 +-- .../cross_file/test/x_file_html_test.dart | 18 ++--- packages/cross_file/test/x_file_io_test.dart | 2 +- script/build_all_plugins_app.sh | 3 +- script/nnbd_plugins.sh | 1 + 11 files changed, 99 insertions(+), 95 deletions(-) diff --git a/packages/cross_file/CHANGELOG.md b/packages/cross_file/CHANGELOG.md index 45f516ad334d..c9b3d1ab2522 100644 --- a/packages/cross_file/CHANGELOG.md +++ b/packages/cross_file/CHANGELOG.md @@ -1,6 +1,12 @@ +## 0.3.0-nullsafety + +* Migrated package to null-safety. +* **breaking change** According to our unit tests, the API should be backwards-compatible. Some relevant changes were made, however: + * Web: `lastModified` returns the epoch time as a default value, to maintain the `Future` return type (and not `null`) + ## 0.2.1 -* Prepare for breaking `package:http` change. +* Prepare for breaking `package:http` change. ## 0.2.0 @@ -12,8 +18,8 @@ ## 0.1.0+1 -- Update Flutter SDK constraint. +* Update Flutter SDK constraint. ## 0.1.0 -- Initial open-source release +* Initial open-source release. diff --git a/packages/cross_file/lib/src/types/base.dart b/packages/cross_file/lib/src/types/base.dart index 1a1b5694d58f..2a59c1c2b246 100644 --- a/packages/cross_file/lib/src/types/base.dart +++ b/packages/cross_file/lib/src/types/base.dart @@ -15,7 +15,7 @@ import 'dart:typed_data'; /// the methods should seem familiar. abstract class XFileBase { /// Construct a CrossFile - XFileBase(String path); + XFileBase(String? path); /// Save the CrossFile at the indicated file path. Future saveTo(String path) { @@ -31,19 +31,19 @@ abstract class XFileBase { /// Accessing the data contained in the picked file by its path /// is platform-dependant (and won't work on web), so use the /// byte getters in the CrossFile instance instead. - String get path { + String? get path { throw UnimplementedError('.path has not been implemented.'); } /// The name of the file as it was selected by the user in their device. /// /// Use only for cosmetic reasons, do not try to use this as a path. - String get name { + String? get name { throw UnimplementedError('.name has not been implemented.'); } /// For web, it may be necessary for a file to know its MIME type. - String get mimeType { + String? get mimeType { throw UnimplementedError('.mimeType has not been implemented.'); } @@ -75,7 +75,7 @@ abstract class XFileBase { /// If `end` is present, only up to byte-index `end` will be read. Otherwise, until end of file. /// /// In order to make sure that system resources are freed, the stream must be read to completion or the subscription on the stream must be cancelled. - Stream openRead([int start, int end]) { + Stream openRead([int? start, int? end]) { throw UnimplementedError('openRead() has not been implemented.'); } diff --git a/packages/cross_file/lib/src/types/html.dart b/packages/cross_file/lib/src/types/html.dart index 527d5e6911f6..203ab5d82e12 100644 --- a/packages/cross_file/lib/src/types/html.dart +++ b/packages/cross_file/lib/src/types/html.dart @@ -6,7 +6,6 @@ import 'dart:convert'; import 'dart:html'; import 'dart:typed_data'; -import 'package:http/http.dart' as http show readBytes; import 'package:meta/meta.dart'; import './base.dart'; @@ -16,16 +15,17 @@ import '../web_helpers/web_helpers.dart'; /// /// It wraps the bytes of a selected file. class XFile extends XFileBase { - String path; + late String path; - final String mimeType; - final Uint8List _data; - final int _length; + final String? mimeType; + final Uint8List? _data; + final int? _length; final String name; - final DateTime _lastModified; - Element _target; + final DateTime? _lastModified; - final CrossFileTestOverrides _overrides; + late Element _target; + + final CrossFileTestOverrides? _overrides; bool get _hasTestOverrides => _overrides != null; @@ -39,56 +39,58 @@ class XFile extends XFileBase { XFile( this.path, { this.mimeType, - this.name, - int length, - Uint8List bytes, - DateTime lastModified, - @visibleForTesting CrossFileTestOverrides overrides, + String? name, + int? length, + Uint8List? bytes, + DateTime? lastModified, + @visibleForTesting CrossFileTestOverrides? overrides, }) : _data = bytes, _length = length, _overrides = overrides, - _lastModified = lastModified, + _lastModified = lastModified ?? DateTime.fromMillisecondsSinceEpoch(0), + name = name ?? '', super(path); /// Construct an CrossFile from its data XFile.fromData( Uint8List bytes, { this.mimeType, - this.name, - int length, - DateTime lastModified, - this.path, - @visibleForTesting CrossFileTestOverrides overrides, + String? name, + int? length, + DateTime? lastModified, + String? path, + @visibleForTesting CrossFileTestOverrides? overrides, }) : _data = bytes, _length = length, _overrides = overrides, - _lastModified = lastModified, + _lastModified = lastModified ?? DateTime.fromMillisecondsSinceEpoch(0), + name = name ?? '', super(path) { if (path == null) { final blob = (mimeType == null) ? Blob([bytes]) : Blob([bytes], mimeType); this.path = Url.createObjectUrl(blob); + } else { + this.path = path; } } @override - Future lastModified() async { - if (_lastModified != null) { - return Future.value(_lastModified); - } - return null; - } + Future lastModified() async => Future.value(_lastModified); Future get _bytes async { if (_data != null) { - return Future.value(UnmodifiableUint8ListView(_data)); + return Future.value(UnmodifiableUint8ListView(_data!)); } - return http.readBytes(Uri.parse(path)); + + // We can force 'response' to be a byte buffer by passing responseType: + ByteBuffer? response = + (await HttpRequest.request(path, responseType: 'arraybuffer')).response; + + return response?.asUint8List() ?? Uint8List(0); } @override - Future length() async { - return _length ?? (await _bytes).length; - } + Future length() async => _length ?? (await _bytes).length; @override Future readAsString({Encoding encoding = utf8}) async { @@ -96,12 +98,10 @@ class XFile extends XFileBase { } @override - Future readAsBytes() async { - return Future.value(await _bytes); - } + Future readAsBytes() async => Future.value(await _bytes); @override - Stream openRead([int start, int end]) async* { + Stream openRead([int? start, int? end]) async* { final bytes = await _bytes; yield bytes.sublist(start ?? 0, end ?? bytes.length); } @@ -114,10 +114,9 @@ class XFile extends XFileBase { // Create an tag with the appropriate download attributes and click it // May be overridden with CrossFileTestOverrides - final AnchorElement element = - (_hasTestOverrides && _overrides.createAnchorElement != null) - ? _overrides.createAnchorElement(this.path, this.name) - : createAnchorElement(this.path, this.name); + final AnchorElement element = _hasTestOverrides + ? _overrides!.createAnchorElement(this.path, this.name) as AnchorElement + : createAnchorElement(this.path, this.name); // Clear the children in our container so we can add an element to click _target.children.clear(); @@ -132,5 +131,5 @@ class CrossFileTestOverrides { Element Function(String href, String suggestedName) createAnchorElement; /// Default constructor for overrides - CrossFileTestOverrides({this.createAnchorElement}); + CrossFileTestOverrides({required this.createAnchorElement}); } diff --git a/packages/cross_file/lib/src/types/interface.dart b/packages/cross_file/lib/src/types/interface.dart index e30bc63b4c92..122f3d1d9364 100644 --- a/packages/cross_file/lib/src/types/interface.dart +++ b/packages/cross_file/lib/src/types/interface.dart @@ -21,12 +21,12 @@ class XFile extends XFileBase { /// (like in web) XFile( String path, { - String mimeType, - String name, - int length, - Uint8List bytes, - DateTime lastModified, - @visibleForTesting CrossFileTestOverrides overrides, + String? mimeType, + String? name, + int? length, + Uint8List? bytes, + DateTime? lastModified, + @visibleForTesting CrossFileTestOverrides? overrides, }) : super(path) { throw UnimplementedError( 'CrossFile is not available in your current platform.'); @@ -35,12 +35,12 @@ class XFile extends XFileBase { /// Construct a CrossFile object from its data XFile.fromData( Uint8List bytes, { - String mimeType, - String name, - int length, - DateTime lastModified, - String path, - @visibleForTesting CrossFileTestOverrides overrides, + String? mimeType, + String? name, + int? length, + DateTime? lastModified, + String? path, + @visibleForTesting CrossFileTestOverrides? overrides, }) : super(path) { throw UnimplementedError( 'CrossFile is not available in your current platform.'); @@ -54,5 +54,5 @@ class CrossFileTestOverrides { dynamic Function(String href, String suggestedName) createAnchorElement; /// Default constructor for overrides - CrossFileTestOverrides({this.createAnchorElement}); + CrossFileTestOverrides({required this.createAnchorElement}); } diff --git a/packages/cross_file/lib/src/types/io.dart b/packages/cross_file/lib/src/types/io.dart index d9a93559b507..6eafaf0ce0cc 100644 --- a/packages/cross_file/lib/src/types/io.dart +++ b/packages/cross_file/lib/src/types/io.dart @@ -11,20 +11,20 @@ import './base.dart'; /// A CrossFile backed by a dart:io File. class XFile extends XFileBase { final File _file; - final String mimeType; - final DateTime _lastModified; - int _length; + final String? mimeType; + final DateTime? _lastModified; + int? _length; - final Uint8List _bytes; + final Uint8List? _bytes; /// Construct a CrossFile object backed by a dart:io File. XFile( String path, { this.mimeType, - String name, - int length, - Uint8List bytes, - DateTime lastModified, + String? name, + int? length, + Uint8List? bytes, + DateTime? lastModified, }) : _file = File(path), _bytes = null, _lastModified = lastModified, @@ -34,10 +34,10 @@ class XFile extends XFileBase { XFile.fromData( Uint8List bytes, { this.mimeType, - String path, - String name, - int length, - DateTime lastModified, + String? path, + String? name, + int? length, + DateTime? lastModified, }) : _bytes = bytes, _file = File(path ?? ''), _length = length, @@ -84,7 +84,7 @@ class XFile extends XFileBase { @override Future readAsString({Encoding encoding = utf8}) { if (_bytes != null) { - return Future.value(String.fromCharCodes(_bytes)); + return Future.value(String.fromCharCodes(_bytes!)); } return _file.readAsString(encoding: encoding); } @@ -97,13 +97,13 @@ class XFile extends XFileBase { return _file.readAsBytes(); } - Stream _getBytes(int start, int end) async* { - final bytes = _bytes; + Stream _getBytes(int? start, int? end) async* { + final bytes = _bytes!; yield bytes.sublist(start ?? 0, end ?? bytes.length); } @override - Stream openRead([int start, int end]) { + Stream openRead([int? start, int? end]) { if (_bytes != null) { return _getBytes(start, end); } else { diff --git a/packages/cross_file/lib/src/web_helpers/web_helpers.dart b/packages/cross_file/lib/src/web_helpers/web_helpers.dart index 813f5f975561..a963e9933f99 100644 --- a/packages/cross_file/lib/src/web_helpers/web_helpers.dart +++ b/packages/cross_file/lib/src/web_helpers/web_helpers.dart @@ -31,7 +31,7 @@ Element ensureInitialized(String id) { if (target == null) { final Element targetElement = Element.tag('flt-x-file')..id = id; - querySelector('body').children.add(targetElement); + querySelector('body')!.children.add(targetElement); target = targetElement; } return target; diff --git a/packages/cross_file/pubspec.yaml b/packages/cross_file/pubspec.yaml index 2228674baf40..af1b7e7d4c0f 100644 --- a/packages/cross_file/pubspec.yaml +++ b/packages/cross_file/pubspec.yaml @@ -1,19 +1,18 @@ name: cross_file description: An abstraction to allow working with files across multiple platforms. homepage: https://github.com/flutter/plugins/tree/master/packages/cross_file -version: 0.2.1 +version: 0.3.0-nullsafety dependencies: flutter: sdk: flutter - http: ^0.12.0+1 - meta: ^1.0.5 + meta: ^1.3.0-nullsafety.3 dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0-nullsafety.3 environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.22.0" diff --git a/packages/cross_file/test/x_file_html_test.dart b/packages/cross_file/test/x_file_html_test.dart index fadba96b3c6c..a271aa1f1525 100644 --- a/packages/cross_file/test/x_file_html_test.dart +++ b/packages/cross_file/test/x_file_html_test.dart @@ -11,10 +11,8 @@ import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; import 'package:cross_file/cross_file.dart'; -import 'dart:html'; - final String expectedStringContents = 'Hello, world!'; -final Uint8List bytes = utf8.encode(expectedStringContents); +final Uint8List bytes = Uint8List.fromList(utf8.encode(expectedStringContents)); final html.File textFile = html.File([bytes], 'hello.txt'); final String textFileUrl = html.Url.createObjectUrl(textFile); @@ -66,7 +64,7 @@ void main() { await file.saveTo(''); - final container = querySelector('#${CrossFileDomElementId}'); + final container = html.querySelector('#${CrossFileDomElementId}'); expect(container, isNotNull); }); @@ -76,18 +74,18 @@ void main() { await file.saveTo('path'); - final container = querySelector('#${CrossFileDomElementId}'); - final AnchorElement element = container?.children?.firstWhere( - (element) => element.tagName == 'A', - orElse: () => null); + final container = html.querySelector('#${CrossFileDomElementId}'); + final html.AnchorElement element = + container?.children.firstWhere((element) => element.tagName == 'A') + as html.AnchorElement; - expect(element, isNotNull); + // if element is not found, the `firstWhere` call will throw StateError. expect(element.href, file.path); expect(element.download, file.name); }); test('anchor element is clicked', () async { - final mockAnchor = AnchorElement(); + final mockAnchor = html.AnchorElement(); CrossFileTestOverrides overrides = CrossFileTestOverrides( createAnchorElement: (_, __) => mockAnchor, diff --git a/packages/cross_file/test/x_file_io_test.dart b/packages/cross_file/test/x_file_io_test.dart index d45ff599fec1..94ac81c4cac4 100644 --- a/packages/cross_file/test/x_file_io_test.dart +++ b/packages/cross_file/test/x_file_io_test.dart @@ -15,7 +15,7 @@ final pathPrefix = Directory.current.path.endsWith('test') ? './assets/' : './test/assets/'; final path = pathPrefix + 'hello.txt'; final String expectedStringContents = 'Hello, world!'; -final Uint8List bytes = utf8.encode(expectedStringContents); +final Uint8List bytes = Uint8List.fromList(utf8.encode(expectedStringContents)); final File textFile = File(path); final String textFilePath = textFile.path; diff --git a/script/build_all_plugins_app.sh b/script/build_all_plugins_app.sh index 72390c213da9..3e08b914ff86 100755 --- a/script/build_all_plugins_app.sh +++ b/script/build_all_plugins_app.sh @@ -23,14 +23,15 @@ readonly EXCLUDED_PLUGINS_LIST=( "connectivity_platform_interface" "connectivity_web" "extension_google_sign_in_as_googleapis_auth" + "file_selector" # currently out of sync with camera "flutter_plugin_android_lifecycle" "google_maps_flutter_platform_interface" "google_maps_flutter_web" "google_sign_in_platform_interface" "google_sign_in_web" "image_picker_platform_interface" - "local_auth" # flutter_plugin_android_lifecycle conflict "instrumentation_adapter" + "local_auth" # flutter_plugin_android_lifecycle conflict "path_provider_linux" "path_provider_macos" "path_provider_platform_interface" diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index b2ca25bf6836..44e5df9e95ef 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -8,6 +8,7 @@ readonly NNBD_PLUGINS_LIST=( "android_intent" "battery" "connectivity" + "cross_file" "device_info" "flutter_plugin_android_lifecycle" "flutter_webview" From 8f66b2ded6de6fae80f1141d251d9f6342e38db2 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Thu, 28 Jan 2021 12:22:33 -0800 Subject: [PATCH 0067/1565] [ci] fix ci failure on ios builds (#3470) --- .cirrus.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.cirrus.yml b/.cirrus.yml index 4ec73ea3f24c..1f82270163fb 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -191,6 +191,7 @@ task: # https://github.com/flutter/flutter/issues/42864 - if [[ "$CHANNEL" -eq "stable" ]]; then find . | grep _web$ | xargs rm -rf; fi - flutter channel $CHANNEL + - flutter upgrade - ./script/incremental_build.sh build-examples --ipa - ./script/incremental_build.sh drive-examples - ./script/incremental_build.sh xctest --target RunnerUITests --skip $PLUGINS_TO_SKIP_XCTESTS From cd358b07e7bca7fc56e4add8870f69c86852b83a Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Thu, 28 Jan 2021 17:06:03 -0800 Subject: [PATCH 0068/1565] [package_info] Register IntegrationTestPlugin in the example app. (#3478) This change registers the IntegrationTestPlugin in the example app, so test results are correctly reported back to FTL. The end-to-end firebase tests for package_info haven't passed in a while (nor have been reported as broken before), but after this change, they start passing again. --- packages/package_info/CHANGELOG.md | 4 ++++ .../plugins/packageinfoexample/EmbedderV1Activity.java | 3 +++ packages/package_info/pubspec.yaml | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/package_info/CHANGELOG.md b/packages/package_info/CHANGELOG.md index ebb95c1da17e..f3f7734a4082 100644 --- a/packages/package_info/CHANGELOG.md +++ b/packages/package_info/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.3+4 + +* Ensure `IntegrationTestPlugin` is registered in `example` app, so Firebase Test Lab tests report test results correctly. [Issue](https://github.com/flutter/flutter/issues/74944). + ## 0.4.3+3 * Update Flutter SDK constraint. diff --git a/packages/package_info/example/android/app/src/main/java/io/flutter/plugins/packageinfoexample/EmbedderV1Activity.java b/packages/package_info/example/android/app/src/main/java/io/flutter/plugins/packageinfoexample/EmbedderV1Activity.java index a32c50484838..eb669bf16109 100644 --- a/packages/package_info/example/android/app/src/main/java/io/flutter/plugins/packageinfoexample/EmbedderV1Activity.java +++ b/packages/package_info/example/android/app/src/main/java/io/flutter/plugins/packageinfoexample/EmbedderV1Activity.java @@ -5,6 +5,7 @@ package io.flutter.plugins.packageinfoexample; import android.os.Bundle; +import dev.flutter.plugins.integration_test.IntegrationTestPlugin; import io.flutter.app.FlutterActivity; import io.flutter.plugins.packageinfo.PackageInfoPlugin; @@ -14,5 +15,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); PackageInfoPlugin.registerWith( registrarFor("io.flutter.plugins.packageinfo.PackageInfoPlugin")); + IntegrationTestPlugin.registerWith( + registrarFor("dev.flutter.plugins.integration_test.IntegrationTestPlugin")); } } diff --git a/packages/package_info/pubspec.yaml b/packages/package_info/pubspec.yaml index 884a71659a48..25e45a6be7bc 100644 --- a/packages/package_info/pubspec.yaml +++ b/packages/package_info/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/package_info # 0.4.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.4.3+3 +version: 0.4.3+4 flutter: plugin: From 07dade429d22ca7d8659db2d2fde2fde3acfaae6 Mon Sep 17 00:00:00 2001 From: Jia Hao Date: Fri, 29 Jan 2021 10:34:57 +0800 Subject: [PATCH 0069/1565] [integration_test] Fix tests from changes to `flutter test` machine output (#3480) --- packages/integration_test/CHANGELOG.md | 4 ++++ packages/integration_test/pubspec.yaml | 2 +- packages/integration_test/test/binding_fail_test.dart | 7 ++++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/integration_test/CHANGELOG.md b/packages/integration_test/CHANGELOG.md index 5ae0883ed081..71ab0e86266b 100644 --- a/packages/integration_test/CHANGELOG.md +++ b/packages/integration_test/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.2+2 + +* Fix tests from changes to `flutter test` machine output. + ## 1.0.2+1 * Update vm_service constraint diff --git a/packages/integration_test/pubspec.yaml b/packages/integration_test/pubspec.yaml index a233f066ea37..33c174a9724a 100644 --- a/packages/integration_test/pubspec.yaml +++ b/packages/integration_test/pubspec.yaml @@ -1,6 +1,6 @@ name: integration_test description: Runs tests that use the flutter_test API as integration tests. -version: 1.0.2+1 +version: 1.0.2+2 homepage: https://github.com/flutter/plugins/tree/master/packages/integration_test environment: diff --git a/packages/integration_test/test/binding_fail_test.dart b/packages/integration_test/test/binding_fail_test.dart index bb5961b18fc7..7ec176897c0c 100644 --- a/packages/integration_test/test/binding_fail_test.dart +++ b/packages/integration_test/test/binding_fail_test.dart @@ -61,13 +61,18 @@ Future> _runTest(String scriptPath) async { final String testResults = (await process.stdout .transform(utf8.decoder) .expand((String text) => text.split('\n')) - .map((String line) { + .map((String line) { try { return jsonDecode(line); } on FormatException { // Only interested in test events which are JSON. } }) + .expand>((dynamic json) { + return json is List + ? json.cast() + : >[json as Map]; + }) .where((dynamic testEvent) => testEvent != null && testEvent['type'] == 'print') .map((dynamic printEvent) => printEvent['message'] as String) From 647f69875803314f044730847a2263cd71c714e6 Mon Sep 17 00:00:00 2001 From: Michael Thomsen Date: Fri, 29 Jan 2021 19:17:25 +0100 Subject: [PATCH 0070/1565] [url_launcher] Update description in pubspec.yaml (#2858) --- packages/url_launcher/url_launcher/CHANGELOG.md | 4 ++++ packages/url_launcher/url_launcher/README.md | 2 +- packages/url_launcher/url_launcher/pubspec.yaml | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index fb66bcd99c1f..9f2719fd6662 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.0.0-nullsafety.6 + +* Correct statement in description about which platforms url_launcher supports. + ## 6.0.0-nullsafety.5 * Document that the web plugin is not endorsed in the `nullsafety` prerelease for now. diff --git a/packages/url_launcher/url_launcher/README.md b/packages/url_launcher/url_launcher/README.md index 573624fa18eb..bc399c73df7d 100644 --- a/packages/url_launcher/url_launcher/README.md +++ b/packages/url_launcher/url_launcher/README.md @@ -2,7 +2,7 @@ [![pub package](https://img.shields.io/pub/v/url_launcher.svg)](https://pub.dev/packages/url_launcher) -A Flutter plugin for launching a URL in the mobile platform. Supports +A Flutter plugin for launching a URL. Supports iOS, Android, web, Windows, macOS, and Linux. ## Usage diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index 2f9c38a22f36..2fdfd8caf217 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -1,8 +1,8 @@ name: url_launcher -description: Flutter plugin for launching a URL on Android and iOS. Supports +description: Flutter plugin for launching a URL. Supports web, phone, SMS, and email schemes. homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher -version: 6.0.0-nullsafety.5 +version: 6.0.0-nullsafety.6 flutter: plugin: From 8c9ad1198a1e2b3d03fcd5c5244b4ac105973f21 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Fri, 29 Jan 2021 11:14:06 -0800 Subject: [PATCH 0071/1565] [ci][image_picker][webviews_flutter] enable Xcode 12 (#3461) --- .cirrus.yml | 51 ++++++++++++++----- .../image_picker/image_picker/CHANGELOG.md | 4 ++ .../ImagePickerFromGalleryUITests.m | 20 ++++++-- .../image_picker/image_picker/pubspec.yaml | 2 +- packages/webview_flutter/CHANGELOG.md | 4 ++ .../webview_flutter_test.dart | 6 ++- packages/webview_flutter/pubspec.yaml | 2 +- 7 files changed, 69 insertions(+), 20 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 1f82270163fb..b6a9c4884a22 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -134,11 +134,12 @@ task: - xvfb-run ./script/incremental_build.sh drive-examples --linux task: + # Xcode 12 task # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins only_if: $CIRRUS_TAG == '' use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' osx_instance: - image: catalina-xcode-11.3.1-flutter + image: big-sur-xcode-12.3 upgrade_script: - sudo gem install cocoapods - flutter channel stable @@ -149,7 +150,7 @@ task: activate_script: pub global activate flutter_plugin_tools create_simulator_script: - xcrun simctl list - - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-X com.apple.CoreSimulator.SimRuntime.iOS-13-3 | xargs xcrun simctl boot + - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-11 com.apple.CoreSimulator.SimRuntime.iOS-14-3 | xargs xcrun simctl boot matrix: - name: build_all_plugins_ipa env: @@ -162,17 +163,6 @@ task: - if [[ "$CHANNEL" -eq "stable" ]]; then find . | grep _web$ | xargs rm -rf; fi - flutter channel $CHANNEL - ./script/build_all_plugins_app.sh ios --no-codesign - - name: lint_darwin_plugins - env: - matrix: - PLUGIN_SHARDING: "--shardIndex 0 --shardCount 2" - PLUGIN_SHARDING: "--shardIndex 1 --shardCount 2" - script: - # TODO(jmagman): Lint macOS podspecs but skip any that fail library validation. - - find . -name "*.podspec" | xargs grep -l "osx" | xargs rm - # Skip the dummy podspecs used to placate the tool. - - find . -name "*_web*.podspec" -o -name "*_mac*.podspec" | xargs rm - - ./script/incremental_build.sh podspecs - name: build-ipas+drive-examples env: PATH: $PATH:/usr/local/bin @@ -194,13 +184,46 @@ task: - flutter upgrade - ./script/incremental_build.sh build-examples --ipa - ./script/incremental_build.sh drive-examples - - ./script/incremental_build.sh xctest --target RunnerUITests --skip $PLUGINS_TO_SKIP_XCTESTS + - ./script/incremental_build.sh xctest --target RunnerUITests --skip $PLUGINS_TO_SKIP_XCTESTS --ios-destination "platform=iOS Simulator,name=iPhone 11,OS=14.3" + task: + # Xcode 11 task + # TODO(cyanglaz): merge Xcode 11 task to Xcode 12 task when all the matrix can be run in Xcode 12. # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins only_if: $CIRRUS_TAG == '' use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' osx_instance: image: catalina-xcode-11.3.1-flutter + upgrade_script: + - sudo gem install cocoapods + - flutter channel stable + - flutter upgrade + - flutter channel master + - flutter upgrade + - git fetch origin master + activate_script: pub global activate flutter_plugin_tools + create_simulator_script: + - xcrun simctl list + - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-X com.apple.CoreSimulator.SimRuntime.iOS-13-3 | xargs xcrun simctl boot + matrix: + - name: lint_darwin_plugins + env: + matrix: + PLUGIN_SHARDING: "--shardIndex 0 --shardCount 2" + PLUGIN_SHARDING: "--shardIndex 1 --shardCount 2" + script: + # TODO(jmagman): Lint macOS podspecs but skip any that fail library validation. + - find . -name "*.podspec" | xargs grep -l "osx" | xargs rm + # Skip the dummy podspecs used to placate the tool. + - find . -name "*_web*.podspec" -o -name "*_mac*.podspec" | xargs rm + - ./script/incremental_build.sh podspecs + +task: + # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins + only_if: $CIRRUS_TAG == '' + use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' + osx_instance: + image: big-sur-xcode-12.3 setup_script: - flutter config --enable-macos-desktop upgrade_script: diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md index 1b3146d532fa..1a09758d13ef 100644 --- a/packages/image_picker/image_picker/CHANGELOG.md +++ b/packages/image_picker/image_picker/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.7+22 + +* iOS: update XCUITests to separate each test session. + ## 0.6.7+21 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. diff --git a/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m b/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m index 74df795a3df3..e30fabd2d071 100644 --- a/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m +++ b/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m @@ -16,6 +16,7 @@ @interface ImagePickerFromGalleryUITests : XCTestCase @implementation ImagePickerFromGalleryUITests - (void)setUp { + [super setUp]; // Delete the app if already exists, to test permission popups self.continueAfterFailure = NO; @@ -31,7 +32,7 @@ - (void)setUp { if (![allPhotoPermission waitForExistenceWithTimeout: kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", - self.app.debugDescription); + weakSelf.app.debugDescription); XCTFail(@"Failed due to not able to find " @"allPhotoPermission button with %@ seconds", @(kElementWaitingTime)); @@ -42,7 +43,7 @@ - (void)setUp { if (![ok waitForExistenceWithTimeout: kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", - self.app.debugDescription); + weakSelf.app.debugDescription); XCTFail(@"Failed due to not able to find ok button " @"with %@ seconds", @(kElementWaitingTime)); @@ -53,11 +54,19 @@ - (void)setUp { }]; } +- (void)tearDown { + [super tearDown]; + [self.app terminate]; +} + - (void)testPickingFromGallery { - [self launchPickerAndCancel]; [self launchPickerAndPick]; } +- (void)testCancel { + [self launchPickerAndCancel]; +} + - (void)launchPickerAndCancel { // Find and tap on the pick from gallery button. NSPredicate* predicateToFindImageFromGalleryButton = @@ -160,6 +169,10 @@ - (void)launchPickerAndPick { XCTAssertTrue(pickButton.exists); [pickButton tap]; + // There is a known bug where the permission popups interruption won't get fired until a tap + // happened in the app. We expect a permission popup so we do a tap here. + [self.app tap]; + // Find an image and tap on it. (IOS 14 UI, images are showing directly) XCUIElement* aImage; if (@available(iOS 14, *)) { @@ -177,6 +190,7 @@ - (void)launchPickerAndPick { identifier:@"PhotosGridView"] .cells.firstMatch; } + os_log_error(OS_LOG_DEFAULT, "description before picking image %@", self.app.debugDescription); if (![aImage waitForExistenceWithTimeout:kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTFail(@"Failed due to not able to find an image with %@ seconds", @(kElementWaitingTime)); diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index 789ca13d5bcb..075c90627bf4 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker description: Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker -version: 0.6.7+21 +version: 0.6.7+22 flutter: plugin: diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index 867ea1757985..9c54b4cc207d 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.4 + +* Update integration test to workaround an iOS 14 issue with `evaluateJavascript`. + ## 2.0.0-nullsafety.3 * Fix `onWebResourceError` on iOS. 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 5f39cc3d86d2..50af77fe6c6e 100644 --- a/packages/webview_flutter/example/integration_test/webview_flutter_test.dart +++ b/packages/webview_flutter/example/integration_test/webview_flutter_test.dart @@ -144,7 +144,11 @@ void main() { await pageLoaded.future; expect(messagesReceived, isEmpty); - await controller.evaluateJavascript('Echo.postMessage("hello");'); + // Append a return value "1" in the end will prevent an iOS platform exception. + // See: https://github.com/flutter/flutter/issues/66318#issuecomment-701105380 + // TODO(cyanglaz): remove the workaround "1" in the end when the below issue is fixed. + // https://github.com/flutter/flutter/issues/66318 + await controller.evaluateJavascript('Echo.postMessage("hello");1;'); expect(messagesReceived, equals(['hello'])); }); diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml index 8bdd790e5e36..11769acce2ba 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.3 +version: 2.0.0-nullsafety.4 homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter environment: From 815beaff69c68584ba76393d6c858735ef34d995 Mon Sep 17 00:00:00 2001 From: Mouad Debbar Date: Fri, 29 Jan 2021 11:55:06 -0800 Subject: [PATCH 0072/1565] [url_launcher_web] Fix Link misalignment issue (#3476) The Link widget builds a Stack on the web. The Stack by default loosens the constraints passed by the parent. This is what was causing the misalignment. In order to fix it, we just need to pass fit: StackFit.passthrough to the Stack. --- .../url_launcher_web/CHANGELOG.md | 4 +++ .../url_launcher_web/lib/src/link.dart | 1 + .../url_launcher_web/pubspec.yaml | 2 +- .../url_launcher_web/test/lib/main.dart | 5 ++- .../url_launcher_web_integration.dart | 33 +++++++++++++++++++ .../url_launcher_web_integration_test.dart | 1 + 6 files changed, 44 insertions(+), 2 deletions(-) diff --git a/packages/url_launcher/url_launcher_web/CHANGELOG.md b/packages/url_launcher/url_launcher_web/CHANGELOG.md index c8d52f5df13f..0416c033bf2b 100644 --- a/packages/url_launcher/url_launcher_web/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_web/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.1.5+3 + +- Fix Link misalignment [issue](https://github.com/flutter/flutter/issues/70053). + # 0.1.5+2 - Update Flutter SDK constraint. diff --git a/packages/url_launcher/url_launcher_web/lib/src/link.dart b/packages/url_launcher/url_launcher_web/lib/src/link.dart index e8a6d68348bb..8169a9c11b94 100644 --- a/packages/url_launcher/url_launcher_web/lib/src/link.dart +++ b/packages/url_launcher/url_launcher_web/lib/src/link.dart @@ -66,6 +66,7 @@ class WebLinkDelegateState extends State { @override Widget build(BuildContext context) { return Stack( + fit: StackFit.passthrough, children: [ widget.link.builder( context, diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml index 2d1b8af8e49f..77a958677015 100644 --- a/packages/url_launcher/url_launcher_web/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/pubspec.yaml @@ -4,7 +4,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/u # 0.1.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.1.5+2 +version: 0.1.5+3 flutter: plugin: diff --git a/packages/url_launcher/url_launcher_web/test/lib/main.dart b/packages/url_launcher/url_launcher_web/test/lib/main.dart index 10415204570c..e1a38dcdcd46 100644 --- a/packages/url_launcher/url_launcher_web/test/lib/main.dart +++ b/packages/url_launcher/url_launcher_web/test/lib/main.dart @@ -17,6 +17,9 @@ class MyApp extends StatefulWidget { class _MyAppState extends State { @override Widget build(BuildContext context) { - return Text('Testing... Look at the console output for results!'); + return Directionality( + textDirection: TextDirection.ltr, + child: Text('Testing... Look at the console output for results!'), + ); } } diff --git a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart b/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart index 4d103443deb9..bfa94821e41a 100644 --- a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart +++ b/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart @@ -2,6 +2,7 @@ // 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; import 'dart:js_util'; import 'package:flutter/widgets.dart'; @@ -271,6 +272,38 @@ void main() { expect(anchor.getAttribute('href'), uri2.toString()); expect(anchor.getAttribute('target'), '_self'); }); + + testWidgets('sizes itself correctly', (WidgetTester tester) async { + final Key containerKey = GlobalKey(); + final Uri uri = Uri.parse('http://foobar'); + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: ConstrainedBox( + constraints: BoxConstraints.tight(Size(100.0, 100.0)), + child: WebLinkDelegate(TestLinkInfo( + uri: uri, + target: LinkTarget.blank, + builder: (BuildContext context, FollowLink followLink) { + return Container( + key: containerKey, + child: SizedBox(width: 50.0, height: 50.0), + ); + }, + )), + ), + ), + )); + await tester.pumpAndSettle(); + + final Size containerSize = tester.getSize(find.byKey(containerKey)); + // The Stack widget inserted by the `WebLinkDelegate` shouldn't loosen the + // constraints before passing them to the inner container. So the inner + // container should respect the tight constraints given by the ancestor + // `ConstrainedBox` widget. + expect(containerSize.width, 100.0); + expect(containerSize.height, 100.0); + }); }); } diff --git a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration_test.dart b/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration_test.dart index 64e2248a4f9b..2d68bb93e9a7 100644 --- a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration_test.dart +++ b/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration_test.dart @@ -2,6 +2,7 @@ // 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:integration_test/integration_test_driver.dart'; Future main() async => integrationDriver(); From 97646369b0a88e70624c4dc22fc1931e35060f94 Mon Sep 17 00:00:00 2001 From: Amir Hardon Date: Fri, 29 Jan 2021 15:09:34 -0800 Subject: [PATCH 0073/1565] Remove amirh from CODEOWNERS (#3484) --- CODEOWNERS | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 5f6d83c209ac..656bd2604c75 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -6,7 +6,7 @@ packages/android_alarm_manager/** @bkonyi packages/android_intent/** @mklim @matthew-carroll -packages/battery/** @amirh @matthew-carroll +packages/battery/** @matthew-carroll packages/camera/** @bparrishMines packages/connectivity/** @cyanglaz @matthew-carroll packages/cross_file/** @ditman @mvanbeusekom @@ -24,4 +24,3 @@ packages/path_provider/** @matthew-carroll packages/shared_preferences/** @matthew-carroll packages/url_launcher/** @mklim packages/video_player/** @iskakaushik @cyanglaz -packages/webview_flutter/** @amirh From 35847e4734d4bd22f8b08394897ffa5997972ba2 Mon Sep 17 00:00:00 2001 From: Jia Hao Date: Sat, 30 Jan 2021 08:33:00 +0800 Subject: [PATCH 0074/1565] [local_auth] Fix incorrect switch fallthrough (#3473) --- packages/local_auth/CHANGELOG.md | 14 +++++++++----- .../plugins/localauth/AuthenticationHelper.java | 1 + packages/local_auth/pubspec.yaml | 4 ++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/local_auth/CHANGELOG.md b/packages/local_auth/CHANGELOG.md index 8bb043f52d8f..152ffb603e10 100644 --- a/packages/local_auth/CHANGELOG.md +++ b/packages/local_auth/CHANGELOG.md @@ -2,10 +2,14 @@ * Allow pin, passcode, and pattern authentication with `authenticate` method * **Breaking change**. Parameter names refactored to use the generic `biometric` prefix in place of `fingerprint` in the `AndroidAuthMessages` class - * `fingerprintHint` is now `biometricHint` - * `fingerprintNotRecognized`is now `biometricNotRecognized` - * `fingerprintSuccess`is now `biometricSuccess` - * `fingerprintRequiredTitle` is now `biometricRequiredTitle` + * `fingerprintHint` is now `biometricHint` + * `fingerprintNotRecognized`is now `biometricNotRecognized` + * `fingerprintSuccess`is now `biometricSuccess` + * `fingerprintRequiredTitle` is now `biometricRequiredTitle` + +## 1.0.0-nullsafety.4 + +* Fix incorrect error handling switch case fallthrough. ## 1.0.0-nullsafety.3 @@ -203,4 +207,4 @@ ## 0.0.1 -* Initial release of local authentication plugin. \ No newline at end of file +* Initial release of local authentication plugin. diff --git a/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java b/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java index 096c7efd6d3d..3a7e2d76ca08 100644 --- a/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java +++ b/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java @@ -138,6 +138,7 @@ public void onAuthenticationError(int errorCode, CharSequence errString) { return; } completionHandler.onError("NotAvailable", "Security credentials not available."); + break; case BiometricPrompt.ERROR_NO_SPACE: case BiometricPrompt.ERROR_NO_BIOMETRICS: if (promptInfo.isDeviceCredentialAllowed()) return; diff --git a/packages/local_auth/pubspec.yaml b/packages/local_auth/pubspec.yaml index 0f5a58835c3c..79870cc57da2 100644 --- a/packages/local_auth/pubspec.yaml +++ b/packages/local_auth/pubspec.yaml @@ -1,8 +1,8 @@ name: local_auth -description: Flutter plugin for Android and iOS devices to allow local +description: Flutter plugin for Android and iOS devices to allow local authentication via fingerprint, touch ID, face ID, passcode, pin, or pattern. homepage: https://github.com/flutter/plugins/tree/master/packages/local_auth -version: 1.0.0-nullsafety.3 +version: 1.0.0-nullsafety.4 flutter: plugin: From 04b0b4b13f59bea7b3375dbe2c5a013e6f0ed5a4 Mon Sep 17 00:00:00 2001 From: Tim Sneath Date: Sat, 30 Jan 2021 12:11:08 -0800 Subject: [PATCH 0075/1565] [path_provider_windows] Resolve FFI stabilization changes (#3485) Ensures that path_provider_windows works on current null safety builds. --- packages/path_provider/path_provider_windows/CHANGELOG.md | 4 ++++ .../lib/src/path_provider_windows_real.dart | 2 +- packages/path_provider/path_provider_windows/pubspec.yaml | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/path_provider/path_provider_windows/CHANGELOG.md b/packages/path_provider/path_provider_windows/CHANGELOG.md index ea271681e63c..24304e36dc0c 100644 --- a/packages/path_provider/path_provider_windows/CHANGELOG.md +++ b/packages/path_provider/path_provider_windows/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.0-nullsafety.1 + +* Bump win32 dependency to latest version. + ## 0.1.0-nullsafety * Migrate to null safety diff --git a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart index 856249036b62..c104343f2502 100644 --- a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart +++ b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart @@ -116,7 +116,7 @@ class PathProviderWindows extends PathProviderPlatform { /// [WindowsKnownFolder]. Future getPath(String folderID) { final pathPtrPtr = allocate>(); - final Pointer knownFolderID = calloc()..setGUID(folderID); + final Pointer knownFolderID = calloc()..ref.setGUID(folderID); try { final hr = SHGetKnownFolderPath( diff --git a/packages/path_provider/path_provider_windows/pubspec.yaml b/packages/path_provider/path_provider_windows/pubspec.yaml index 55c73c87ad19..578000682e63 100644 --- a/packages/path_provider/path_provider_windows/pubspec.yaml +++ b/packages/path_provider/path_provider_windows/pubspec.yaml @@ -1,7 +1,7 @@ name: path_provider_windows description: Windows implementation of the path_provider plugin homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_windows -version: 0.1.0-nullsafety +version: 0.1.0-nullsafety.1 flutter: plugin: @@ -17,7 +17,7 @@ dependencies: flutter: sdk: flutter ffi: ^0.2.0-nullsafety.1 - win32: ^2.0.0-nullsafety.8 + win32: ^2.0.0-nullsafety.9 dev_dependencies: flutter_test: From a16411b50970d988ae6510f399114520149053dc Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Mon, 1 Feb 2021 14:22:59 -0800 Subject: [PATCH 0076/1565] Remove Dart stubs from macOS plugins (#3491) When these federated plugins were created, plugins had to have at least one Dart file to avoid issues with the analyzer, so were created with a stub file since all the code is native. The analyzer no longer has this limitation, so the stub is no longer necesssary. --- packages/connectivity/connectivity_macos/CHANGELOG.md | 4 ++++ .../connectivity_macos/lib/connectivity_macos.dart | 3 --- packages/connectivity/connectivity_macos/pubspec.yaml | 2 +- packages/path_provider/path_provider_macos/CHANGELOG.md | 4 ++++ .../path_provider_macos/lib/path_provider_macos.dart | 3 --- packages/path_provider/path_provider_macos/pubspec.yaml | 2 +- 6 files changed, 10 insertions(+), 8 deletions(-) delete mode 100644 packages/connectivity/connectivity_macos/lib/connectivity_macos.dart delete mode 100644 packages/path_provider/path_provider_macos/lib/path_provider_macos.dart diff --git a/packages/connectivity/connectivity_macos/CHANGELOG.md b/packages/connectivity/connectivity_macos/CHANGELOG.md index 9261b0e789fe..890c8938482f 100644 --- a/packages/connectivity/connectivity_macos/CHANGELOG.md +++ b/packages/connectivity/connectivity_macos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.0-nullsafety.1 + +* Remove placeholder Dart file. + ## 0.2.0-nullsafety * Update Dart SDK constraint. diff --git a/packages/connectivity/connectivity_macos/lib/connectivity_macos.dart b/packages/connectivity/connectivity_macos/lib/connectivity_macos.dart deleted file mode 100644 index 7be7b143ca79..000000000000 --- a/packages/connectivity/connectivity_macos/lib/connectivity_macos.dart +++ /dev/null @@ -1,3 +0,0 @@ -// Analyze will fail if there is no main.dart file. This file should -// be removed once an example app has been added to connectivity_macos. -// https://github.com/flutter/flutter/issues/51007 diff --git a/packages/connectivity/connectivity_macos/pubspec.yaml b/packages/connectivity/connectivity_macos/pubspec.yaml index dd193f715c2a..49c28f081ad7 100644 --- a/packages/connectivity/connectivity_macos/pubspec.yaml +++ b/packages/connectivity/connectivity_macos/pubspec.yaml @@ -3,7 +3,7 @@ description: macOS implementation of the connectivity plugin. # 0.1.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.2.0-nullsafety +version: 0.2.0-nullsafety.1 homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_macos flutter: diff --git a/packages/path_provider/path_provider_macos/CHANGELOG.md b/packages/path_provider/path_provider_macos/CHANGELOG.md index b082aefd9da6..1380d76a8f3c 100644 --- a/packages/path_provider/path_provider_macos/CHANGELOG.md +++ b/packages/path_provider/path_provider_macos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.4+9 + +* Remove placeholder Dart file. + ## 0.0.4+8 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. diff --git a/packages/path_provider/path_provider_macos/lib/path_provider_macos.dart b/packages/path_provider/path_provider_macos/lib/path_provider_macos.dart deleted file mode 100644 index cf440b2858af..000000000000 --- a/packages/path_provider/path_provider_macos/lib/path_provider_macos.dart +++ /dev/null @@ -1,3 +0,0 @@ -// Analyze will fail if there is no main.dart file. This file should -// be removed once an example app has been added to path_provider_macos. -// https://github.com/flutter/flutter/issues/51007 diff --git a/packages/path_provider/path_provider_macos/pubspec.yaml b/packages/path_provider/path_provider_macos/pubspec.yaml index 0af1cfbf0aaa..9d3a3896903e 100644 --- a/packages/path_provider/path_provider_macos/pubspec.yaml +++ b/packages/path_provider/path_provider_macos/pubspec.yaml @@ -3,7 +3,7 @@ description: macOS implementation of the path_provider plugin # 0.0.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.0.4+8 +version: 0.0.4+9 homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_macos flutter: From 31a8b5c3d5be8bf8db0def800496a6c7076bb59c Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Mon, 1 Feb 2021 16:04:43 -0800 Subject: [PATCH 0077/1565] Migrate shared_preferences_platform_interfaces to null safety (#3466) --- .../CHANGELOG.md | 4 ++ .../method_channel_shared_preferences.dart | 43 ++++++++----------- ...shared_preferences_platform_interface.dart | 2 +- .../pubspec.yaml | 7 ++- ...ethod_channel_shared_preferences_test.dart | 14 +++--- script/nnbd_plugins.sh | 2 +- 6 files changed, 33 insertions(+), 39 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md b/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md index 88d3a9ac5f00..6661e2757326 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Migrate to null safety. + ## 1.0.5 * Update Flutter SDK constraint. diff --git a/packages/shared_preferences/shared_preferences_platform_interface/lib/method_channel_shared_preferences.dart b/packages/shared_preferences/shared_preferences_platform_interface/lib/method_channel_shared_preferences.dart index 66009a5caf14..c02c537adcbd 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/lib/method_channel_shared_preferences.dart +++ b/packages/shared_preferences/shared_preferences_platform_interface/lib/method_channel_shared_preferences.dart @@ -18,39 +18,32 @@ const MethodChannel _kChannel = class MethodChannelSharedPreferencesStore extends SharedPreferencesStorePlatform { @override - Future remove(String key) { - return _invokeBoolMethod('remove', { - 'key': key, - }); + Future remove(String key) async { + return (await _kChannel.invokeMethod( + 'remove', + {'key': key}, + ))!; } @override - Future setValue(String valueType, String key, Object value) { - return _invokeBoolMethod('set$valueType', { - 'key': key, - 'value': value, - }); - } - - Future _invokeBoolMethod(String method, Map params) { - return _kChannel - .invokeMethod(method, params) - // TODO(yjbanov): I copied this from the original - // shared_preferences.dart implementation, but I - // actually do not know why it's necessary to pipe the - // result through an identity function. - // - // Source: https://github.com/flutter/plugins/blob/3a87296a40a2624d200917d58f036baa9fb18df8/packages/shared_preferences/lib/shared_preferences.dart#L134 - .then((dynamic result) => result); + Future setValue(String valueType, String key, Object value) async { + return (await _kChannel.invokeMethod( + 'set$valueType', + {'key': key, 'value': value}, + ))!; } @override - Future clear() { - return _kChannel.invokeMethod('clear'); + Future clear() async { + return (await _kChannel.invokeMethod('clear'))!; } @override - Future> getAll() { - return _kChannel.invokeMapMethod('getAll'); + Future> getAll() async { + final Map? preferences = + await _kChannel.invokeMapMethod('getAll'); + + if (preferences == null) return {}; + return preferences; } } diff --git a/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_platform_interface.dart b/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_platform_interface.dart index 5a2b99ca69b1..cf194f82c267 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_platform_interface.dart +++ b/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_platform_interface.dart @@ -4,7 +4,7 @@ import 'dart:async'; -import 'package:meta/meta.dart'; +import 'package:flutter/foundation.dart'; import 'method_channel_shared_preferences.dart'; diff --git a/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml b/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml index da31497df1c6..9e5d57230761 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml @@ -1,18 +1,17 @@ name: shared_preferences_platform_interface description: A common platform interface for the shared_preferences plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_platform_interface -version: 1.0.5 +version: 2.0.0-nullsafety dependencies: - meta: ^1.0.4 flutter: sdk: flutter dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0-nullsafety environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.12.8" diff --git a/packages/shared_preferences/shared_preferences_platform_interface/test/method_channel_shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_platform_interface/test/method_channel_shared_preferences_test.dart index 4cc79b058675..d828126168ba 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/test/method_channel_shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_platform_interface/test/method_channel_shared_preferences_test.dart @@ -15,7 +15,7 @@ void main() { 'plugins.flutter.io/shared_preferences', ); - const Map kTestValues = { + const Map kTestValues = { 'flutter.String': 'hello world', 'flutter.Bool': true, 'flutter.Int': 42, @@ -23,10 +23,10 @@ void main() { 'flutter.StringList': ['foo', 'bar'], }; - InMemorySharedPreferencesStore testData; + late InMemorySharedPreferencesStore testData; final List log = []; - MethodChannelSharedPreferencesStore store; + late MethodChannelSharedPreferencesStore store; setUp(() async { testData = InMemorySharedPreferencesStore.empty(); @@ -44,9 +44,9 @@ void main() { return await testData.clear(); } final RegExp setterRegExp = RegExp(r'set(.*)'); - final Match match = setterRegExp.matchAsPrefix(methodCall.method); - if (match.groupCount == 1) { - final String valueType = match.group(1); + final Match? match = setterRegExp.matchAsPrefix(methodCall.method); + if (match?.groupCount == 1) { + final String valueType = match!.group(1)!; final String key = methodCall.arguments['key']; final Object value = methodCall.arguments['value']; return await testData.setValue(valueType, key, value); @@ -59,8 +59,6 @@ void main() { tearDown(() async { await testData.clear(); - store = null; - testData = null; }); test('getAll', () async { diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index 44e5df9e95ef..3d0676f8b1a5 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -17,6 +17,7 @@ readonly NNBD_PLUGINS_LIST=( "path_provider" "plugin_platform_interface" "share" + "shared_preferences" "url_launcher" "video_player" "webview_flutter" @@ -35,7 +36,6 @@ readonly NON_NNBD_PLUGINS_LIST=( # "in_app_purchase" # "quick_actions" # "sensors" - # "shared_preferences" # "wifi_info_flutter" ) From 30721bed3afe4712b32abad1f2bf3f2ff6c18608 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Mon, 1 Feb 2021 18:12:19 -0800 Subject: [PATCH 0078/1565] Automatically add platform labels (#3487) Tags PRs with platform-* labels based on the platform(s) being edited. This will allow filtering open PRs by OS (e.g., to allow someone focusing on a single platform's plugin implementations to easily find all relevant PRs). --- .github/labeler.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/labeler.yml b/.github/labeler.yml index 66dc68f1fbbe..cdb9ade0e7f8 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -84,3 +84,27 @@ 'p: wifi_info_flutter': - packages/wifi_info_flutter/**/* + +'platform-android': + - packages/*/*_android/**/* + - packages/**/android/**/* + +'platform-ios': + - packages/*/*_ios/**/* + - packages/**/ios/**/* + +'platform-linux': + - packages/*/*_linux/**/* + - packages/**/linux/**/* + +'platform-macos': + - packages/*/*_macos/**/* + - packages/**/macos/**/* + +'platform-web': + - packages/*/*_web/**/* + - packages/**/web/**/* + +'platform-windows': + - packages/*/*_windows/**/* + - packages/**/windows/**/* From a87497f1399cf6b074dc98563168569d8f738348 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Mon, 1 Feb 2021 19:46:03 -0800 Subject: [PATCH 0079/1565] Add plugin issue query to README (#3493) --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 42c64e1c6a50..b65c10e7f381 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,9 @@ These plugins are also available on Please file any issues, bugs, or feature requests in the [main flutter repo](https://github.com/flutter/flutter/issues/new). +Issues pertaining to this repository are [labeled +"plugin"](https://github.com/flutter/flutter/issues?q=is%3Aopen+is%3Aissue+label%3Aplugin). + ## Contributing If you wish to contribute a new plugin to the Flutter ecosystem, please From a45557608af1c6aada64705884101cada1d6c6d2 Mon Sep 17 00:00:00 2001 From: Alex Li Date: Tue, 2 Feb 2021 16:48:11 +0800 Subject: [PATCH 0080/1565] [camera] Fix example reference in camera's doc (#3472) --- AUTHORS | 3 ++- packages/camera/camera/CHANGELOG.md | 4 ++++ packages/camera/camera/README.md | 2 +- packages/camera/camera/pubspec.yaml | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/AUTHORS b/AUTHORS index dabc20108f28..1f2b9cba2f16 100644 --- a/AUTHORS +++ b/AUTHORS @@ -60,4 +60,5 @@ Eitan Schwartz Chris Rutkowski Juan Alvarez Aleksandr Yurkovskiy -Anton Borries \ No newline at end of file +Anton Borries +Alex Li diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index cc734737182f..35a4d950e510 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.0+2 + +* Fix example reference in README. + ## 0.7.0+1 * Ensure communication from JAVA to Dart is done on the main UI thread. diff --git a/packages/camera/camera/README.md b/packages/camera/camera/README.md index f7163818aae3..b9fdd7384297 100644 --- a/packages/camera/camera/README.md +++ b/packages/camera/camera/README.md @@ -122,7 +122,7 @@ class _CameraAppState extends State { } ``` -For a more elaborate usage example see [here](https://github.com/flutter/plugins/tree/master/packages/camera/example). +For a more elaborate usage example see [here](https://github.com/flutter/plugins/tree/master/packages/camera/camera/example). *Note*: This plugin is still under development, and some APIs might not be available yet. [Feedback welcome](https://github.com/flutter/flutter/issues) and diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index b406ce5ba64f..2b6d163dfbeb 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.7.0+1 +version: 0.7.0+2 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From 59086bd4d5f37a4ae9cc94f243d736dbc3b26e97 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Tue, 2 Feb 2021 12:51:04 +0100 Subject: [PATCH 0081/1565] Revert compileSdkVersion to 29 (#3496) --- packages/camera/camera/CHANGELOG.md | 4 ++++ packages/camera/camera/android/build.gradle | 2 +- .../flutter/plugins/camera/DeviceOrientationManager.java | 9 +-------- packages/camera/camera/example/android/app/build.gradle | 2 +- packages/camera/camera/pubspec.yaml | 2 +- 5 files changed, 8 insertions(+), 11 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 35a4d950e510..911d7a1e9920 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.7.0+3 + +* Revert compileSdkVersion back to 29 (from 30) as this is causing problems with add-to-app configurations. + ## 0.7.0+2 * Fix example reference in README. diff --git a/packages/camera/camera/android/build.gradle b/packages/camera/camera/android/build.gradle index 0606738a0a69..0b88fd10fb71 100644 --- a/packages/camera/camera/android/build.gradle +++ b/packages/camera/camera/android/build.gradle @@ -27,7 +27,7 @@ project.getTasks().withType(JavaCompile){ apply plugin: 'com.android.library' android { - compileSdkVersion 30 + compileSdkVersion 29 defaultConfig { minSdkVersion 21 diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java index d39a8da55cc8..7c6011b185fb 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java @@ -11,8 +11,6 @@ import android.content.IntentFilter; import android.content.res.Configuration; import android.hardware.SensorManager; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; import android.provider.Settings; import android.view.Display; import android.view.OrientationEventListener; @@ -191,11 +189,6 @@ private int getDeviceDefaultOrientation() { @SuppressWarnings("deprecation") private Display getDisplay() { - if (VERSION.SDK_INT >= VERSION_CODES.R) { - return activity.getDisplay(); - } else { - return ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)) - .getDefaultDisplay(); - } + return ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); } } diff --git a/packages/camera/camera/example/android/app/build.gradle b/packages/camera/camera/example/android/app/build.gradle index c5eeb246fe30..7d0e281b74e8 100644 --- a/packages/camera/camera/example/android/app/build.gradle +++ b/packages/camera/camera/example/android/app/build.gradle @@ -25,7 +25,7 @@ apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 30 + compileSdkVersion 29 lintOptions { disable 'InvalidPackage' diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 2b6d163dfbeb..cebbb334c8f2 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.7.0+2 +version: 0.7.0+3 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From a65d350c3f97fd6b5e4120c2d782f971103987a5 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 2 Feb 2021 10:21:05 -0800 Subject: [PATCH 0082/1565] Remove cyanglaz from some package code owners (#3495) --- CODEOWNERS | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 656bd2604c75..bd774ebe4315 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -8,19 +8,19 @@ packages/android_alarm_manager/** @bkonyi packages/android_intent/** @mklim @matthew-carroll packages/battery/** @matthew-carroll packages/camera/** @bparrishMines -packages/connectivity/** @cyanglaz @matthew-carroll +packages/connectivity/** @matthew-carroll packages/cross_file/** @ditman @mvanbeusekom packages/device_info/** @matthew-carroll packages/espresso/** @collinjackson @adazh packages/file_selector/** @ditman packages/google_maps_flutter/** @cyanglaz -packages/google_sign_in/** @cyanglaz @mehmetf +packages/google_sign_in/** @mehmetf packages/image_picker/** @cyanglaz packages/integration_test/** @dnfield packages/in_app_purchase/** @mklim @cyanglaz @LHLL packages/ios_platform_images/** @gaaclarke -packages/package_info/** @cyanglaz @matthew-carroll +packages/package_info/** @matthew-carroll packages/path_provider/** @matthew-carroll packages/shared_preferences/** @matthew-carroll packages/url_launcher/** @mklim -packages/video_player/** @iskakaushik @cyanglaz +packages/video_player/** @iskakaushik From 42d5325a93ffc80179ab770febcdd79243c3ff87 Mon Sep 17 00:00:00 2001 From: Emmanuel Garcia Date: Tue, 2 Feb 2021 16:35:32 -0800 Subject: [PATCH 0083/1565] Run pub global activate before pub global run (#3502) --- .cirrus.yml | 5 ----- script/build_all_plugins_app.sh | 2 +- script/check_publish.sh | 2 +- script/common.sh | 16 ++++++++++++++++ script/incremental_build.sh | 12 +++--------- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index b6a9c4884a22..a4815ec2489e 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -14,7 +14,6 @@ task: - flutter channel master - flutter upgrade - git fetch origin master - activate_script: pub global activate flutter_plugin_tools matrix: - name: publishable script: @@ -122,7 +121,6 @@ task: - flutter channel master - flutter upgrade - git fetch origin master - activate_script: pub global activate flutter_plugin_tools matrix: - name: build-linux+drive-examples install_script: @@ -147,7 +145,6 @@ task: - flutter channel master - flutter upgrade - git fetch origin master - activate_script: pub global activate flutter_plugin_tools create_simulator_script: - xcrun simctl list - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-11 com.apple.CoreSimulator.SimRuntime.iOS-14-3 | xargs xcrun simctl boot @@ -201,7 +198,6 @@ task: - flutter channel master - flutter upgrade - git fetch origin master - activate_script: pub global activate flutter_plugin_tools create_simulator_script: - xcrun simctl list - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-X com.apple.CoreSimulator.SimRuntime.iOS-13-3 | xargs xcrun simctl boot @@ -231,7 +227,6 @@ task: - flutter channel master - flutter upgrade - git fetch origin master - activate_script: pub global activate flutter_plugin_tools matrix: - name: build_all_plugins_app script: diff --git a/script/build_all_plugins_app.sh b/script/build_all_plugins_app.sh index 3e08b914ff86..9d9e38550ed5 100755 --- a/script/build_all_plugins_app.sh +++ b/script/build_all_plugins_app.sh @@ -64,7 +64,7 @@ fi echo "Excluding the following plugins: $ALL_EXCLUDED" -(cd "$REPO_DIR" && pub global run flutter_plugin_tools all-plugins-app --exclude $ALL_EXCLUDED) +(cd "$REPO_DIR" && plugin_tools all-plugins-app --exclude $ALL_EXCLUDED) function error() { echo "$@" 1>&2 diff --git a/script/check_publish.sh b/script/check_publish.sh index 2e53fc80cb47..5584fc601916 100755 --- a/script/check_publish.sh +++ b/script/check_publish.sh @@ -12,7 +12,7 @@ source "$SCRIPT_DIR/common.sh" function check_publish() { local failures=() - for dir in $(pub global run flutter_plugin_tools list --plugins="$1"); do + for dir in $(plugin_tools list --plugins="$1"); do local package_name=$(basename "$dir") echo "Checking that $package_name can be published." diff --git a/script/common.sh b/script/common.sh index 7950a3ea71cd..cd2c1ca3fd83 100644 --- a/script/common.sh +++ b/script/common.sh @@ -45,3 +45,19 @@ function check_changed_packages() { fi return 0 } + +# Normalizes the call to the pub command. +function pub_command() { + if [ "$(expr substr $(uname -s) 1 5)" == "MINGW" ]; then + pub.bat "$@" + else + pub "$@" + fi +} + +# Activates the Flutter plugin tool to ensures that the plugin tools dependencies +# are resolved using the current Dart SDK. +# Finally, runs the tool with the parameters. +function plugin_tools() { + pub_command global activate flutter_plugin_tools && pub_command global run flutter_plugin_tools "$@" +} diff --git a/script/incremental_build.sh b/script/incremental_build.sh index 3911f0a6e9c8..d98e7aac6e30 100755 --- a/script/incremental_build.sh +++ b/script/incremental_build.sh @@ -7,12 +7,6 @@ readonly REPO_DIR="$(dirname "$SCRIPT_DIR")" source "$SCRIPT_DIR/common.sh" source "$SCRIPT_DIR/nnbd_plugins.sh" -if [ "$(expr substr $(uname -s) 1 5)" == "MINGW" ]; then - PUB=pub.bat -else - PUB=pub -fi - # Plugins that are excluded from this task. ALL_EXCLUDED=("") # Exclude nnbd plugins from stable. @@ -49,7 +43,7 @@ PLUGIN_SHARDING=($PLUGIN_SHARDING) if [[ "${BRANCH_NAME}" == "master" ]]; then echo "Running for all packages" - (cd "$REPO_DIR" && $PUB global run flutter_plugin_tools "${ACTIONS[@]}" --exclude="$ALL_EXCLUDED" ${PLUGIN_SHARDING[@]}) + (cd "$REPO_DIR" && plugin_tools "${ACTIONS[@]}" --exclude="$ALL_EXCLUDED" ${PLUGIN_SHARDING[@]}) else # Sets CHANGED_PACKAGES check_changed_packages @@ -57,10 +51,10 @@ else if [[ "$CHANGED_PACKAGES" == "" ]]; then echo "No changes detected in packages." echo "Running for all packages" - (cd "$REPO_DIR" && $PUB global run flutter_plugin_tools "${ACTIONS[@]}" --exclude="$ALL_EXCLUDED" ${PLUGIN_SHARDING[@]}) + (cd "$REPO_DIR" && plugin_tools "${ACTIONS[@]}" --exclude="$ALL_EXCLUDED" ${PLUGIN_SHARDING[@]}) else echo running "${ACTIONS[@]}" - (cd "$REPO_DIR" && $PUB global run flutter_plugin_tools "${ACTIONS[@]}" --plugins="$CHANGED_PACKAGES" --exclude="$ALL_EXCLUDED" ${PLUGIN_SHARDING[@]}) + (cd "$REPO_DIR" && plugin_tools "${ACTIONS[@]}" --plugins="$CHANGED_PACKAGES" --exclude="$ALL_EXCLUDED" ${PLUGIN_SHARDING[@]}) echo "Running version check for changed packages" # TODO(egarciad): Enable this check once in master. # (cd "$REPO_DIR" && $PUB global run flutter_plugin_tools version-check --base_sha="$(get_branch_base_sha)") From 9e1d573e1e953ddc2e4c7c823f442244f1ff4ebf Mon Sep 17 00:00:00 2001 From: Emmanuel Garcia Date: Wed, 3 Feb 2021 12:50:36 -0800 Subject: [PATCH 0084/1565] Run activate before run (#3506) --- script/check_publish.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/script/check_publish.sh b/script/check_publish.sh index 5584fc601916..9f435e9ba42c 100755 --- a/script/check_publish.sh +++ b/script/check_publish.sh @@ -12,7 +12,8 @@ source "$SCRIPT_DIR/common.sh" function check_publish() { local failures=() - for dir in $(plugin_tools list --plugins="$1"); do + pub_command global activate flutter_plugin_tools + for dir in $(pub_command global run flutter_plugin_tools list --plugins="$1"); do local package_name=$(basename "$dir") echo "Checking that $package_name can be published." From 782b05782831d8865c100dab60ca7f85d7e46fab Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Wed, 3 Feb 2021 13:32:12 -0800 Subject: [PATCH 0085/1565] [path_provider] Update macOS for NNBD (#3498) macOS federated plugin implementations that contain no Dart code just need their Dart SDK bumped in order to be considered nullsafe. --- packages/path_provider/path_provider_macos/CHANGELOG.md | 4 ++++ packages/path_provider/path_provider_macos/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/path_provider/path_provider_macos/CHANGELOG.md b/packages/path_provider/path_provider_macos/CHANGELOG.md index 1380d76a8f3c..2f7290c2ced1 100644 --- a/packages/path_provider/path_provider_macos/CHANGELOG.md +++ b/packages/path_provider/path_provider_macos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.5-nullsafety + +* Update Dart SDK constraint for null safety. + ## 0.0.4+9 * Remove placeholder Dart file. diff --git a/packages/path_provider/path_provider_macos/pubspec.yaml b/packages/path_provider/path_provider_macos/pubspec.yaml index 9d3a3896903e..a2bbd58b7289 100644 --- a/packages/path_provider/path_provider_macos/pubspec.yaml +++ b/packages/path_provider/path_provider_macos/pubspec.yaml @@ -3,7 +3,7 @@ description: macOS implementation of the path_provider plugin # 0.0.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.0.4+9 +version: 0.0.5-nullsafety homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_macos flutter: @@ -13,7 +13,7 @@ flutter: pluginClass: PathProviderPlugin environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.10.0" dependencies: From 61118a7fab0372661575b399c0cba83a51a4dfc5 Mon Sep 17 00:00:00 2001 From: Yash Johri Date: Thu, 4 Feb 2021 03:30:57 +0530 Subject: [PATCH 0086/1565] [path_provider_linux] Migrate to null safety (#3330) --- .../path_provider_linux/CHANGELOG.md | 4 ++++ .../integration_test/path_provider_test.dart | 21 ++++++++++++------- .../path_provider_linux/example/lib/main.dart | 11 +++++----- .../path_provider_linux/example/pubspec.yaml | 2 +- .../lib/path_provider_linux.dart | 12 +++++------ .../path_provider_linux/pubspec.yaml | 12 +++++------ 6 files changed, 36 insertions(+), 26 deletions(-) diff --git a/packages/path_provider/path_provider_linux/CHANGELOG.md b/packages/path_provider/path_provider_linux/CHANGELOG.md index ee382b04710b..2deb84237712 100644 --- a/packages/path_provider/path_provider_linux/CHANGELOG.md +++ b/packages/path_provider/path_provider_linux/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.0-nullsafety + +* Migrate to null safety. + ## 0.1.1+3 * Update Flutter SDK constraint. diff --git a/packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart b/packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart index 18ac49debbd4..febd52172759 100644 --- a/packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart @@ -4,14 +4,15 @@ import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; -import 'package:path_provider/path_provider.dart'; +import 'package:path_provider_linux/path_provider_linux.dart'; import 'package:integration_test/integration_test.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('getTemporaryDirectory', (WidgetTester tester) async { - final Directory result = await getTemporaryDirectory(); + final PathProviderLinux provider = PathProviderLinux(); + final String result = await provider.getTemporaryPath(); _verifySampleFile(result, 'temporaryDirectory'); }); @@ -19,25 +20,29 @@ void main() { if (!Platform.isLinux) { return; } - final Directory result = await getDownloadsDirectory(); + final PathProviderLinux provider = PathProviderLinux(); + final String result = await provider.getDownloadsPath(); _verifySampleFile(result, 'downloadDirectory'); }); testWidgets('getApplicationDocumentsDirectory', (WidgetTester tester) async { - final Directory result = await getApplicationDocumentsDirectory(); + final PathProviderLinux provider = PathProviderLinux(); + final String result = await provider.getApplicationDocumentsPath(); _verifySampleFile(result, 'applicationDocuments'); }); testWidgets('getApplicationSupportDirectory', (WidgetTester tester) async { - final Directory result = await getApplicationSupportDirectory(); + final PathProviderLinux provider = PathProviderLinux(); + final String result = await provider.getApplicationSupportPath(); _verifySampleFile(result, 'applicationSupport'); }); } -/// Verify a file called [name] in [directory] by recreating it with test +/// Verify a file called [name] in [directoryPath] by recreating it with test /// contents when necessary. -void _verifySampleFile(Directory directory, String name) { - final File file = File('${directory.path}/$name'); +void _verifySampleFile(String directoryPath, String name) { + final Directory directory = Directory(directoryPath); + final File file = File('${directory.path}${Platform.pathSeparator}$name'); if (file.existsSync()) { file.deleteSync(); diff --git a/packages/path_provider/path_provider_linux/example/lib/main.dart b/packages/path_provider/path_provider_linux/example/lib/main.dart index 6dc364b77f2a..069308233acb 100644 --- a/packages/path_provider/path_provider_linux/example/lib/main.dart +++ b/packages/path_provider/path_provider_linux/example/lib/main.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'dart:async'; import 'package:flutter/services.dart'; -import 'package:path_provider/path_provider.dart'; +import 'package:path_provider_linux/path_provider_linux.dart'; void main() async { runApp(MyApp()); @@ -19,6 +19,7 @@ class _MyAppState extends State { String _downloadsDirectory = 'Unknown'; String _appSupportDirectory = 'Unknown'; String _documentsDirectory = 'Unknown'; + final PathProviderLinux _provider = PathProviderLinux(); @override void initState() { @@ -34,27 +35,27 @@ class _MyAppState extends State { String documentsDirectory; // Platform messages may fail, so we use a try/catch PlatformException. try { - tempDirectory = (await getTemporaryDirectory()).path; + tempDirectory = await _provider.getTemporaryPath(); } on PlatformException catch (e, stackTrace) { tempDirectory = 'Failed to get temp directory.'; print('$tempDirectory $e $stackTrace'); } try { - downloadsDirectory = (await getDownloadsDirectory()).path; + downloadsDirectory = await _provider.getDownloadsPath(); } on PlatformException catch (e, stackTrace) { downloadsDirectory = 'Failed to get downloads directory.'; print('$downloadsDirectory $e $stackTrace'); } try { - documentsDirectory = (await getApplicationDocumentsDirectory()).path; + documentsDirectory = await _provider.getApplicationDocumentsPath(); } on PlatformException catch (e, stackTrace) { documentsDirectory = 'Failed to get documents directory.'; print('$documentsDirectory $e $stackTrace'); } try { - appSupportDirectory = (await getApplicationSupportDirectory()).path; + appSupportDirectory = await _provider.getApplicationSupportPath(); } on PlatformException catch (e, stackTrace) { appSupportDirectory = 'Failed to get documents directory.'; print('$appSupportDirectory $e $stackTrace'); diff --git a/packages/path_provider/path_provider_linux/example/pubspec.yaml b/packages/path_provider/path_provider_linux/example/pubspec.yaml index 85dbb24bbb29..d66af910c998 100644 --- a/packages/path_provider/path_provider_linux/example/pubspec.yaml +++ b/packages/path_provider/path_provider_linux/example/pubspec.yaml @@ -9,7 +9,7 @@ dependencies: flutter: sdk: flutter - path_provider: ^1.6.10 + path_provider_linux: any # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. diff --git a/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart b/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart index 09d2447c0a6c..e35b73bf3766 100644 --- a/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart +++ b/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart @@ -18,12 +18,12 @@ class PathProviderLinux extends PathProviderPlatform { } @override - Future getTemporaryPath() { + Future getTemporaryPath() { return Future.value("/tmp"); } @override - Future getApplicationSupportPath() async { + Future getApplicationSupportPath() async { final processName = path.basenameWithoutExtension( await File('/proc/self/exe').resolveSymbolicLinks()); final directory = Directory(path.join(xdg.dataHome.path, processName)); @@ -35,12 +35,12 @@ class PathProviderLinux extends PathProviderPlatform { } @override - Future getApplicationDocumentsPath() { - return Future.value(xdg.getUserDirectory('DOCUMENTS').path); + Future getApplicationDocumentsPath() { + return Future.value(xdg.getUserDirectory('DOCUMENTS')?.path); } @override - Future getDownloadsPath() { - return Future.value(xdg.getUserDirectory('DOWNLOAD').path); + Future getDownloadsPath() { + return Future.value(xdg.getUserDirectory('DOWNLOAD')?.path); } } diff --git a/packages/path_provider/path_provider_linux/pubspec.yaml b/packages/path_provider/path_provider_linux/pubspec.yaml index adabbdd45246..df459e12d37f 100644 --- a/packages/path_provider/path_provider_linux/pubspec.yaml +++ b/packages/path_provider/path_provider_linux/pubspec.yaml @@ -1,6 +1,6 @@ name: path_provider_linux description: linux implementation of the path_provider plugin -version: 0.1.1+3 +version: 0.2.0-nullsafety homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_linux flutter: @@ -11,17 +11,17 @@ flutter: pluginClass: none environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.10.0" dependencies: - path: ^1.6.4 - xdg_directories: ^0.1.0 - path_provider_platform_interface: ^1.0.1 + path: ^1.8.0-nullsafety.3 + xdg_directories: ^0.2.0-nullsafety.1 + path_provider_platform_interface: ^2.0.0-nullsafety flutter: sdk: flutter dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0-nullsafety.3 From 47a5ea7994daad4cf05eb6fb4f8011f200fa8efe Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Wed, 3 Feb 2021 14:01:05 -0800 Subject: [PATCH 0087/1565] fix google_maps_flutter_platform_interface version (#3500) --- .../google_maps_flutter_platform_interface/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml index d8b260a7a3eb..487a54b08e5e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the google_maps_flutter plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.1.0 +version: 1.2.0 dependencies: flutter: From 37d658e7b984c7585e4f7463127e328d63f69236 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Wed, 3 Feb 2021 15:36:03 -0800 Subject: [PATCH 0088/1565] [google_maps_flutter] add tile overlays (#3434) --- .../google_maps_flutter/android/build.gradle | 5 + .../flutter/plugins/googlemaps/Convert.java | 53 +++- .../plugins/googlemaps/GoogleMapBuilder.java | 9 + .../googlemaps/GoogleMapController.java | 41 +++ .../plugins/googlemaps/GoogleMapFactory.java | 4 + .../googlemaps/GoogleMapOptionsSink.java | 4 + .../googlemaps/TileOverlayBuilder.java | 46 ++++ .../googlemaps/TileOverlayController.java | 62 +++++ .../plugins/googlemaps/TileOverlaySink.java | 20 ++ .../googlemaps/TileOverlaysController.java | 120 +++++++++ .../googlemaps/TileProviderController.java | 100 +++++++ .../google_map_inspector.dart | 7 + .../integration_test/google_maps_test.dart | 244 ++++++++++++++++++ .../google_maps_flutter/example/lib/main.dart | 2 + .../example/lib/tile_overlay.dart | 151 +++++++++++ .../FLTGoogleMapTileOverlayController.h | 42 +++ .../FLTGoogleMapTileOverlayController.m | 234 +++++++++++++++++ .../ios/Classes/GoogleMapController.m | 30 +++ .../lib/google_maps_flutter.dart | 6 +- .../lib/src/controller.dart | 24 ++ .../lib/src/google_map.dart | 13 + .../google_maps_flutter/pubspec.yaml | 2 +- .../test/fake_maps_controllers.dart | 79 ++++++ .../test/tile_overlay_updates_test.dart | 210 +++++++++++++++ 24 files changed, 1505 insertions(+), 3 deletions(-) create mode 100644 packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayBuilder.java create mode 100644 packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayController.java create mode 100644 packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaySink.java create mode 100644 packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java create mode 100644 packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileProviderController.java create mode 100644 packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart create mode 100644 packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h create mode 100644 packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m create mode 100644 packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart diff --git a/packages/google_maps_flutter/google_maps_flutter/android/build.gradle b/packages/google_maps_flutter/google_maps_flutter/android/build.gradle index a1d7da08a8d9..479c100b8293 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/build.gradle +++ b/packages/google_maps_flutter/google_maps_flutter/android/build.gradle @@ -39,6 +39,11 @@ android { androidTestImplementation 'androidx.test:rules:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } dependencies { diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java index 4108a1d23bb5..f9e0ed9c32d0 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java @@ -23,6 +23,7 @@ import com.google.android.gms.maps.model.PatternItem; import com.google.android.gms.maps.model.RoundCap; import com.google.android.gms.maps.model.SquareCap; +import com.google.android.gms.maps.model.Tile; import io.flutter.view.FlutterMain; import java.util.ArrayList; import java.util.Arrays; @@ -78,7 +79,8 @@ private static BitmapDescriptor getBitmapFromBytes(List data) { } } else { throw new IllegalArgumentException( - "fromBytes should have exactly one argument, the bytes. Got: " + data.size()); + "fromBytes should have exactly one argument, interpretTileOverlayOptions the bytes. Got: " + + data.size()); } } @@ -200,6 +202,20 @@ static Object circleIdToJson(String circleId) { return data; } + static Map tileOverlayArgumentsToJson( + String tileOverlayId, int x, int y, int zoom) { + + if (tileOverlayId == null) { + return null; + } + final Map data = new HashMap<>(4); + data.put("tileOverlayId", tileOverlayId); + data.put("x", x); + data.put("y", y); + data.put("zoom", zoom); + return data; + } + static Object latLngToJson(LatLng latLng) { return Arrays.asList(latLng.latitude, latLng.longitude); } @@ -645,4 +661,39 @@ private static Cap toCap(Object o) { throw new IllegalArgumentException("Cannot interpret " + o + " as Cap"); } } + + static String interpretTileOverlayOptions(Map data, TileOverlaySink sink) { + final Object fadeIn = data.get("fadeIn"); + if (fadeIn != null) { + sink.setFadeIn(toBoolean(fadeIn)); + } + final Object transparency = data.get("transparency"); + if (transparency != null) { + sink.setTransparency(toFloat(transparency)); + } + final Object zIndex = data.get("zIndex"); + if (zIndex != null) { + sink.setZIndex(toFloat(zIndex)); + } + final Object visible = data.get("visible"); + if (visible != null) { + sink.setVisible(toBoolean(visible)); + } + final String tileOverlayId = (String) data.get("tileOverlayId"); + if (tileOverlayId == null) { + throw new IllegalArgumentException("tileOverlayId was null"); + } else { + return tileOverlayId; + } + } + + static Tile interpretTile(Map data) { + int width = toInt(data.get("width")); + int height = toInt(data.get("height")); + byte[] dataArray = null; + if (data.get("data") != null) { + dataArray = (byte[]) data.get("data"); + } + return new Tile(width, height, dataArray); + } } diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java index 93a3c3ec9c28..6d5c8c64ae1d 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java @@ -10,6 +10,8 @@ import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.LatLngBounds; import io.flutter.plugin.common.BinaryMessenger; +import java.util.List; +import java.util.Map; class GoogleMapBuilder implements GoogleMapOptionsSink { private final GoogleMapOptions options = new GoogleMapOptions(); @@ -23,6 +25,7 @@ class GoogleMapBuilder implements GoogleMapOptionsSink { private Object initialPolygons; private Object initialPolylines; private Object initialCircles; + private List> initialTileOverlays; private Rect padding = new Rect(0, 0, 0, 0); GoogleMapController build( @@ -44,6 +47,7 @@ GoogleMapController build( controller.setInitialPolylines(initialPolylines); controller.setInitialCircles(initialCircles); controller.setPadding(padding.top, padding.left, padding.bottom, padding.right); + controller.setInitialTileOverlays(initialTileOverlays); return controller; } @@ -165,4 +169,9 @@ public void setInitialPolylines(Object initialPolylines) { public void setInitialCircles(Object initialCircles) { this.initialCircles = initialCircles; } + + @Override + public void setInitialTileOverlays(List> initialTileOverlays) { + this.initialTileOverlays = initialTileOverlays; + } } diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java index f6b8c3fe1fd1..7db65c56a5e8 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java @@ -76,10 +76,12 @@ final class GoogleMapController private final PolygonsController polygonsController; private final PolylinesController polylinesController; private final CirclesController circlesController; + private final TileOverlaysController tileOverlaysController; private List initialMarkers; private List initialPolygons; private List initialPolylines; private List initialCircles; + private List> initialTileOverlays; GoogleMapController( int id, @@ -99,6 +101,7 @@ final class GoogleMapController this.polygonsController = new PolygonsController(methodChannel, density); this.polylinesController = new PolylinesController(methodChannel, density); this.circlesController = new CirclesController(methodChannel, density); + this.tileOverlaysController = new TileOverlaysController(methodChannel); } @Override @@ -140,10 +143,12 @@ public void onMapReady(GoogleMap googleMap) { polygonsController.setGoogleMap(googleMap); polylinesController.setGoogleMap(googleMap); circlesController.setGoogleMap(googleMap); + tileOverlaysController.setGoogleMap(googleMap); updateInitialMarkers(); updateInitialPolygons(); updateInitialPolylines(); updateInitialCircles(); + updateInitialTileOverlays(); } @Override @@ -385,6 +390,30 @@ public void onSnapshotReady(Bitmap bitmap) { result.success(mapStyleResult); break; } + case "tileOverlays#update": + { + List> tileOverlaysToAdd = call.argument("tileOverlaysToAdd"); + tileOverlaysController.addTileOverlays(tileOverlaysToAdd); + List> tileOverlaysToChange = call.argument("tileOverlaysToChange"); + tileOverlaysController.changeTileOverlays(tileOverlaysToChange); + List tileOverlaysToRemove = call.argument("tileOverlayIdsToRemove"); + tileOverlaysController.removeTileOverlays(tileOverlaysToRemove); + result.success(null); + break; + } + case "tileOverlays#clearTileCache": + { + String tileOverlayId = call.argument("tileOverlayId"); + tileOverlaysController.clearTileCache(tileOverlayId); + result.success(null); + break; + } + case "map#getTileOverlayInfo": + { + String tileOverlayId = call.argument("tileOverlayId"); + result.success(tileOverlaysController.getTileOverlayInfo(tileOverlayId)); + break; + } default: result.notImplemented(); } @@ -732,6 +761,18 @@ private void updateInitialCircles() { circlesController.addCircles(initialCircles); } + @Override + public void setInitialTileOverlays(List> initialTileOverlays) { + this.initialTileOverlays = initialTileOverlays; + if (googleMap != null) { + updateInitialTileOverlays(); + } + } + + private void updateInitialTileOverlays() { + tileOverlaysController.addTileOverlays(initialTileOverlays); + } + @SuppressLint("MissingPermission") private void updateMyLocationSettings() { if (hasLocationPermission()) { diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java index e56adbbb987a..bf9188ffd1b1 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java @@ -10,6 +10,7 @@ import io.flutter.plugin.common.StandardMessageCodec; import io.flutter.plugin.platform.PlatformView; import io.flutter.plugin.platform.PlatformViewFactory; +import java.util.List; import java.util.Map; public class GoogleMapFactory extends PlatformViewFactory { @@ -46,6 +47,9 @@ public PlatformView create(Context context, int id, Object args) { if (params.containsKey("circlesToAdd")) { builder.setInitialCircles(params.get("circlesToAdd")); } + if (params.containsKey("tileOverlaysToAdd")) { + builder.setInitialTileOverlays((List>) params.get("tileOverlaysToAdd")); + } return builder.build(id, context, binaryMessenger, lifecycleProvider); } } diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java index 9e6fa2a27236..03377d4b760e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java @@ -5,6 +5,8 @@ package io.flutter.plugins.googlemaps; import com.google.android.gms.maps.model.LatLngBounds; +import java.util.List; +import java.util.Map; /** Receiver of GoogleMap configuration options. */ interface GoogleMapOptionsSink { @@ -51,4 +53,6 @@ interface GoogleMapOptionsSink { void setInitialPolylines(Object initialPolylines); void setInitialCircles(Object initialCircles); + + void setInitialTileOverlays(List> initialTileOverlays); } diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayBuilder.java new file mode 100644 index 000000000000..1b5593358536 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayBuilder.java @@ -0,0 +1,46 @@ +// Copyright 2018 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. + +package io.flutter.plugins.googlemaps; + +import com.google.android.gms.maps.model.TileOverlayOptions; +import com.google.android.gms.maps.model.TileProvider; + +class TileOverlayBuilder implements TileOverlaySink { + + private final TileOverlayOptions tileOverlayOptions; + + TileOverlayBuilder() { + this.tileOverlayOptions = new TileOverlayOptions(); + } + + TileOverlayOptions build() { + return tileOverlayOptions; + } + + @Override + public void setFadeIn(boolean fadeIn) { + tileOverlayOptions.fadeIn(fadeIn); + } + + @Override + public void setTransparency(float transparency) { + tileOverlayOptions.transparency(transparency); + } + + @Override + public void setZIndex(float zIndex) { + tileOverlayOptions.zIndex(zIndex); + } + + @Override + public void setVisible(boolean visible) { + tileOverlayOptions.visible(visible); + } + + @Override + public void setTileProvider(TileProvider tileProvider) { + tileOverlayOptions.tileProvider(tileProvider); + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayController.java new file mode 100644 index 000000000000..1204bcdaafd7 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayController.java @@ -0,0 +1,62 @@ +// Copyright 2018 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. + +package io.flutter.plugins.googlemaps; + +import com.google.android.gms.maps.model.TileOverlay; +import com.google.android.gms.maps.model.TileProvider; +import java.util.HashMap; +import java.util.Map; + +class TileOverlayController implements TileOverlaySink { + + private final TileOverlay tileOverlay; + + TileOverlayController(TileOverlay tileOverlay) { + this.tileOverlay = tileOverlay; + } + + void remove() { + tileOverlay.remove(); + } + + void clearTileCache() { + tileOverlay.clearTileCache(); + } + + Map getTileOverlayInfo() { + Map tileOverlayInfo = new HashMap<>(); + tileOverlayInfo.put("fadeIn", tileOverlay.getFadeIn()); + tileOverlayInfo.put("transparency", tileOverlay.getTransparency()); + tileOverlayInfo.put("id", tileOverlay.getId()); + tileOverlayInfo.put("zIndex", tileOverlay.getZIndex()); + tileOverlayInfo.put("visible", tileOverlay.isVisible()); + return tileOverlayInfo; + } + + @Override + public void setFadeIn(boolean fadeIn) { + tileOverlay.setFadeIn(fadeIn); + } + + @Override + public void setTransparency(float transparency) { + tileOverlay.setTransparency(transparency); + } + + @Override + public void setZIndex(float zIndex) { + tileOverlay.setZIndex(zIndex); + } + + @Override + public void setVisible(boolean visible) { + tileOverlay.setVisible(visible); + } + + @Override + public void setTileProvider(TileProvider tileProvider) { + // You can not change tile provider after creation + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaySink.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaySink.java new file mode 100644 index 000000000000..fd611d7c57f3 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaySink.java @@ -0,0 +1,20 @@ +// Copyright 2018 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. + +package io.flutter.plugins.googlemaps; + +import com.google.android.gms.maps.model.TileProvider; + +/** Receiver of TileOverlayOptions configuration. */ +interface TileOverlaySink { + void setFadeIn(boolean fadeIn); + + void setTransparency(float transparency); + + void setZIndex(float zIndex); + + void setVisible(boolean visible); + + void setTileProvider(TileProvider tileProvider); +} diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java new file mode 100644 index 000000000000..cd583e247cdd --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java @@ -0,0 +1,120 @@ +// Copyright 2018 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. + +package io.flutter.plugins.googlemaps; + +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.model.TileOverlay; +import com.google.android.gms.maps.model.TileOverlayOptions; +import io.flutter.plugin.common.MethodChannel; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +class TileOverlaysController { + + private final Map tileOverlayIdToController; + private final MethodChannel methodChannel; + private GoogleMap googleMap; + + TileOverlaysController(MethodChannel methodChannel) { + this.tileOverlayIdToController = new HashMap<>(); + this.methodChannel = methodChannel; + } + + void setGoogleMap(GoogleMap googleMap) { + this.googleMap = googleMap; + } + + void addTileOverlays(List> tileOverlaysToAdd) { + if (tileOverlaysToAdd == null) { + return; + } + for (Map tileOverlayToAdd : tileOverlaysToAdd) { + addTileOverlay(tileOverlayToAdd); + } + } + + void changeTileOverlays(List> tileOverlaysToChange) { + if (tileOverlaysToChange == null) { + return; + } + for (Map tileOverlayToChange : tileOverlaysToChange) { + changeTileOverlay(tileOverlayToChange); + } + } + + void removeTileOverlays(List tileOverlayIdsToRemove) { + if (tileOverlayIdsToRemove == null) { + return; + } + for (String tileOverlayId : tileOverlayIdsToRemove) { + if (tileOverlayId == null) { + continue; + } + removeTileOverlay(tileOverlayId); + } + } + + void clearTileCache(String tileOverlayId) { + if (tileOverlayId == null) { + return; + } + TileOverlayController tileOverlayController = tileOverlayIdToController.get(tileOverlayId); + if (tileOverlayController != null) { + tileOverlayController.clearTileCache(); + } + } + + Map getTileOverlayInfo(String tileOverlayId) { + if (tileOverlayId == null) { + return null; + } + TileOverlayController tileOverlayController = tileOverlayIdToController.get(tileOverlayId); + if (tileOverlayController == null) { + return null; + } + return tileOverlayController.getTileOverlayInfo(); + } + + private void addTileOverlay(Map tileOverlayOptions) { + if (tileOverlayOptions == null) { + return; + } + TileOverlayBuilder tileOverlayOptionsBuilder = new TileOverlayBuilder(); + String tileOverlayId = + Convert.interpretTileOverlayOptions(tileOverlayOptions, tileOverlayOptionsBuilder); + TileProviderController tileProviderController = + new TileProviderController(methodChannel, tileOverlayId); + tileOverlayOptionsBuilder.setTileProvider(tileProviderController); + TileOverlayOptions options = tileOverlayOptionsBuilder.build(); + TileOverlay tileOverlay = googleMap.addTileOverlay(options); + TileOverlayController tileOverlayController = new TileOverlayController(tileOverlay); + tileOverlayIdToController.put(tileOverlayId, tileOverlayController); + } + + private void changeTileOverlay(Map tileOverlayOptions) { + if (tileOverlayOptions == null) { + return; + } + String tileOverlayId = getTileOverlayId(tileOverlayOptions); + TileOverlayController tileOverlayController = tileOverlayIdToController.get(tileOverlayId); + if (tileOverlayController != null) { + Convert.interpretTileOverlayOptions(tileOverlayOptions, tileOverlayController); + } + } + + private void removeTileOverlay(String tileOverlayId) { + TileOverlayController tileOverlayController = tileOverlayIdToController.get(tileOverlayId); + if (tileOverlayController != null) { + tileOverlayController.remove(); + tileOverlayIdToController.remove(tileOverlayId); + } + } + + @SuppressWarnings("unchecked") + private static String getTileOverlayId(Map tileOverlay) { + return (String) tileOverlay.get("tileOverlayId"); + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileProviderController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileProviderController.java new file mode 100644 index 000000000000..f28118c91db4 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileProviderController.java @@ -0,0 +1,100 @@ +// Copyright 2018 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. + +package io.flutter.plugins.googlemaps; + +import android.os.Handler; +import android.os.Looper; +import android.util.Log; +import androidx.annotation.NonNull; +import com.google.android.gms.maps.model.Tile; +import com.google.android.gms.maps.model.TileProvider; +import io.flutter.plugin.common.MethodChannel; +import java.util.Map; +import java.util.concurrent.CountDownLatch; + +class TileProviderController implements TileProvider { + + private static final String TAG = "TileProviderController"; + + private final String tileOverlayId; + private final MethodChannel methodChannel; + private final Handler handler = new Handler(Looper.getMainLooper()); + + TileProviderController(MethodChannel methodChannel, String tileOverlayId) { + this.tileOverlayId = tileOverlayId; + this.methodChannel = methodChannel; + } + + @Override + public Tile getTile(final int x, final int y, final int zoom) { + Worker worker = new Worker(x, y, zoom); + return worker.getTile(); + } + + private final class Worker implements MethodChannel.Result { + + private final CountDownLatch countDownLatch = new CountDownLatch(1); + private final int x; + private final int y; + private final int zoom; + private Map result; + + Worker(int x, int y, int zoom) { + this.x = x; + this.y = y; + this.zoom = zoom; + } + + @NonNull + Tile getTile() { + handler.post( + () -> + methodChannel.invokeMethod( + "tileOverlay#getTile", + Convert.tileOverlayArgumentsToJson(tileOverlayId, x, y, zoom), + this)); + try { + // Because `methodChannel.invokeMethod` is async, we use a `countDownLatch` make it synchronized. + countDownLatch.await(); + } catch (InterruptedException e) { + Log.e( + TAG, + String.format("countDownLatch: can't get tile: x = %d, y= %d, zoom = %d", x, y, zoom), + e); + return TileProvider.NO_TILE; + } + try { + return Convert.interpretTile(result); + } catch (Exception e) { + Log.e(TAG, "Can't parse tile data", e); + return TileProvider.NO_TILE; + } + } + + @Override + public void success(Object data) { + result = (Map) data; + countDownLatch.countDown(); + } + + @Override + public void error(String errorCode, String errorMessage, Object data) { + Log.e( + TAG, + String.format( + "Can't get tile: errorCode = %s, errorMessage = %s, date = %s", + errorCode, errorCode, data)); + result = null; + countDownLatch.countDown(); + } + + @Override + public void notImplemented() { + Log.e(TAG, "Can't get tile: notImplemented"); + result = null; + countDownLatch.countDown(); + } + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart index 2fcfec15713a..0f2dafb80f70 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart @@ -76,4 +76,11 @@ class GoogleMapInspector { Future takeSnapshot() async { return await _channel.invokeMethod('map#takeSnapshot'); } + + Future> getTileOverlayInfo(String id) async { + return await _channel.invokeMapMethod( + 'map#getTileOverlayInfo', { + 'tileOverlayId': id, + }); + } } diff --git a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart index 2a5bf80a4578..557337f0c025 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart @@ -5,6 +5,7 @@ import 'dart:async'; import 'dart:io'; import 'dart:typed_data'; +import 'dart:ui' as ui; import 'package:integration_test/integration_test.dart'; import 'package:flutter/material.dart'; @@ -987,4 +988,247 @@ void main() { // TODO(cyanglaz): un-skip the test when we can test this on CI with API key enabled. // https://github.com/flutter/flutter/issues/57057 skip: Platform.isAndroid); + + testWidgets( + 'set tileOverlay correctly', + (WidgetTester tester) async { + Completer inspectorCompleter = + Completer(); + final TileOverlay tileOverlay1 = TileOverlay( + tileOverlayId: TileOverlayId('tile_overlay_1'), + tileProvider: _DebugTileProvider(), + zIndex: 2, + visible: true, + transparency: 0.2, + fadeIn: true, + ); + + final TileOverlay tileOverlay2 = TileOverlay( + tileOverlayId: TileOverlayId('tile_overlay_2'), + tileProvider: _DebugTileProvider(), + zIndex: 1, + visible: false, + transparency: 0.3, + fadeIn: false, + ); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: GoogleMap( + initialCameraPosition: _kInitialCameraPosition, + tileOverlays: {tileOverlay1, tileOverlay2}, + onMapCreated: (GoogleMapController controller) { + final GoogleMapInspector inspector = + // ignore: invalid_use_of_visible_for_testing_member + GoogleMapInspector(controller.channel); + inspectorCompleter.complete(inspector); + }, + ), + ), + ); + await tester.pumpAndSettle(const Duration(seconds: 3)); + + final GoogleMapInspector inspector = await inspectorCompleter.future; + + Map tileOverlayInfo1 = + await inspector.getTileOverlayInfo('tile_overlay_1'); + Map tileOverlayInfo2 = + await inspector.getTileOverlayInfo('tile_overlay_2'); + + expect(tileOverlayInfo1['visible'], isTrue); + expect(tileOverlayInfo1['fadeIn'], isTrue); + expect(tileOverlayInfo1['transparency'], + moreOrLessEquals(0.2, epsilon: 0.001)); + expect(tileOverlayInfo1['zIndex'], 2); + + expect(tileOverlayInfo2['visible'], isFalse); + expect(tileOverlayInfo2['fadeIn'], isFalse); + expect(tileOverlayInfo2['transparency'], + moreOrLessEquals(0.3, epsilon: 0.001)); + expect(tileOverlayInfo2['zIndex'], 1); + }, + ); + + testWidgets( + 'update tileOverlays correctly', + (WidgetTester tester) async { + Completer inspectorCompleter = + Completer(); + final Key key = GlobalKey(); + final TileOverlay tileOverlay1 = TileOverlay( + tileOverlayId: TileOverlayId('tile_overlay_1'), + tileProvider: _DebugTileProvider(), + zIndex: 2, + visible: true, + transparency: 0.2, + fadeIn: true, + ); + + final TileOverlay tileOverlay2 = TileOverlay( + tileOverlayId: TileOverlayId('tile_overlay_2'), + tileProvider: _DebugTileProvider(), + zIndex: 3, + visible: true, + transparency: 0.5, + fadeIn: true, + ); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: GoogleMap( + key: key, + initialCameraPosition: _kInitialCameraPosition, + tileOverlays: {tileOverlay1, tileOverlay2}, + onMapCreated: (GoogleMapController controller) { + final GoogleMapInspector inspector = + // ignore: invalid_use_of_visible_for_testing_member + GoogleMapInspector(controller.channel); + inspectorCompleter.complete(inspector); + }, + ), + ), + ); + + final GoogleMapInspector inspector = await inspectorCompleter.future; + + final TileOverlay tileOverlay1New = TileOverlay( + tileOverlayId: TileOverlayId('tile_overlay_1'), + tileProvider: _DebugTileProvider(), + zIndex: 1, + visible: false, + transparency: 0.3, + fadeIn: false, + ); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: GoogleMap( + key: key, + initialCameraPosition: _kInitialCameraPosition, + tileOverlays: {tileOverlay1New}, + onMapCreated: (GoogleMapController controller) { + fail('update: OnMapCreated should get called only once.'); + }, + ), + ), + ); + + await tester.pumpAndSettle(const Duration(seconds: 3)); + + Map tileOverlayInfo1 = + await inspector.getTileOverlayInfo('tile_overlay_1'); + Map tileOverlayInfo2 = + await inspector.getTileOverlayInfo('tile_overlay_2'); + + expect(tileOverlayInfo1['visible'], isFalse); + expect(tileOverlayInfo1['fadeIn'], isFalse); + expect(tileOverlayInfo1['transparency'], + moreOrLessEquals(0.3, epsilon: 0.001)); + expect(tileOverlayInfo1['zIndex'], 1); + + expect(tileOverlayInfo2, isNull); + }, + ); + + testWidgets( + 'remove tileOverlays correctly', + (WidgetTester tester) async { + Completer inspectorCompleter = + Completer(); + final Key key = GlobalKey(); + final TileOverlay tileOverlay1 = TileOverlay( + tileOverlayId: TileOverlayId('tile_overlay_1'), + tileProvider: _DebugTileProvider(), + zIndex: 2, + visible: true, + transparency: 0.2, + fadeIn: true, + ); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: GoogleMap( + key: key, + initialCameraPosition: _kInitialCameraPosition, + tileOverlays: {tileOverlay1}, + onMapCreated: (GoogleMapController controller) { + final GoogleMapInspector inspector = + // ignore: invalid_use_of_visible_for_testing_member + GoogleMapInspector(controller.channel); + inspectorCompleter.complete(inspector); + }, + ), + ), + ); + + final GoogleMapInspector inspector = await inspectorCompleter.future; + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: GoogleMap( + key: key, + initialCameraPosition: _kInitialCameraPosition, + onMapCreated: (GoogleMapController controller) { + fail('OnMapCreated should get called only once.'); + }, + ), + ), + ); + + await tester.pumpAndSettle(const Duration(seconds: 3)); + Map tileOverlayInfo1 = + await inspector.getTileOverlayInfo('tile_overlay_1'); + + expect(tileOverlayInfo1, isNull); + }, + ); +} + +class _DebugTileProvider implements TileProvider { + _DebugTileProvider() { + boxPaint.isAntiAlias = true; + boxPaint.color = Colors.blue; + boxPaint.strokeWidth = 2.0; + boxPaint.style = PaintingStyle.stroke; + } + + static const int width = 100; + static const int height = 100; + static final Paint boxPaint = Paint(); + static final TextStyle textStyle = TextStyle( + color: Colors.red, + fontSize: 20, + ); + + @override + Future getTile(int x, int y, int zoom) async { + final ui.PictureRecorder recorder = ui.PictureRecorder(); + final Canvas canvas = Canvas(recorder); + final TextSpan textSpan = TextSpan( + text: "$x,$y", + style: textStyle, + ); + final TextPainter textPainter = TextPainter( + text: textSpan, + textDirection: TextDirection.ltr, + ); + textPainter.layout( + minWidth: 0.0, + maxWidth: width.toDouble(), + ); + final Offset offset = const Offset(0, 0); + textPainter.paint(canvas, offset); + canvas.drawRect( + Rect.fromLTRB(0, 0, width.toDouble(), width.toDouble()), boxPaint); + final ui.Picture picture = recorder.endRecording(); + final Uint8List byteData = await picture + .toImage(width, height) + .then((ui.Image image) => + image.toByteData(format: ui.ImageByteFormat.png)) + .then((ByteData byteData) => byteData.buffer.asUint8List()); + return Tile(width, height, byteData); + } } diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart index 13763edb8216..b795040658e6 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart @@ -20,6 +20,7 @@ import 'place_polygon.dart'; import 'place_polyline.dart'; import 'scrolling_map.dart'; import 'snapshot.dart'; +import 'tile_overlay.dart'; final List _allPages = [ MapUiPage(), @@ -36,6 +37,7 @@ final List _allPages = [ PaddingPage(), SnapshotPage(), LiteModePage(), + TileOverlayPage(), ]; class MapsDemo extends StatelessWidget { diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart new file mode 100644 index 000000000000..354fa06a7ab7 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart @@ -0,0 +1,151 @@ +// Copyright 2018 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. + +// ignore_for_file: public_member_api_docs + +import 'dart:typed_data'; +import 'dart:ui' as ui; + +import 'package:flutter/material.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; + +import 'page.dart'; + +class TileOverlayPage extends GoogleMapExampleAppPage { + TileOverlayPage() : super(const Icon(Icons.map), 'Tile overlay'); + + @override + Widget build(BuildContext context) { + return const TileOverlayBody(); + } +} + +class TileOverlayBody extends StatefulWidget { + const TileOverlayBody(); + + @override + State createState() => TileOverlayBodyState(); +} + +class TileOverlayBodyState extends State { + TileOverlayBodyState(); + + GoogleMapController controller; + TileOverlay _tileOverlay; + + void _onMapCreated(GoogleMapController controller) { + this.controller = controller; + } + + @override + void dispose() { + super.dispose(); + } + + void _removeTileOverlay() { + setState(() { + _tileOverlay = null; + }); + } + + void _addTileOverlay() { + final TileOverlay tileOverlay = TileOverlay( + tileOverlayId: TileOverlayId('tile_overlay_1'), + tileProvider: _DebugTileProvider(), + ); + setState(() { + _tileOverlay = tileOverlay; + }); + } + + void _clearTileCache() { + if (_tileOverlay != null && controller != null) { + controller.clearTileCache(_tileOverlay.tileOverlayId); + } + } + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Center( + child: SizedBox( + width: 350.0, + height: 300.0, + child: GoogleMap( + initialCameraPosition: const CameraPosition( + target: LatLng(59.935460, 30.325177), + zoom: 7.0, + ), + tileOverlays: + _tileOverlay != null ? {_tileOverlay} : null, + onMapCreated: _onMapCreated, + ), + ), + ), + TextButton( + child: const Text('Add tile overlay'), + onPressed: _addTileOverlay, + ), + TextButton( + child: const Text('Remove tile overlay'), + onPressed: _removeTileOverlay, + ), + TextButton( + child: const Text('Clear tile cache'), + onPressed: _clearTileCache, + ), + ], + ); + } +} + +class _DebugTileProvider implements TileProvider { + _DebugTileProvider() { + boxPaint.isAntiAlias = true; + boxPaint.color = Colors.blue; + boxPaint.strokeWidth = 2.0; + boxPaint.style = PaintingStyle.stroke; + } + + static const int width = 100; + static const int height = 100; + static final Paint boxPaint = Paint(); + static final TextStyle textStyle = TextStyle( + color: Colors.red, + fontSize: 20, + ); + + @override + Future getTile(int x, int y, int zoom) async { + final ui.PictureRecorder recorder = ui.PictureRecorder(); + final Canvas canvas = Canvas(recorder); + final TextSpan textSpan = TextSpan( + text: '$x,$y', + style: textStyle, + ); + final TextPainter textPainter = TextPainter( + text: textSpan, + textDirection: TextDirection.ltr, + ); + textPainter.layout( + minWidth: 0.0, + maxWidth: width.toDouble(), + ); + final Offset offset = const Offset(0, 0); + textPainter.paint(canvas, offset); + canvas.drawRect( + Rect.fromLTRB(0, 0, width.toDouble(), width.toDouble()), boxPaint); + final ui.Picture picture = recorder.endRecording(); + final Uint8List byteData = await picture + .toImage(width, height) + .then((ui.Image image) => + image.toByteData(format: ui.ImageByteFormat.png)) + .then((ByteData byteData) => byteData.buffer.asUint8List()); + return Tile(width, height, byteData); + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h new file mode 100644 index 000000000000..f84ad7c20bb4 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h @@ -0,0 +1,42 @@ +// Copyright 2018 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. + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +// Defines map UI options writable from Flutter. +@protocol FLTGoogleMapTileOverlayOptionsSink +- (void)setFadeIn:(BOOL)fadeIn; +- (void)setTransparency:(float)transparency; +- (void)setZIndex:(int)zIndex; +- (void)setVisible:(BOOL)visible; +- (void)setTileSize:(NSInteger)tileSize; +@end + +@interface FLTGoogleMapTileOverlayController : NSObject +- (instancetype)initWithTileLayer:(GMSTileLayer *)tileLayer mapView:(GMSMapView *)mapView; +- (void)removeTileOverlay; +- (void)clearTileCache; +- (NSDictionary *)getTileOverlayInfo; +@end + +@interface FLTTileProviderController : GMSTileLayer +@property(copy, nonatomic, readonly) NSString *tileOverlayId; +- (instancetype)init:(FlutterMethodChannel *)methodChannel tileOverlayId:(NSString *)tileOverlayId; +@end + +@interface FLTTileOverlaysController : NSObject +- (instancetype)init:(FlutterMethodChannel *)methodChannel + mapView:(GMSMapView *)mapView + registrar:(NSObject *)registrar; +- (void)addTileOverlays:(NSArray *)tileOverlaysToAdd; +- (void)changeTileOverlays:(NSArray *)tileOverlaysToChange; +- (void)removeTileOverlayIds:(NSArray *)tileOverlayIdsToRemove; +- (void)clearTileCache:(NSString *)tileOverlayId; +- (nullable NSDictionary *)getTileOverlayInfo:(NSString *)tileverlayId; +@end + +NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m new file mode 100644 index 000000000000..7fbd7c53b90a --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m @@ -0,0 +1,234 @@ +// Copyright 2018 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. + +#import "FLTGoogleMapTileOverlayController.h" +#import "JsonConversions.h" + +static void InterpretTileOverlayOptions(NSDictionary* data, + id sink, + NSObject* registrar) { + NSNumber* visible = data[@"visible"]; + if (visible != nil) { + [sink setVisible:visible.boolValue]; + } + + NSNumber* transparency = data[@"transparency"]; + if (transparency != nil) { + [sink setTransparency:transparency.floatValue]; + } + + NSNumber* zIndex = data[@"zIndex"]; + if (zIndex != nil) { + [sink setZIndex:zIndex.intValue]; + } + + NSNumber* fadeIn = data[@"fadeIn"]; + if (fadeIn != nil) { + [sink setFadeIn:fadeIn.boolValue]; + } + + NSNumber* tileSize = data[@"tileSize"]; + if (tileSize != nil) { + [sink setTileSize:tileSize.integerValue]; + } +} + +@interface FLTGoogleMapTileOverlayController () + +@property(strong, nonatomic) GMSTileLayer* layer; +@property(weak, nonatomic) GMSMapView* mapView; + +@end + +@implementation FLTGoogleMapTileOverlayController + +- (instancetype)initWithTileLayer:(GMSTileLayer*)tileLayer mapView:(GMSMapView*)mapView { + self = [super init]; + if (self) { + self.layer = tileLayer; + self.mapView = mapView; + } + return self; +} + +- (void)removeTileOverlay { + self.layer.map = nil; +} + +- (void)clearTileCache { + [self.layer clearTileCache]; +} + +- (NSDictionary*)getTileOverlayInfo { + NSMutableDictionary* info = [[NSMutableDictionary alloc] init]; + BOOL visible = self.layer.map != nil; + info[@"visible"] = @(visible); + info[@"fadeIn"] = @(self.layer.fadeIn); + float transparency = 1.0 - self.layer.opacity; + info[@"transparency"] = @(transparency); + info[@"zIndex"] = @(self.layer.zIndex); + return info; +} + +#pragma mark - FLTGoogleMapTileOverlayOptionsSink methods + +- (void)setFadeIn:(BOOL)fadeIn { + self.layer.fadeIn = fadeIn; +} + +- (void)setTransparency:(float)transparency { + float opacity = 1.0 - transparency; + self.layer.opacity = opacity; +} + +- (void)setVisible:(BOOL)visible { + self.layer.map = visible ? self.mapView : nil; +} + +- (void)setZIndex:(int)zIndex { + self.layer.zIndex = zIndex; +} + +- (void)setTileSize:(NSInteger)tileSize { + self.layer.tileSize = tileSize; +} +@end + +@interface FLTTileProviderController () + +@property(weak, nonatomic) FlutterMethodChannel* methodChannel; +@property(copy, nonatomic, readwrite) NSString* tileOverlayId; + +@end + +@implementation FLTTileProviderController + +- (instancetype)init:(FlutterMethodChannel*)methodChannel tileOverlayId:(NSString*)tileOverlayId { + self = [super init]; + if (self) { + self.methodChannel = methodChannel; + self.tileOverlayId = tileOverlayId; + } + return self; +} + +#pragma mark - GMSTileLayer method + +- (void)requestTileForX:(NSUInteger)x + y:(NSUInteger)y + zoom:(NSUInteger)zoom + receiver:(id)receiver { + [self.methodChannel + invokeMethod:@"tileOverlay#getTile" + arguments:@{ + @"tileOverlayId" : self.tileOverlayId, + @"x" : @(x), + @"y" : @(y), + @"zoom" : @(zoom) + } + result:^(id _Nullable result) { + UIImage* tileImage; + if ([result isKindOfClass:[NSDictionary class]]) { + FlutterStandardTypedData* typedData = (FlutterStandardTypedData*)result[@"data"]; + if (typedData == nil) { + tileImage = kGMSTileLayerNoTile; + } else { + tileImage = [UIImage imageWithData:typedData.data]; + } + } else { + if ([result isKindOfClass:[FlutterError class]]) { + FlutterError* error = (FlutterError*)result; + NSLog(@"Can't get tile: errorCode = %@, errorMessage = %@, details = %@", + [error code], [error message], [error details]); + } + if ([result isKindOfClass:[FlutterMethodNotImplemented class]]) { + NSLog(@"Can't get tile: notImplemented"); + } + tileImage = kGMSTileLayerNoTile; + } + + [receiver receiveTileWithX:x y:y zoom:zoom image:tileImage]; + }]; +} + +@end + +@interface FLTTileOverlaysController () + +@property(strong, nonatomic) NSMutableDictionary* tileOverlayIdToController; +@property(weak, nonatomic) FlutterMethodChannel* methodChannel; +@property(weak, nonatomic) NSObject* registrar; +@property(weak, nonatomic) GMSMapView* mapView; + +@end + +@implementation FLTTileOverlaysController + +- (instancetype)init:(FlutterMethodChannel*)methodChannel + mapView:(GMSMapView*)mapView + registrar:(NSObject*)registrar { + self = [super init]; + if (self) { + self.methodChannel = methodChannel; + self.mapView = mapView; + self.tileOverlayIdToController = [[NSMutableDictionary alloc] init]; + self.registrar = registrar; + } + return self; +} + +- (void)addTileOverlays:(NSArray*)tileOverlaysToAdd { + for (NSDictionary* tileOverlay in tileOverlaysToAdd) { + NSString* tileOverlayId = [FLTTileOverlaysController getTileOverlayId:tileOverlay]; + FLTTileProviderController* tileProvider = + [[FLTTileProviderController alloc] init:self.methodChannel tileOverlayId:tileOverlayId]; + FLTGoogleMapTileOverlayController* controller = + [[FLTGoogleMapTileOverlayController alloc] initWithTileLayer:tileProvider + mapView:self.mapView]; + InterpretTileOverlayOptions(tileOverlay, controller, self.registrar); + self.tileOverlayIdToController[tileOverlayId] = controller; + } +} + +- (void)changeTileOverlays:(NSArray*)tileOverlaysToChange { + for (NSDictionary* tileOverlay in tileOverlaysToChange) { + NSString* tileOverlayId = [FLTTileOverlaysController getTileOverlayId:tileOverlay]; + FLTGoogleMapTileOverlayController* controller = self.tileOverlayIdToController[tileOverlayId]; + if (!controller) { + continue; + } + InterpretTileOverlayOptions(tileOverlay, controller, self.registrar); + } +} +- (void)removeTileOverlayIds:(NSArray*)tileOverlayIdsToRemove { + for (NSString* tileOverlayId in tileOverlayIdsToRemove) { + FLTGoogleMapTileOverlayController* controller = self.tileOverlayIdToController[tileOverlayId]; + if (!controller) { + continue; + } + [controller removeTileOverlay]; + [self.tileOverlayIdToController removeObjectForKey:tileOverlayId]; + } +} + +- (void)clearTileCache:(NSString*)tileOverlayId { + FLTGoogleMapTileOverlayController* controller = self.tileOverlayIdToController[tileOverlayId]; + if (!controller) { + return; + } + [controller clearTileCache]; +} + +- (nullable NSDictionary*)getTileOverlayInfo:(NSString*)tileverlayId { + if (self.tileOverlayIdToController[tileverlayId] == nil) { + return nil; + } + return [self.tileOverlayIdToController[tileverlayId] getTileOverlayInfo]; +} + ++ (NSString*)getTileOverlayId:(NSDictionary*)tileOverlay { + return tileOverlay[@"tileOverlayId"]; +} + +@end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m index 321ddd318536..749ce9e84a4e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m @@ -3,6 +3,7 @@ // found in the LICENSE file. #import "GoogleMapController.h" +#import "FLTGoogleMapTileOverlayController.h" #import "JsonConversions.h" #pragma mark - Conversion of JSON-like values sent via platform channels. Forward declarations. @@ -55,6 +56,7 @@ @implementation FLTGoogleMapController { FLTPolygonsController* _polygonsController; FLTPolylinesController* _polylinesController; FLTCirclesController* _circlesController; + FLTTileOverlaysController* _tileOverlaysController; } - (instancetype)initWithFrame:(CGRect)frame @@ -94,6 +96,9 @@ - (instancetype)initWithFrame:(CGRect)frame _circlesController = [[FLTCirclesController alloc] init:_channel mapView:_mapView registrar:registrar]; + _tileOverlaysController = [[FLTTileOverlaysController alloc] init:_channel + mapView:_mapView + registrar:registrar]; id markersToAdd = args[@"markersToAdd"]; if ([markersToAdd isKindOfClass:[NSArray class]]) { [_markersController addMarkers:markersToAdd]; @@ -110,6 +115,10 @@ - (instancetype)initWithFrame:(CGRect)frame if ([circlesToAdd isKindOfClass:[NSArray class]]) { [_circlesController addCircles:circlesToAdd]; } + id tileOverlaysToAdd = args[@"tileOverlaysToAdd"]; + if ([tileOverlaysToAdd isKindOfClass:[NSArray class]]) { + [_tileOverlaysController addTileOverlays:tileOverlaysToAdd]; + } } return self; } @@ -298,6 +307,24 @@ - (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { [_circlesController removeCircleIds:circleIdsToRemove]; } result(nil); + } else if ([call.method isEqualToString:@"tileOverlays#update"]) { + id tileOverlaysToAdd = call.arguments[@"tileOverlaysToAdd"]; + if ([tileOverlaysToAdd isKindOfClass:[NSArray class]]) { + [_tileOverlaysController addTileOverlays:tileOverlaysToAdd]; + } + id tileOverlaysToChange = call.arguments[@"tileOverlaysToChange"]; + if ([tileOverlaysToChange isKindOfClass:[NSArray class]]) { + [_tileOverlaysController changeTileOverlays:tileOverlaysToChange]; + } + id tileOverlayIdsToRemove = call.arguments[@"tileOverlayIdsToRemove"]; + if ([tileOverlayIdsToRemove isKindOfClass:[NSArray class]]) { + [_tileOverlaysController removeTileOverlayIds:tileOverlayIdsToRemove]; + } + result(nil); + } else if ([call.method isEqualToString:@"tileOverlays#clearTileCache"]) { + id rawTileOverlayId = call.arguments[@"tileOverlayId"]; + [_tileOverlaysController clearTileCache:rawTileOverlayId]; + result(nil); } else if ([call.method isEqualToString:@"map#isCompassEnabled"]) { NSNumber* isCompassEnabled = @(_mapView.settings.compassButton); result(isCompassEnabled); @@ -341,6 +368,9 @@ - (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { } else { result(@[ @(NO), error ]); } + } else if ([call.method isEqualToString:@"map#getTileOverlayInfo"]) { + NSString* rawTileOverlayId = call.arguments[@"tileOverlayId"]; + result([_tileOverlaysController getTileOverlayInfo:rawTileOverlayId]); } else { result(FlutterMethodNotImplemented); } diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart b/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart index 682c901f4d4a..703ba63e5ccc 100644 --- a/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart +++ b/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart @@ -42,7 +42,11 @@ export 'package:google_maps_flutter_platform_interface/google_maps_flutter_platf PolygonId, Polyline, PolylineId, - ScreenCoordinate; + ScreenCoordinate, + Tile, + TileOverlayId, + TileOverlay, + TileProvider; part 'src/controller.dart'; part 'src/google_map.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart index f47b8e57b049..3967179b0e50 100644 --- a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart @@ -152,6 +152,30 @@ class GoogleMapController { mapId: mapId); } + /// Updates tile overlays configuration. + /// + /// Change listeners are notified once the update has been made on the + /// platform side. + /// + /// The returned [Future] completes after listeners have been notified. + Future _updateTileOverlays(Set newTileOverlays) { + return _googleMapsFlutterPlatform.updateTileOverlays( + newTileOverlays: newTileOverlays, mapId: mapId); + } + + /// Clears the tile cache so that all tiles will be requested again from the + /// [TileProvider]. + /// + /// The current tiles from this tile overlay will also be + /// cleared from the map after calling this method. The API maintains a small + /// in-memory cache of tiles. If you want to cache tiles for longer, you + /// should implement an on-disk cache. + Future clearTileCache(TileOverlayId tileOverlayId) async { + assert(tileOverlayId != null); + return _googleMapsFlutterPlatform.clearTileCache(tileOverlayId, + mapId: mapId); + } + /// Starts an animated change of the map camera position. /// /// The returned [Future] completes after the change has been started on the diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart index d7f0f1a4e280..e7f5e32d61b9 100644 --- a/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart +++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart @@ -50,6 +50,7 @@ class GoogleMap extends StatefulWidget { this.polylines, this.circles, this.onCameraMoveStarted, + this.tileOverlays, this.onCameraMove, this.onCameraIdle, this.onTap, @@ -120,6 +121,9 @@ class GoogleMap extends StatefulWidget { /// Circles to be placed on the map. final Set circles; + /// Tile overlays to be placed on the map. + final Set tileOverlays; + /// Called when the camera starts moving. /// /// This can be initiated by the following: @@ -232,6 +236,7 @@ class _GoogleMapState extends State { 'polylinesToAdd': serializePolylineSet(widget.polylines), 'circlesToAdd': serializeCircleSet(widget.circles), '_webOnlyMapCreationId': _webOnlyMapCreationId, + 'tileOverlaysToAdd': serializeTileOverlaySet(widget.tileOverlays), }; return _googleMapsFlutterPlatform.buildView( @@ -266,6 +271,7 @@ class _GoogleMapState extends State { _updatePolygons(); _updatePolylines(); _updateCircles(); + _updateTileOverlays(); } void _updateOptions() async { @@ -313,6 +319,12 @@ class _GoogleMapState extends State { _circles = keyByCircleId(widget.circles); } + void _updateTileOverlays() async { + final GoogleMapController controller = await _controller.future; + // ignore: unawaited_futures + controller._updateTileOverlays(widget.tileOverlays); + } + Future onPlatformViewCreated(int id) async { final GoogleMapController controller = await GoogleMapController.init( id, @@ -320,6 +332,7 @@ class _GoogleMapState extends State { this, ); _controller.complete(controller); + _updateTileOverlays(); if (widget.onMapCreated != null) { widget.onMapCreated(controller); } diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index ef3a06f5862c..be5c0d449806 100644 --- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml @@ -7,7 +7,7 @@ dependencies: flutter: sdk: flutter flutter_plugin_android_lifecycle: ^1.0.0 - google_maps_flutter_platform_interface: ^1.1.0 + google_maps_flutter_platform_interface: ^1.2.0 dev_dependencies: flutter_test: diff --git a/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart b/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart index 9a849bd94e70..d72ac2ebe656 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart @@ -19,6 +19,7 @@ class FakePlatformGoogleMap { updatePolygons(params); updatePolylines(params); updateCircles(params); + updateTileOverlays(Map.castFrom(params)); } MethodChannel channel; @@ -83,6 +84,12 @@ class FakePlatformGoogleMap { Set circlesToChange; + Set tileOverlayIdsToRemove; + + Set tileOverlaysToAdd; + + Set tileOverlaysToChange; + Future onMethodCall(MethodCall call) { switch (call.method) { case 'map#update': @@ -97,6 +104,10 @@ class FakePlatformGoogleMap { case 'polylines#update': updatePolylines(call.arguments); return Future.sync(() {}); + case 'tileOverlays#update': + updateTileOverlays( + Map.castFrom(call.arguments)); + return Future.sync(() {}); case 'circles#update': updateCircles(call.arguments); return Future.sync(() {}); @@ -292,6 +303,31 @@ class FakePlatformGoogleMap { circlesToChange = _deserializeCircles(circleUpdates['circlesToChange']); } + void updateTileOverlays(Map updateTileOverlayUpdates) { + if (updateTileOverlayUpdates == null) { + return; + } + final List> tileOverlaysToAddList = + updateTileOverlayUpdates['tileOverlaysToAdd'] != null + ? List.castFrom>( + updateTileOverlayUpdates['tileOverlaysToAdd']) + : null; + final List tileOverlayIdsToRemoveList = + updateTileOverlayUpdates['tileOverlayIdsToRemove'] != null + ? List.castFrom( + updateTileOverlayUpdates['tileOverlayIdsToRemove']) + : null; + final List> tileOverlaysToChangeList = + updateTileOverlayUpdates['tileOverlaysToChange'] != null + ? List.castFrom>( + updateTileOverlayUpdates['tileOverlaysToChange']) + : null; + tileOverlaysToAdd = _deserializeTileOverlays(tileOverlaysToAddList); + tileOverlayIdsToRemove = + _deserializeTileOverlayIds(tileOverlayIdsToRemoveList); + tileOverlaysToChange = _deserializeTileOverlays(tileOverlaysToChangeList); + } + Set _deserializeCircleIds(List circleIds) { if (circleIds == null) { // TODO(iskakaushik): Remove this when collection literals makes it to stable. @@ -329,6 +365,49 @@ class FakePlatformGoogleMap { return result; } + Set _deserializeTileOverlayIds(List tileOverlayIds) { + if (tileOverlayIds == null || tileOverlayIds.isEmpty) { + // TODO(iskakaushik): Remove this when collection literals makes it to stable. + // https://github.com/flutter/flutter/issues/28312 + // ignore: prefer_collection_literals + return Set(); + } + return tileOverlayIds + .map((String tileOverlayId) => TileOverlayId(tileOverlayId)) + .toSet(); + } + + Set _deserializeTileOverlays( + List> tileOverlays) { + if (tileOverlays == null || tileOverlays.isEmpty) { + // TODO(iskakaushik): Remove this when collection literals makes it to stable. + // https://github.com/flutter/flutter/issues/28312 + // ignore: prefer_collection_literals + return Set(); + } + // TODO(iskakaushik): Remove this when collection literals makes it to stable. + // https://github.com/flutter/flutter/issues/28312 + // ignore: prefer_collection_literals + final Set result = Set(); + for (Map tileOverlayData in tileOverlays) { + final String tileOverlayId = tileOverlayData['tileOverlayId']; + final bool fadeIn = tileOverlayData['fadeIn']; + final double transparency = tileOverlayData['transparency']; + final int zIndex = tileOverlayData['zIndex']; + final bool visible = tileOverlayData['visible']; + + result.add(TileOverlay( + tileOverlayId: TileOverlayId(tileOverlayId), + fadeIn: fadeIn, + transparency: transparency, + zIndex: zIndex, + visible: visible, + )); + } + + return result; + } + void updateOptions(Map options) { if (options.containsKey('compassEnabled')) { compassEnabled = options['compassEnabled']; diff --git a/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart new file mode 100644 index 000000000000..b94d4906dec7 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart @@ -0,0 +1,210 @@ +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; + +import 'fake_maps_controllers.dart'; + +Set _toSet({TileOverlay t1, TileOverlay t2, TileOverlay t3}) { + final Set res = Set.identity(); + if (t1 != null) { + res.add(t1); + } + if (t2 != null) { + res.add(t2); + } + if (t3 != null) { + res.add(t3); + } + return res; +} + +Widget _mapWithTileOverlays(Set tileOverlays) { + return Directionality( + textDirection: TextDirection.ltr, + child: GoogleMap( + initialCameraPosition: const CameraPosition(target: LatLng(10.0, 15.0)), + tileOverlays: tileOverlays, + ), + ); +} + +void main() { + final FakePlatformViewsController fakePlatformViewsController = + FakePlatformViewsController(); + + setUpAll(() { + SystemChannels.platform_views.setMockMethodCallHandler( + fakePlatformViewsController.fakePlatformViewsMethodHandler); + }); + + setUp(() { + fakePlatformViewsController.reset(); + }); + + testWidgets('Initializing a tile overlay', (WidgetTester tester) async { + final TileOverlay t1 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_1")); + await tester.pumpWidget(_mapWithTileOverlays(_toSet(t1: t1))); + + final FakePlatformGoogleMap platformGoogleMap = + fakePlatformViewsController.lastCreatedView; + expect(platformGoogleMap.tileOverlaysToAdd.length, 1); + + final TileOverlay initializedTileOverlay = + platformGoogleMap.tileOverlaysToAdd.first; + expect(initializedTileOverlay, equals(t1)); + expect(platformGoogleMap.tileOverlayIdsToRemove.isEmpty, true); + expect(platformGoogleMap.tileOverlaysToChange.isEmpty, true); + }); + + testWidgets("Adding a tile overlay", (WidgetTester tester) async { + final TileOverlay t1 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_1")); + final TileOverlay t2 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_2")); + + await tester.pumpWidget(_mapWithTileOverlays(_toSet(t1: t1))); + await tester.pumpWidget(_mapWithTileOverlays(_toSet(t1: t1, t2: t2))); + + final FakePlatformGoogleMap platformGoogleMap = + fakePlatformViewsController.lastCreatedView; + expect(platformGoogleMap.tileOverlaysToAdd.length, 1); + + final TileOverlay addedTileOverlay = + platformGoogleMap.tileOverlaysToAdd.first; + expect(addedTileOverlay, equals(t2)); + expect(platformGoogleMap.tileOverlayIdsToRemove.isEmpty, true); + + expect(platformGoogleMap.tileOverlaysToChange.isEmpty, true); + }); + + testWidgets("Removing a tile overlay", (WidgetTester tester) async { + final TileOverlay t1 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_1")); + + await tester.pumpWidget(_mapWithTileOverlays(_toSet(t1: t1))); + await tester.pumpWidget(_mapWithTileOverlays(null)); + + final FakePlatformGoogleMap platformGoogleMap = + fakePlatformViewsController.lastCreatedView; + expect(platformGoogleMap.tileOverlayIdsToRemove.length, 1); + expect(platformGoogleMap.tileOverlayIdsToRemove.first, + equals(t1.tileOverlayId)); + + expect(platformGoogleMap.tileOverlaysToChange.isEmpty, true); + expect(platformGoogleMap.tileOverlaysToAdd.isEmpty, true); + }); + + testWidgets("Updating a tile overlay", (WidgetTester tester) async { + final TileOverlay t1 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_1")); + final TileOverlay t2 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_1"), zIndex: 10); + + await tester.pumpWidget(_mapWithTileOverlays(_toSet(t1: t1))); + await tester.pumpWidget(_mapWithTileOverlays(_toSet(t1: t2))); + + final FakePlatformGoogleMap platformGoogleMap = + fakePlatformViewsController.lastCreatedView; + expect(platformGoogleMap.tileOverlaysToChange.length, 1); + expect(platformGoogleMap.tileOverlaysToChange.first, equals(t2)); + + expect(platformGoogleMap.tileOverlayIdsToRemove.isEmpty, true); + expect(platformGoogleMap.tileOverlaysToAdd.isEmpty, true); + }); + + testWidgets("Updating a tile overlay", (WidgetTester tester) async { + final TileOverlay t1 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_1")); + final TileOverlay t2 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_1"), zIndex: 10); + + await tester.pumpWidget(_mapWithTileOverlays(_toSet(t1: t1))); + await tester.pumpWidget(_mapWithTileOverlays(_toSet(t1: t2))); + + final FakePlatformGoogleMap platformGoogleMap = + fakePlatformViewsController.lastCreatedView; + expect(platformGoogleMap.tileOverlaysToChange.length, 1); + + final TileOverlay update = platformGoogleMap.tileOverlaysToChange.first; + expect(update, equals(t2)); + expect(update.zIndex, 10); + }); + + testWidgets("Multi Update", (WidgetTester tester) async { + TileOverlay t1 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_1")); + TileOverlay t2 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_2")); + final Set prev = _toSet(t1: t1, t2: t2); + t1 = TileOverlay( + tileOverlayId: TileOverlayId("tile_overlay_1"), visible: false); + t2 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_2"), zIndex: 10); + final Set cur = _toSet(t1: t1, t2: t2); + + await tester.pumpWidget(_mapWithTileOverlays(prev)); + await tester.pumpWidget(_mapWithTileOverlays(cur)); + + final FakePlatformGoogleMap platformGoogleMap = + fakePlatformViewsController.lastCreatedView; + + expect(platformGoogleMap.tileOverlaysToChange, cur); + expect(platformGoogleMap.tileOverlayIdsToRemove.isEmpty, true); + expect(platformGoogleMap.tileOverlaysToAdd.isEmpty, true); + }); + + testWidgets("Multi Update", (WidgetTester tester) async { + TileOverlay t2 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_2")); + final TileOverlay t3 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_3")); + final Set prev = _toSet(t2: t2, t3: t3); + + // t1 is added, t2 is updated, t3 is removed. + final TileOverlay t1 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_1")); + t2 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_2"), zIndex: 10); + final Set cur = _toSet(t1: t1, t2: t2); + + await tester.pumpWidget(_mapWithTileOverlays(prev)); + await tester.pumpWidget(_mapWithTileOverlays(cur)); + + final FakePlatformGoogleMap platformGoogleMap = + fakePlatformViewsController.lastCreatedView; + + expect(platformGoogleMap.tileOverlaysToChange.length, 1); + expect(platformGoogleMap.tileOverlaysToAdd.length, 1); + expect(platformGoogleMap.tileOverlayIdsToRemove.length, 1); + + expect(platformGoogleMap.tileOverlaysToChange.first, equals(t2)); + expect(platformGoogleMap.tileOverlaysToAdd.first, equals(t1)); + expect(platformGoogleMap.tileOverlayIdsToRemove.first, + equals(t3.tileOverlayId)); + }); + + testWidgets("Partial Update", (WidgetTester tester) async { + final TileOverlay t1 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_1")); + final TileOverlay t2 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_2")); + TileOverlay t3 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_3")); + final Set prev = _toSet(t1: t1, t2: t2, t3: t3); + t3 = + TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_3"), zIndex: 10); + final Set cur = _toSet(t1: t1, t2: t2, t3: t3); + + await tester.pumpWidget(_mapWithTileOverlays(prev)); + await tester.pumpWidget(_mapWithTileOverlays(cur)); + + final FakePlatformGoogleMap platformGoogleMap = + fakePlatformViewsController.lastCreatedView; + + expect(platformGoogleMap.tileOverlaysToChange, _toSet(t3: t3)); + expect(platformGoogleMap.tileOverlayIdsToRemove.isEmpty, true); + expect(platformGoogleMap.tileOverlaysToAdd.isEmpty, true); + }); +} From 956b1ebb2418a2314a25550a6a4c418c6f8ee86e Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Wed, 3 Feb 2021 16:34:37 -0800 Subject: [PATCH 0089/1565] Merge upcoming camera updates (#3501) --- packages/camera/camera/CHANGELOG.md | 5 +---- packages/camera/camera/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 911d7a1e9920..a8dbe65e7453 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,10 +1,7 @@ -# 0.7.0+3 - -* Revert compileSdkVersion back to 29 (from 30) as this is causing problems with add-to-app configurations. - ## 0.7.0+2 * Fix example reference in README. +* Revert compileSdkVersion back to 29 (from 30) as this is causing problems with add-to-app configurations. ## 0.7.0+1 diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index cebbb334c8f2..2b6d163dfbeb 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.7.0+3 +version: 0.7.0+2 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From 41be560b958f8fe1fabe1124b168cd0813cbc4f3 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Thu, 4 Feb 2021 04:18:58 -0800 Subject: [PATCH 0090/1565] [shared_preferences] Update macOS for NNBD (#3505) macOS federated plugin implementations that contain no Dart code just need their Dart SDK bumped in order to be considered nullsafe. --- .../shared_preferences_macos/CHANGELOG.md | 4 ++++ .../shared_preferences_macos/pubspec.yaml | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_macos/CHANGELOG.md b/packages/shared_preferences/shared_preferences_macos/CHANGELOG.md index 3eff6db6949e..ec5c5b4bc502 100644 --- a/packages/shared_preferences/shared_preferences_macos/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_macos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.2-nullsafety + +* Update Dart SDK constraint for null safety. + ## 0.0.1+12 * Update Flutter SDK constraint. diff --git a/packages/shared_preferences/shared_preferences_macos/pubspec.yaml b/packages/shared_preferences/shared_preferences_macos/pubspec.yaml index afc5b9ec0b4e..912e2f648a26 100644 --- a/packages/shared_preferences/shared_preferences_macos/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_macos/pubspec.yaml @@ -3,7 +3,7 @@ description: macOS implementation of the shared_preferences plugin. # 0.0.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.0.1+12 +version: 0.0.2-nullsafety homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_macos flutter: @@ -13,11 +13,11 @@ flutter: pluginClass: SharedPreferencesPlugin environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.12.8" dependencies: - shared_preferences_platform_interface: ^1.0.0 + shared_preferences_platform_interface: ^2.0.0-nullsafety flutter: sdk: flutter dev_dependencies: From e51dd6723b0638ad050b332db929a7f40dc184fc Mon Sep 17 00:00:00 2001 From: Emmanuel Garcia Date: Thu, 4 Feb 2021 08:52:58 -0800 Subject: [PATCH 0091/1565] Clean up CODEOWNERS (#3438) --- CODEOWNERS | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index bd774ebe4315..01732888ad89 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -4,23 +4,12 @@ # These names are just suggestions. It is fine to have your changes # reviewed by someone else. -packages/android_alarm_manager/** @bkonyi -packages/android_intent/** @mklim @matthew-carroll -packages/battery/** @matthew-carroll + packages/camera/** @bparrishMines -packages/connectivity/** @matthew-carroll packages/cross_file/** @ditman @mvanbeusekom -packages/device_info/** @matthew-carroll -packages/espresso/** @collinjackson @adazh packages/file_selector/** @ditman packages/google_maps_flutter/** @cyanglaz -packages/google_sign_in/** @mehmetf packages/image_picker/** @cyanglaz packages/integration_test/** @dnfield -packages/in_app_purchase/** @mklim @cyanglaz @LHLL +packages/in_app_purchase/** @cyanglaz @LHLL packages/ios_platform_images/** @gaaclarke -packages/package_info/** @matthew-carroll -packages/path_provider/** @matthew-carroll -packages/shared_preferences/** @matthew-carroll -packages/url_launcher/** @mklim -packages/video_player/** @iskakaushik From 546d6c10377a338d2f0504ab664209ed7db111c6 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Thu, 4 Feb 2021 11:36:04 -0800 Subject: [PATCH 0092/1565] update versino (#3512) --- packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md | 4 ++++ packages/google_maps_flutter/google_maps_flutter/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index 3b6db09ea10b..fd73ad6ca0eb 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.2.0 + +* Support custom tiles. + ## 1.1.1 * Fix in example app to properly place polyline at initial camera position. diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index be5c0d449806..20bd56ab57da 100644 --- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: google_maps_flutter description: A Flutter plugin for integrating Google Maps in iOS and Android applications. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter -version: 1.1.1 +version: 1.2.0 dependencies: flutter: From 342d0109e9861b7b413d03e3cc0c29a120213c06 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Thu, 4 Feb 2021 12:11:51 -0800 Subject: [PATCH 0093/1565] Add a note about Plus plugins to CONTRIBUTING.md (#3511) Adds a prominent note to CONTRIBUTING.md about the new policy regarding PRs for plugins for which there is a Flutter Community Plus Plugins equivalent. --- CONTRIBUTING.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b763320b67c9..6c4abd0cb516 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,6 +5,25 @@ _See also: [Flutter's code of conduct](https://github.com/flutter/flutter/blob/master/CODE_OF_CONDUCT.md)_ +## Important note + +As of January 2021, we are no longer accepting non-critical PRs for plugins +for which there is a corresponding [Flutter Community Plus +Plugin](https://plus.fluttercommunity.dev/), as we hope in time to be able +to transition users to those versions of the plugins. If you have a PR for +something other than a critical issue (crashes, build failures, null safety, etc.) +for any of the following plugins, we encourage you to submit it +[there](https://github.com/fluttercommunity/plus_plugins/pulls) instead: +- `android_alarm_manager` +- `android_intent` +- `battery` +- `connectivity` +- `device_info` +- `package_info` +- `sensors` +- `share` +- `wifi_info_flutter` (corresponds to `network_info_plus`) + ## Things you will need From caf7fbf0b6185f7ff91a3c70e66228bc0b26e958 Mon Sep 17 00:00:00 2001 From: Kate Lovett Date: Thu, 4 Feb 2021 15:51:19 -0600 Subject: [PATCH 0094/1565] [in_app_purchases] Remove TypeMatcher reference (#3494) --- packages/in_app_purchase/CHANGELOG.md | 4 ++++ packages/in_app_purchase/pubspec.yaml | 2 +- .../google_play_connection_test.dart | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/CHANGELOG.md index 3c77e0c313f5..abafaf506f3a 100644 --- a/packages/in_app_purchase/CHANGELOG.md +++ b/packages/in_app_purchase/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.5+2 + +* Migrate deprecated references. + ## 0.3.5+1 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. diff --git a/packages/in_app_purchase/pubspec.yaml b/packages/in_app_purchase/pubspec.yaml index 02240ea654db..6a6c525132da 100644 --- a/packages/in_app_purchase/pubspec.yaml +++ b/packages/in_app_purchase/pubspec.yaml @@ -1,7 +1,7 @@ name: in_app_purchase description: A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases through the App Store and Google Play. homepage: https://github.com/flutter/plugins/tree/master/packages/in_app_purchase -version: 0.3.5+1 +version: 0.3.5+2 dependencies: async: ^2.0.8 diff --git a/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart b/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart index f06c4ff7efef..9294d2b60d1e 100644 --- a/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart +++ b/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart @@ -9,7 +9,7 @@ import 'package:flutter_test/flutter_test.dart' show TestWidgetsFlutterBinding; import 'package:in_app_purchase/src/in_app_purchase/purchase_details.dart'; import 'package:test/test.dart'; -import 'package:flutter/widgets.dart' hide TypeMatcher; +import 'package:flutter/widgets.dart' as widgets; import 'package:in_app_purchase/billing_client_wrappers.dart'; import 'package:in_app_purchase/src/billing_client_wrappers/enum_converters.dart'; import 'package:in_app_purchase/src/in_app_purchase/google_play_connection.dart'; @@ -34,7 +34,7 @@ void main() { }); setUp(() { - WidgetsFlutterBinding.ensureInitialized(); + widgets.WidgetsFlutterBinding.ensureInitialized(); const String debugMessage = 'dummy message'; final BillingResponse responseCode = BillingResponse.ok; final BillingResultWrapper expectedBillingResult = BillingResultWrapper( From 7301aa1e25b271b362ae5302f54c3fdf4c16843f Mon Sep 17 00:00:00 2001 From: Tim Sneath Date: Thu, 4 Feb 2021 13:57:13 -0800 Subject: [PATCH 0095/1565] Remove stray dependency (#3515) --- .../shared_preferences_windows/CHANGELOG.md | 4 ++++ .../shared_preferences_windows/pubspec.yaml | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md b/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md index f6a199d52cb0..a8c3a85cd3ce 100644 --- a/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.2+3 + +* Remove 'ffi' dependency. + ## 0.0.2+2 * Relax 'ffi' version constraint. diff --git a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml index 2970b3ff053e..6123300c9689 100644 --- a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml @@ -1,7 +1,7 @@ name: shared_preferences_windows description: Windows implementation of shared_preferences homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_windows -version: 0.0.2+2 +version: 0.0.2+3 flutter: plugin: @@ -18,7 +18,6 @@ dependencies: shared_preferences_platform_interface: ^1.0.0 flutter: sdk: flutter - ffi: ">=0.1.3 < 0.3.0" file: ">=5.1.0 <7.0.0" meta: ^1.1.7 path: ^1.6.4 From 9e982cf959979098634aee2f5780bc6377e5b2ba Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Thu, 4 Feb 2021 14:01:06 -0800 Subject: [PATCH 0096/1565] [image_picker_platform_interface] migrate to nnbd (#3492) --- .../CHANGELOG.md | 7 + .../method_channel_image_picker.dart | 89 ++--- .../image_picker_platform.dart | 95 +---- .../lib/src/types/lost_data_response.dart | 52 --- .../lib/src/types/picked_file/base.dart | 2 +- .../lib/src/types/picked_file/html.dart | 8 +- .../lib/src/types/picked_file/io.dart | 2 +- .../lib/src/types/picked_file/lost_data.dart | 8 +- .../lib/src/types/types.dart | 1 - .../pubspec.yaml | 13 +- .../method_channel_image_picker_test.dart | 345 ------------------ .../new_method_channel_image_picker_test.dart | 8 +- .../test/picked_file_html_test.dart | 3 +- script/build_all_plugins_app.sh | 1 + script/nnbd_plugins.sh | 1 + 15 files changed, 68 insertions(+), 567 deletions(-) delete mode 100644 packages/image_picker/image_picker_platform_interface/lib/src/types/lost_data_response.dart delete mode 100644 packages/image_picker/image_picker_platform_interface/test/method_channel_image_picker_test.dart diff --git a/packages/image_picker/image_picker_platform_interface/CHANGELOG.md b/packages/image_picker/image_picker_platform_interface/CHANGELOG.md index 581cf1830610..fc953e4e6333 100644 --- a/packages/image_picker/image_picker_platform_interface/CHANGELOG.md +++ b/packages/image_picker/image_picker_platform_interface/CHANGELOG.md @@ -1,3 +1,10 @@ +## 2.0.0-nullsafety + +* Migrate to null safety. +* Breaking Changes: + * Removed the deprecated methods: `ImagePickerPlatform.retrieveLostDataAsDartIoFile`,`ImagePickerPlatform.pickImagePath` and `ImagePickerPlatform.pickVideoPath`. + * Removed deprecated class: `LostDataResponse`. + ## 1.1.6 * Fix test asset file location. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/method_channel/method_channel_image_picker.dart b/packages/image_picker/image_picker_platform_interface/lib/src/method_channel/method_channel_image_picker.dart index 71704b63ced4..8535f9dfb20e 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/method_channel/method_channel_image_picker.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/method_channel/method_channel_image_picker.dart @@ -3,11 +3,10 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; -import 'package:meta/meta.dart' show required, visibleForTesting; +import 'package:meta/meta.dart' show visibleForTesting; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; @@ -20,14 +19,14 @@ class MethodChannelImagePicker extends ImagePickerPlatform { MethodChannel get channel => _channel; @override - Future pickImage({ - @required ImageSource source, - double maxWidth, - double maxHeight, - int imageQuality, + Future pickImage({ + required ImageSource source, + double? maxWidth, + double? maxHeight, + int? imageQuality, CameraDevice preferredCameraDevice = CameraDevice.rear, }) async { - String path = await pickImagePath( + String? path = await _pickImagePath( source: source, maxWidth: maxWidth, maxHeight: maxHeight, @@ -37,15 +36,13 @@ class MethodChannelImagePicker extends ImagePickerPlatform { return path != null ? PickedFile(path) : null; } - @override - Future pickImagePath({ - @required ImageSource source, - double maxWidth, - double maxHeight, - int imageQuality, + Future _pickImagePath({ + required ImageSource source, + double? maxWidth, + double? maxHeight, + int? imageQuality, CameraDevice preferredCameraDevice = CameraDevice.rear, }) { - assert(source != null); if (imageQuality != null && (imageQuality < 0 || imageQuality > 100)) { throw ArgumentError.value( imageQuality, 'imageQuality', 'must be between 0 and 100'); @@ -72,12 +69,12 @@ class MethodChannelImagePicker extends ImagePickerPlatform { } @override - Future pickVideo({ - @required ImageSource source, + Future pickVideo({ + required ImageSource source, CameraDevice preferredCameraDevice = CameraDevice.rear, - Duration maxDuration, + Duration? maxDuration, }) async { - String path = await pickVideoPath( + String? path = await _pickVideoPath( source: source, maxDuration: maxDuration, preferredCameraDevice: preferredCameraDevice, @@ -85,13 +82,11 @@ class MethodChannelImagePicker extends ImagePickerPlatform { return path != null ? PickedFile(path) : null; } - @override - Future pickVideoPath({ - @required ImageSource source, + Future _pickVideoPath({ + required ImageSource source, CameraDevice preferredCameraDevice = CameraDevice.rear, - Duration maxDuration, + Duration? maxDuration, }) { - assert(source != null); return _channel.invokeMethod( 'pickVideo', { @@ -104,7 +99,7 @@ class MethodChannelImagePicker extends ImagePickerPlatform { @override Future retrieveLostData() async { - final Map result = + final Map? result = await _channel.invokeMapMethod('retrieve'); if (result == null) { @@ -113,23 +108,23 @@ class MethodChannelImagePicker extends ImagePickerPlatform { assert(result.containsKey('path') ^ result.containsKey('errorCode')); - final String type = result['type']; + final String? type = result['type']; assert(type == kTypeImage || type == kTypeVideo); - RetrieveType retrieveType; + RetrieveType? retrieveType; if (type == kTypeImage) { retrieveType = RetrieveType.image; } else if (type == kTypeVideo) { retrieveType = RetrieveType.video; } - PlatformException exception; + PlatformException? exception; if (result.containsKey('errorCode')) { exception = PlatformException( code: result['errorCode'], message: result['errorMessage']); } - final String path = result['path']; + final String? path = result['path']; return LostData( file: path != null ? PickedFile(path) : null, @@ -137,40 +132,4 @@ class MethodChannelImagePicker extends ImagePickerPlatform { type: retrieveType, ); } - - @override - // ignore: deprecated_member_use_from_same_package - Future retrieveLostDataAsDartIoFile() async { - final Map result = - await _channel.invokeMapMethod('retrieve'); - if (result == null) { - // ignore: deprecated_member_use_from_same_package - return LostDataResponse.empty(); - } - assert(result.containsKey('path') ^ result.containsKey('errorCode')); - - final String type = result['type']; - assert(type == kTypeImage || type == kTypeVideo); - - RetrieveType retrieveType; - if (type == kTypeImage) { - retrieveType = RetrieveType.image; - } else if (type == kTypeVideo) { - retrieveType = RetrieveType.video; - } - - PlatformException exception; - if (result.containsKey('errorCode')) { - exception = PlatformException( - code: result['errorCode'], message: result['errorMessage']); - } - - final String path = result['path']; - - // ignore: deprecated_member_use_from_same_package - return LostDataResponse( - file: path == null ? null : File(path), - exception: exception, - type: retrieveType); - } } diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/platform_interface/image_picker_platform.dart b/packages/image_picker/image_picker_platform_interface/lib/src/platform_interface/image_picker_platform.dart index cbd604187714..44b85f17f3db 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/platform_interface/image_picker_platform.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/platform_interface/image_picker_platform.dart @@ -4,7 +4,6 @@ import 'dart:async'; -import 'package:meta/meta.dart' show required; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'package:image_picker_platform_interface/src/method_channel/method_channel_image_picker.dart'; @@ -39,80 +38,6 @@ abstract class ImagePickerPlatform extends PlatformInterface { _instance = instance; } - /// Returns a [String] containing a path to the image that was picked. - /// - /// The `source` argument controls where the image comes from. This can - /// be either [ImageSource.camera] or [ImageSource.gallery]. - /// - /// If specified, the image will be at most `maxWidth` wide and - /// `maxHeight` tall. Otherwise the image will be returned at it's - /// original width and height. - /// - /// The `imageQuality` argument modifies the quality of the image, ranging from 0-100 - /// where 100 is the original/max quality. If `imageQuality` is null, the image with - /// the original quality will be returned. Compression is only supported for certain - /// image types such as JPEG and on Android PNG and WebP, too. If compression is not supported for the image that is picked, - /// a warning message will be logged. - /// - /// Use `preferredCameraDevice` to specify the camera to use when the `source` is [ImageSource.camera]. - /// The `preferredCameraDevice` is ignored when `source` is [ImageSource.gallery]. It is also ignored if the chosen camera is not supported on the device. - /// Defaults to [CameraDevice.rear]. - /// - /// In Android, the MainActivity can be destroyed for various reasons. If that happens, the result will be lost - /// in this call. You can then call [retrieveLostDataAsDartIoFile] when your app relaunches to retrieve the lost data. - @Deprecated('Use pickImage instead.') - Future pickImagePath({ - @required ImageSource source, - double maxWidth, - double maxHeight, - int imageQuality, - CameraDevice preferredCameraDevice = CameraDevice.rear, - }) { - throw UnimplementedError('legacyPickImage() has not been implemented.'); - } - - /// Returns a [String] containing a path to the video that was picked. - /// - /// The [source] argument controls where the video comes from. This can - /// be either [ImageSource.camera] or [ImageSource.gallery]. - /// - /// The [maxDuration] argument specifies the maximum duration of the captured video. If no [maxDuration] is specified, - /// the maximum duration will be infinite. - /// - /// Use `preferredCameraDevice` to specify the camera to use when the `source` is [ImageSource.camera]. - /// The `preferredCameraDevice` is ignored when `source` is [ImageSource.gallery]. It is also ignored if the chosen camera is not supported on the device. - /// Defaults to [CameraDevice.rear]. - /// - /// In Android, the MainActivity can be destroyed for various fo reasons. If that happens, the result will be lost - /// in this call. You can then call [retrieveLostDataAsDartIoFile] when your app relaunches to retrieve the lost data. - @Deprecated('Use pickVideo instead.') - Future pickVideoPath({ - @required ImageSource source, - CameraDevice preferredCameraDevice = CameraDevice.rear, - Duration maxDuration, - }) { - throw UnimplementedError('pickVideoPath() has not been implemented.'); - } - - /// Retrieve the lost image file when [pickImagePath] or [pickVideoPath] failed because the MainActivity is destroyed. (Android only) - /// - /// Image or video can be lost if the MainActivity is destroyed. And there is no guarantee that the MainActivity is always alive. - /// Call this method to retrieve the lost data and process the data according to your APP's business logic. - /// - /// Returns a [LostDataResponse] if successfully retrieved the lost data. The [LostDataResponse] can represent either a - /// successful image/video selection, or a failure. - /// - /// Calling this on a non-Android platform will throw [UnimplementedError] exception. - /// - /// See also: - /// * [LostDataResponse], for what's included in the response. - /// * [Android Activity Lifecycle](https://developer.android.com/reference/android/app/Activity.html), for more information on MainActivity destruction. - @Deprecated('Use retrieveLostData instead.') - Future retrieveLostDataAsDartIoFile() { - throw UnimplementedError( - 'retrieveLostDataAsDartIoFile() has not been implemented.'); - } - // Next version of the API. /// Returns a [PickedFile] with the image that was picked. @@ -141,11 +66,13 @@ abstract class ImagePickerPlatform extends PlatformInterface { /// /// In Android, the MainActivity can be destroyed for various reasons. If that happens, the result will be lost /// in this call. You can then call [retrieveLostData] when your app relaunches to retrieve the lost data. - Future pickImage({ - @required ImageSource source, - double maxWidth, - double maxHeight, - int imageQuality, + /// + /// If no images were picked, the return value is null. + Future pickImage({ + required ImageSource source, + double? maxWidth, + double? maxHeight, + int? imageQuality, CameraDevice preferredCameraDevice = CameraDevice.rear, }) { throw UnimplementedError('pickImage() has not been implemented.'); @@ -165,10 +92,12 @@ abstract class ImagePickerPlatform extends PlatformInterface { /// /// In Android, the MainActivity can be destroyed for various fo reasons. If that happens, the result will be lost /// in this call. You can then call [retrieveLostData] when your app relaunches to retrieve the lost data. - Future pickVideo({ - @required ImageSource source, + /// + /// If no images were picked, the return value is null. + Future pickVideo({ + required ImageSource source, CameraDevice preferredCameraDevice = CameraDevice.rear, - Duration maxDuration, + Duration? maxDuration, }) { throw UnimplementedError('pickVideo() has not been implemented.'); } diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/lost_data_response.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/lost_data_response.dart deleted file mode 100644 index d82618b23cd1..000000000000 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/lost_data_response.dart +++ /dev/null @@ -1,52 +0,0 @@ -// 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. - -import 'dart:io'; - -import 'package:flutter/services.dart'; -import 'package:image_picker_platform_interface/src/types/types.dart'; - -/// The response object of [ImagePicker.retrieveLostData]. -/// -/// Only applies to Android. -/// See also: -/// * [ImagePicker.retrieveLostData] for more details on retrieving lost data. -@Deprecated('Use methods that return a LostData object instead.') -class LostDataResponse { - /// Creates an instance with the given [file], [exception], and [type]. Any of - /// the params may be null, but this is never considered to be empty. - LostDataResponse({this.file, this.exception, this.type}); - - /// Initializes an instance with all member params set to null and considered - /// to be empty. - LostDataResponse.empty() - : file = null, - exception = null, - type = null, - _empty = true; - - /// Whether it is an empty response. - /// - /// An empty response should have [file], [exception] and [type] to be null. - bool get isEmpty => _empty; - - /// The file that was lost in a previous [pickImage] or [pickVideo] call due to MainActivity being destroyed. - /// - /// Can be null if [exception] exists. - final File file; - - /// The exception of the last [pickImage] or [pickVideo]. - /// - /// If the last [pickImage] or [pickVideo] threw some exception before the MainActivity destruction, this variable keeps that - /// exception. - /// You should handle this exception as if the [pickImage] or [pickVideo] got an exception when the MainActivity was not destroyed. - /// - /// Note that it is not the exception that caused the destruction of the MainActivity. - final PlatformException exception; - - /// Can either be [RetrieveType.image] or [RetrieveType.video]; - final RetrieveType type; - - bool _empty = false; -} diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart index 285294efcb3d..2b078ef28190 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart @@ -52,7 +52,7 @@ abstract class PickedFileBase { /// If `end` is present, only up to byte-index `end` will be read. Otherwise, until end of file. /// /// In order to make sure that system resources are freed, the stream must be read to completion or the subscription on the stream must be cancelled. - Stream openRead([int start, int end]) { + Stream openRead([int? start, int? end]) { throw UnimplementedError('openRead() has not been implemented.'); } } diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart index ee5145009dc7..b855eb3fa20d 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart @@ -10,19 +10,19 @@ import './base.dart'; /// It wraps the bytes of a selected file. class PickedFile extends PickedFileBase { final String path; - final Uint8List _initBytes; + final Uint8List? _initBytes; /// Construct a PickedFile object from its ObjectUrl. /// /// Optionally, this can be initialized with `bytes` /// so no http requests are performed to retrieve files later. - PickedFile(this.path, {Uint8List bytes}) + PickedFile(this.path, {Uint8List? bytes}) : _initBytes = bytes, super(path); Future get _bytes async { if (_initBytes != null) { - return Future.value(UnmodifiableUint8ListView(_initBytes)); + return Future.value(UnmodifiableUint8ListView(_initBytes!)); } return http.readBytes(Uri.parse(path)); } @@ -38,7 +38,7 @@ class PickedFile extends PickedFileBase { } @override - Stream openRead([int start, int end]) async* { + Stream openRead([int? start, int? end]) async* { final bytes = await _bytes; yield bytes.sublist(start ?? 0, end ?? bytes.length); } diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart index dd64558bf044..4b56add0add4 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart @@ -29,7 +29,7 @@ class PickedFile extends PickedFileBase { } @override - Stream openRead([int start, int end]) { + Stream openRead([int? start, int? end]) { return _file .openRead(start ?? 0, end) .map((chunk) => Uint8List.fromList(chunk)); diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/lost_data.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/lost_data.dart index b94e69de219e..831c7bd6cb15 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/lost_data.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/lost_data.dart @@ -31,7 +31,7 @@ class LostData { /// The file that was lost in a previous [pickImage] or [pickVideo] call due to MainActivity being destroyed. /// /// Can be null if [exception] exists. - final PickedFile file; + final PickedFile? file; /// The exception of the last [pickImage] or [pickVideo]. /// @@ -40,10 +40,12 @@ class LostData { /// You should handle this exception as if the [pickImage] or [pickVideo] got an exception when the MainActivity was not destroyed. /// /// Note that it is not the exception that caused the destruction of the MainActivity. - final PlatformException exception; + final PlatformException? exception; /// Can either be [RetrieveType.image] or [RetrieveType.video]; - final RetrieveType type; + /// + /// If the lost data is empty, this will be null. + final RetrieveType? type; bool _empty = false; } diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart index 9c44fae1aa9d..f38a4ec74005 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart @@ -1,6 +1,5 @@ export 'camera_device.dart'; export 'image_source.dart'; -export 'lost_data_response.dart'; export 'retrieve_type.dart'; export 'picked_file/picked_file.dart'; diff --git a/packages/image_picker/image_picker_platform_interface/pubspec.yaml b/packages/image_picker/image_picker_platform_interface/pubspec.yaml index b9ad12a50eb6..d5f5ce93016b 100644 --- a/packages/image_picker/image_picker_platform_interface/pubspec.yaml +++ b/packages/image_picker/image_picker_platform_interface/pubspec.yaml @@ -3,21 +3,20 @@ description: A common platform interface for the image_picker plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.1.6 +version: 2.0.0-nullsafety dependencies: flutter: sdk: flutter - meta: ^1.1.8 - http: ^0.12.1 - plugin_platform_interface: ^1.0.2 + meta: ^1.3.0-nullsafety.6 + http: ^0.13.0-nullsafety.0 + plugin_platform_interface: ^1.1.0-nullsafety.2 dev_dependencies: flutter_test: sdk: flutter - mockito: ^4.1.1 - pedantic: ^1.8.0+1 + pedantic: ^1.10.0-nullsafety.3 environment: - sdk: ">=2.5.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.10.0" diff --git a/packages/image_picker/image_picker_platform_interface/test/method_channel_image_picker_test.dart b/packages/image_picker/image_picker_platform_interface/test/method_channel_image_picker_test.dart deleted file mode 100644 index ddaad3d32f41..000000000000 --- a/packages/image_picker/image_picker_platform_interface/test/method_channel_image_picker_test.dart +++ /dev/null @@ -1,345 +0,0 @@ -// Copyright 2019 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/services.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; -import 'package:image_picker_platform_interface/src/method_channel/method_channel_image_picker.dart'; - -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - - group('$MethodChannelImagePicker', () { - MethodChannelImagePicker picker = MethodChannelImagePicker(); - - final List log = []; - - setUp(() { - picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { - log.add(methodCall); - return ''; - }); - - log.clear(); - }); - - group('#pickImagePath', () { - test('passes the image source argument correctly', () async { - await picker.pickImagePath(source: ImageSource.camera); - await picker.pickImagePath(source: ImageSource.gallery); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0 - }), - isMethodCall('pickImage', arguments: { - 'source': 1, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0 - }), - ], - ); - }); - - test('passes the width and height arguments correctly', () async { - await picker.pickImagePath(source: ImageSource.camera); - await picker.pickImagePath( - source: ImageSource.camera, - maxWidth: 10.0, - ); - await picker.pickImagePath( - source: ImageSource.camera, - maxHeight: 10.0, - ); - await picker.pickImagePath( - source: ImageSource.camera, - maxWidth: 10.0, - maxHeight: 20.0, - ); - await picker.pickImagePath( - source: ImageSource.camera, maxWidth: 10.0, imageQuality: 70); - await picker.pickImagePath( - source: ImageSource.camera, maxHeight: 10.0, imageQuality: 70); - await picker.pickImagePath( - source: ImageSource.camera, - maxWidth: 10.0, - maxHeight: 20.0, - imageQuality: 70); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0 - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0 - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': 10.0, - 'imageQuality': null, - 'cameraDevice': 0 - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': 20.0, - 'imageQuality': null, - 'cameraDevice': 0 - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': null, - 'imageQuality': 70, - 'cameraDevice': 0 - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': 10.0, - 'imageQuality': 70, - 'cameraDevice': 0 - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': 20.0, - 'imageQuality': 70, - 'cameraDevice': 0 - }), - ], - ); - }); - - test('does not accept a negative width or height argument', () { - expect( - () => - picker.pickImagePath(source: ImageSource.camera, maxWidth: -1.0), - throwsArgumentError, - ); - - expect( - () => - picker.pickImagePath(source: ImageSource.camera, maxHeight: -1.0), - throwsArgumentError, - ); - }); - - test('handles a null image path response gracefully', () async { - picker.channel - .setMockMethodCallHandler((MethodCall methodCall) => null); - - expect(await picker.pickImagePath(source: ImageSource.gallery), isNull); - expect(await picker.pickImagePath(source: ImageSource.camera), isNull); - }); - - test('camera position defaults to back', () async { - await picker.pickImagePath(source: ImageSource.camera); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0, - }), - ], - ); - }); - - test('camera position can set to front', () async { - await picker.pickImagePath( - source: ImageSource.camera, - preferredCameraDevice: CameraDevice.front); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 1, - }), - ], - ); - }); - }); - - group('#pickVideoPath', () { - test('passes the image source argument correctly', () async { - await picker.pickVideoPath(source: ImageSource.camera); - await picker.pickVideoPath(source: ImageSource.gallery); - - expect( - log, - [ - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'cameraDevice': 0, - 'maxDuration': null, - }), - isMethodCall('pickVideo', arguments: { - 'source': 1, - 'cameraDevice': 0, - 'maxDuration': null, - }), - ], - ); - }); - - test('passes the duration argument correctly', () async { - await picker.pickVideoPath(source: ImageSource.camera); - await picker.pickVideoPath( - source: ImageSource.camera, - maxDuration: const Duration(seconds: 10)); - await picker.pickVideoPath( - source: ImageSource.camera, - maxDuration: const Duration(minutes: 1)); - await picker.pickVideoPath( - source: ImageSource.camera, maxDuration: const Duration(hours: 1)); - expect( - log, - [ - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': null, - 'cameraDevice': 0, - }), - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': 10, - 'cameraDevice': 0, - }), - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': 60, - 'cameraDevice': 0, - }), - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': 3600, - 'cameraDevice': 0, - }), - ], - ); - }); - - test('handles a null video path response gracefully', () async { - picker.channel - .setMockMethodCallHandler((MethodCall methodCall) => null); - - expect(await picker.pickVideoPath(source: ImageSource.gallery), isNull); - expect(await picker.pickVideoPath(source: ImageSource.camera), isNull); - }); - - test('camera position defaults to back', () async { - await picker.pickVideoPath(source: ImageSource.camera); - - expect( - log, - [ - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'cameraDevice': 0, - 'maxDuration': null, - }), - ], - ); - }); - - test('camera position can set to front', () async { - await picker.pickVideoPath( - source: ImageSource.camera, - preferredCameraDevice: CameraDevice.front); - - expect( - log, - [ - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': null, - 'cameraDevice': 1, - }), - ], - ); - }); - }); - - group('#retrieveLostDataAsDartIoFile', () { - test('retrieveLostData get success response', () async { - picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { - return { - 'type': 'image', - 'path': '/example/path', - }; - }); - // ignore: deprecated_member_use_from_same_package - final LostDataResponse response = - await picker.retrieveLostDataAsDartIoFile(); - expect(response.type, RetrieveType.image); - expect(response.file.path, '/example/path'); - }); - - test('retrieveLostData get error response', () async { - picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { - return { - 'type': 'video', - 'errorCode': 'test_error_code', - 'errorMessage': 'test_error_message', - }; - }); - // ignore: deprecated_member_use_from_same_package - final LostDataResponse response = - await picker.retrieveLostDataAsDartIoFile(); - expect(response.type, RetrieveType.video); - expect(response.exception.code, 'test_error_code'); - expect(response.exception.message, 'test_error_message'); - }); - - test('retrieveLostData get null response', () async { - picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { - return null; - }); - expect((await picker.retrieveLostDataAsDartIoFile()).isEmpty, true); - }); - - test('retrieveLostData get both path and error should throw', () async { - picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { - return { - 'type': 'video', - 'errorCode': 'test_error_code', - 'errorMessage': 'test_error_message', - 'path': '/example/path', - }; - }); - expect(picker.retrieveLostDataAsDartIoFile(), throwsAssertionError); - }); - }, skip: isBrowser); - }); -} diff --git a/packages/image_picker/image_picker_platform_interface/test/new_method_channel_image_picker_test.dart b/packages/image_picker/image_picker_platform_interface/test/new_method_channel_image_picker_test.dart index e7abe37e4838..df35f8fd96b8 100644 --- a/packages/image_picker/image_picker_platform_interface/test/new_method_channel_image_picker_test.dart +++ b/packages/image_picker/image_picker_platform_interface/test/new_method_channel_image_picker_test.dart @@ -312,7 +312,8 @@ void main() { // ignore: deprecated_member_use_from_same_package final LostData response = await picker.retrieveLostData(); expect(response.type, RetrieveType.image); - expect(response.file.path, '/example/path'); + expect(response.file, isNotNull); + expect(response.file!.path, '/example/path'); }); test('retrieveLostData get error response', () async { @@ -326,8 +327,9 @@ void main() { // ignore: deprecated_member_use_from_same_package final LostData response = await picker.retrieveLostData(); expect(response.type, RetrieveType.video); - expect(response.exception.code, 'test_error_code'); - expect(response.exception.message, 'test_error_message'); + expect(response.exception, isNotNull); + expect(response.exception!.code, 'test_error_code'); + expect(response.exception!.message, 'test_error_message'); }); test('retrieveLostData get null response', () async { diff --git a/packages/image_picker/image_picker_platform_interface/test/picked_file_html_test.dart b/packages/image_picker/image_picker_platform_interface/test/picked_file_html_test.dart index 49d84ff88f88..ee0edbea03e0 100644 --- a/packages/image_picker/image_picker_platform_interface/test/picked_file_html_test.dart +++ b/packages/image_picker/image_picker_platform_interface/test/picked_file_html_test.dart @@ -6,13 +6,12 @@ import 'dart:convert'; import 'dart:html' as html; -import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; final String expectedStringContents = 'Hello, world!'; -final Uint8List bytes = utf8.encode(expectedStringContents); +final List bytes = utf8.encode(expectedStringContents); final html.File textFile = html.File([bytes], 'hello.txt'); final String textFileUrl = html.Url.createObjectUrl(textFile); diff --git a/script/build_all_plugins_app.sh b/script/build_all_plugins_app.sh index 9d9e38550ed5..7807e6a98bce 100755 --- a/script/build_all_plugins_app.sh +++ b/script/build_all_plugins_app.sh @@ -30,6 +30,7 @@ readonly EXCLUDED_PLUGINS_LIST=( "google_sign_in_platform_interface" "google_sign_in_web" "image_picker_platform_interface" + "image_picker" "instrumentation_adapter" "local_auth" # flutter_plugin_android_lifecycle conflict "path_provider_linux" diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index 3d0676f8b1a5..b43d11c2fe1d 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -21,6 +21,7 @@ readonly NNBD_PLUGINS_LIST=( "url_launcher" "video_player" "webview_flutter" + "image_picker" ) # This list contains the list of plugins that have *not* been From 60fa97998b439924d64b476ac8f2d8129d527c38 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Thu, 4 Feb 2021 15:23:49 -0800 Subject: [PATCH 0097/1565] [package_info] Migrate to null safety (#3398) --- packages/package_info/CHANGELOG.md | 4 ++++ packages/package_info/lib/package_info.dart | 23 ++++++++++--------- packages/package_info/pubspec.yaml | 6 ++--- .../package_info/test/package_info_test.dart | 2 +- script/nnbd_plugins.sh | 1 + 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/packages/package_info/CHANGELOG.md b/packages/package_info/CHANGELOG.md index f3f7734a4082..91da35966283 100644 --- a/packages/package_info/CHANGELOG.md +++ b/packages/package_info/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.0-nullsafety + +* Migrate to null safety. + ## 0.4.3+4 * Ensure `IntegrationTestPlugin` is registered in `example` app, so Firebase Test Lab tests report test results correctly. [Issue](https://github.com/flutter/flutter/issues/74944). diff --git a/packages/package_info/lib/package_info.dart b/packages/package_info/lib/package_info.dart index eaf28597e56c..51348978ffa5 100644 --- a/packages/package_info/lib/package_info.dart +++ b/packages/package_info/lib/package_info.dart @@ -24,30 +24,31 @@ class PackageInfo { /// See [fromPlatform] for the right API to get a [PackageInfo] that's /// actually populated with real data. PackageInfo({ - this.appName, - this.packageName, - this.version, - this.buildNumber, + required this.appName, + required this.packageName, + required this.version, + required this.buildNumber, }); - static PackageInfo _fromPlatform; + static PackageInfo? _fromPlatform; /// Retrieves package information from the platform. /// The result is cached. static Future fromPlatform() async { - if (_fromPlatform != null) { - return _fromPlatform; - } + PackageInfo? packageInfo = _fromPlatform; + if (packageInfo != null) return packageInfo; final Map map = - await _kChannel.invokeMapMethod('getAll'); - _fromPlatform = PackageInfo( + (await _kChannel.invokeMapMethod('getAll'))!; + + packageInfo = PackageInfo( appName: map["appName"], packageName: map["packageName"], version: map["version"], buildNumber: map["buildNumber"], ); - return _fromPlatform; + _fromPlatform = packageInfo; + return packageInfo; } /// The app name. `CFBundleDisplayName` on iOS, `application/label` on Android. diff --git a/packages/package_info/pubspec.yaml b/packages/package_info/pubspec.yaml index 25e45a6be7bc..f575ad155e4e 100644 --- a/packages/package_info/pubspec.yaml +++ b/packages/package_info/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/package_info # 0.4.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.4.3+4 +version: 0.5.0-nullsafety flutter: plugin: @@ -29,8 +29,8 @@ dev_dependencies: sdk: flutter integration_test: path: ../integration_test - pedantic: ^1.8.0 + pedantic: ^1.10.0-nullsafety environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/package_info/test/package_info_test.dart b/packages/package_info/test/package_info_test.dart index 47d48fde2d2d..cb6967155ca0 100644 --- a/packages/package_info/test/package_info_test.dart +++ b/packages/package_info/test/package_info_test.dart @@ -11,7 +11,7 @@ void main() { const MethodChannel channel = MethodChannel('plugins.flutter.io/package_info'); - List log; + late List log; channel.setMockMethodCallHandler((MethodCall methodCall) async { log.add(methodCall); diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index b43d11c2fe1d..742487ad7bfa 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -15,6 +15,7 @@ readonly NNBD_PLUGINS_LIST=( "google_sign_in" "local_auth" "path_provider" + "package_info" "plugin_platform_interface" "share" "shared_preferences" From 7f5696c88c3e6b6eaba45bed7b6f755258e1ba5c Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Thu, 4 Feb 2021 16:37:52 -0800 Subject: [PATCH 0098/1565] Migrate path_provider to null safety. (#3460) --- .../path_provider/path_provider/CHANGELOG.md | 4 ++ .../integration_test/path_provider_test.dart | 6 +++ .../path_provider/lib/path_provider.dart | 40 +++++++++++-------- .../path_provider/path_provider/pubspec.yaml | 18 ++++----- .../test/path_provider_test.dart | 38 +++++++++--------- 5 files changed, 61 insertions(+), 45 deletions(-) diff --git a/packages/path_provider/path_provider/CHANGELOG.md b/packages/path_provider/path_provider/CHANGELOG.md index 43e765aaf0b4..7364305333cf 100644 --- a/packages/path_provider/path_provider/CHANGELOG.md +++ b/packages/path_provider/path_provider/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Migrate to null safety. + ## 1.6.28 * Drop unused UUID dependency for tests. diff --git a/packages/path_provider/path_provider/integration_test/path_provider_test.dart b/packages/path_provider/path_provider/integration_test/path_provider_test.dart index 18570aeca57e..da368d52b832 100644 --- a/packages/path_provider/path_provider/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider/integration_test/path_provider_test.dart @@ -1,3 +1,9 @@ +// Copyright 2019 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. + +// @dart=2.9 + import 'package:flutter_test/flutter_test.dart'; import 'package:path_provider/path_provider.dart'; import 'package:integration_test/integration_test.dart'; diff --git a/packages/path_provider/path_provider/lib/path_provider.dart b/packages/path_provider/path_provider/lib/path_provider.dart index 0fbab57700be..1560c3399e72 100644 --- a/packages/path_provider/path_provider/lib/path_provider.dart +++ b/packages/path_provider/path_provider/lib/path_provider.dart @@ -51,8 +51,8 @@ PathProviderPlatform get _platform { /// On iOS, this uses the `NSCachesDirectory` API. /// /// On Android, this uses the `getCacheDir` API on the context. -Future getTemporaryDirectory() async { - final String path = await _platform.getTemporaryPath(); +Future getTemporaryDirectory() async { + final String? path = await _platform.getTemporaryPath(); if (path == null) { return null; } @@ -69,8 +69,8 @@ Future getTemporaryDirectory() async { /// If this directory does not exist, it is created automatically. /// /// On Android, this function uses the `getFilesDir` API on the context. -Future getApplicationSupportDirectory() async { - final String path = await _platform.getApplicationSupportPath(); +Future getApplicationSupportDirectory() async { + final String? path = await _platform.getApplicationSupportPath(); if (path == null) { return null; } @@ -83,8 +83,8 @@ Future getApplicationSupportDirectory() async { /// /// On Android, this function throws an [UnsupportedError] as no equivalent /// path exists. -Future getLibraryDirectory() async { - final String path = await _platform.getLibraryPath(); +Future getLibraryDirectory() async { + final String? path = await _platform.getLibraryPath(); if (path == null) { return null; } @@ -100,8 +100,8 @@ Future getLibraryDirectory() async { /// On Android, this uses the `getDataDirectory` API on the context. Consider /// using [getExternalStorageDirectory] instead if data is intended to be visible /// to the user. -Future getApplicationDocumentsDirectory() async { - final String path = await _platform.getApplicationDocumentsPath(); +Future getApplicationDocumentsDirectory() async { + final String? path = await _platform.getApplicationDocumentsPath(); if (path == null) { return null; } @@ -116,8 +116,8 @@ Future getApplicationDocumentsDirectory() async { /// to access outside the app's sandbox. /// /// On Android this uses the `getExternalFilesDir(null)`. -Future getExternalStorageDirectory() async { - final String path = await _platform.getExternalStoragePath(); +Future getExternalStorageDirectory() async { + final String? path = await _platform.getExternalStoragePath(); if (path == null) { return null; } @@ -137,8 +137,11 @@ Future getExternalStorageDirectory() async { /// /// On Android this returns Context.getExternalCacheDirs() or /// Context.getExternalCacheDir() on API levels below 19. -Future> getExternalCacheDirectories() async { - final List paths = await _platform.getExternalCachePaths(); +Future?> getExternalCacheDirectories() async { + final List? paths = await _platform.getExternalCachePaths(); + if (paths == null) { + return null; + } return paths.map((String path) => Directory(path)).toList(); } @@ -155,13 +158,16 @@ Future> getExternalCacheDirectories() async { /// /// On Android this returns Context.getExternalFilesDirs(String type) or /// Context.getExternalFilesDir(String type) on API levels below 19. -Future> getExternalStorageDirectories({ +Future?> getExternalStorageDirectories({ /// Optional parameter. See [StorageDirectory] for more informations on /// how this type translates to Android storage directories. - StorageDirectory type, + StorageDirectory? type, }) async { - final List paths = + final List? paths = await _platform.getExternalStoragePaths(type: type); + if (paths == null) { + return null; + } return paths.map((String path) => Directory(path)).toList(); } @@ -171,8 +177,8 @@ Future> getExternalStorageDirectories({ /// /// On Android and on iOS, this function throws an [UnsupportedError] as no equivalent /// path exists. -Future getDownloadsDirectory() async { - final String path = await _platform.getDownloadsPath(); +Future getDownloadsDirectory() async { + final String? path = await _platform.getDownloadsPath(); if (path == null) { return null; } diff --git a/packages/path_provider/path_provider/pubspec.yaml b/packages/path_provider/path_provider/pubspec.yaml index 065c53fec9fd..6c4c851d8103 100644 --- a/packages/path_provider/path_provider/pubspec.yaml +++ b/packages/path_provider/path_provider/pubspec.yaml @@ -1,7 +1,7 @@ name: path_provider description: Flutter plugin for getting commonly used locations on host platform file systems, such as the temp and app data directories. homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider -version: 1.6.28 +version: 2.0.0-nullsafety flutter: plugin: @@ -21,10 +21,10 @@ flutter: dependencies: flutter: sdk: flutter - path_provider_platform_interface: ^1.0.1 - path_provider_macos: ^0.0.4 - path_provider_linux: ^0.0.1 - path_provider_windows: ^0.0.4 + path_provider_platform_interface: ^2.0.0-nullsafety + path_provider_macos: ^0.0.5-nullsafety + path_provider_linux: ^0.2.0-nullsafety + path_provider_windows: ^0.1.0-nullsafety dev_dependencies: integration_test: @@ -33,10 +33,10 @@ dev_dependencies: sdk: flutter flutter_driver: sdk: flutter - pedantic: ^1.8.0 - mockito: ^4.1.1 - plugin_platform_interface: ^1.0.0 + pedantic: ^1.10.0-nullsafety + mockito: ^5.0.0-nullsafety.0 + plugin_platform_interface: ^1.1.0-nullsafety environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/path_provider/path_provider/test/path_provider_test.dart b/packages/path_provider/path_provider/test/path_provider_test.dart index eb17178b9975..aec5e060f631 100644 --- a/packages/path_provider/path_provider/test/path_provider_test.dart +++ b/packages/path_provider/path_provider/test/path_provider_test.dart @@ -28,45 +28,45 @@ void main() { }); test('getTemporaryDirectory', () async { - Directory result = await getTemporaryDirectory(); - expect(result.path, kTemporaryPath); + Directory? result = await getTemporaryDirectory(); + expect(result?.path, kTemporaryPath); }); test('getApplicationSupportDirectory', () async { - Directory result = await getApplicationSupportDirectory(); - expect(result.path, kApplicationSupportPath); + Directory? result = await getApplicationSupportDirectory(); + expect(result?.path, kApplicationSupportPath); }); test('getLibraryDirectory', () async { - Directory result = await getLibraryDirectory(); - expect(result.path, kLibraryPath); + Directory? result = await getLibraryDirectory(); + expect(result?.path, kLibraryPath); }); test('getApplicationDocumentsDirectory', () async { - Directory result = await getApplicationDocumentsDirectory(); - expect(result.path, kApplicationDocumentsPath); + Directory? result = await getApplicationDocumentsDirectory(); + expect(result?.path, kApplicationDocumentsPath); }); test('getExternalStorageDirectory', () async { - Directory result = await getExternalStorageDirectory(); - expect(result.path, kExternalStoragePath); + Directory? result = await getExternalStorageDirectory(); + expect(result?.path, kExternalStoragePath); }); test('getExternalCacheDirectories', () async { - List result = await getExternalCacheDirectories(); - expect(result.length, 1); - expect(result.first.path, kExternalCachePath); + List? result = await getExternalCacheDirectories(); + expect(result?.length, 1); + expect(result?.first.path, kExternalCachePath); }); test('getExternalStorageDirectories', () async { - List result = await getExternalStorageDirectories(); - expect(result.length, 1); - expect(result.first.path, kExternalStoragePath); + List? result = await getExternalStorageDirectories(); + expect(result?.length, 1); + expect(result?.first.path, kExternalStoragePath); }); test('getDownloadsDirectory', () async { - Directory result = await getDownloadsDirectory(); - expect(result.path, kDownloadsPath); + Directory? result = await getDownloadsDirectory(); + expect(result?.path, kDownloadsPath); }); }); } @@ -99,7 +99,7 @@ class MockPathProviderPlatform extends Mock } Future> getExternalStoragePaths({ - StorageDirectory type, + StorageDirectory? type, }) async { return [kExternalStoragePath]; } From ad308e54ce39cfa91b6f93e7c407d828fd465ebc Mon Sep 17 00:00:00 2001 From: Tim Sneath Date: Fri, 5 Feb 2021 04:01:57 -0800 Subject: [PATCH 0099/1565] Update to ffi 0.3.0-nullsafety.1 (#3513) ffi 0.3.0 supports the new memory allocation model in Dart 2.12.0-259 and later. --- .../path_provider_windows/CHANGELOG.md | 4 +++ .../example/windows/flutter/CMakeLists.txt | 1 + .../lib/src/path_provider_windows_real.dart | 34 +++++++++---------- .../path_provider_windows/pubspec.yaml | 9 ++--- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/packages/path_provider/path_provider_windows/CHANGELOG.md b/packages/path_provider/path_provider_windows/CHANGELOG.md index 24304e36dc0c..6190c39457da 100644 --- a/packages/path_provider/path_provider_windows/CHANGELOG.md +++ b/packages/path_provider/path_provider_windows/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.0-nullsafety.2 + +* Bump ffi dependency to 0.3.0-nullsafety.1 + ## 0.1.0-nullsafety.1 * Bump win32 dependency to latest version. diff --git a/packages/path_provider/path_provider_windows/example/windows/flutter/CMakeLists.txt b/packages/path_provider/path_provider_windows/example/windows/flutter/CMakeLists.txt index c7a8c7607d81..744f08a9389b 100644 --- a/packages/path_provider/path_provider_windows/example/windows/flutter/CMakeLists.txt +++ b/packages/path_provider/path_provider_windows/example/windows/flutter/CMakeLists.txt @@ -91,6 +91,7 @@ add_custom_command( ${FLUTTER_TOOL_ENVIRONMENT} "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" windows-x64 $ + VERBATIM ) add_custom_target(flutter_assemble DEPENDS "${FLUTTER_LIBRARY}" diff --git a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart index c104343f2502..c88e10a0f9b3 100644 --- a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart +++ b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart @@ -28,17 +28,17 @@ class VersionInfoQuerier { } const kEnUsLanguageCode = '040904e4'; final keyPath = TEXT('\\StringFileInfo\\$kEnUsLanguageCode\\$key'); - final length = allocate(); - final valueAddress = allocate>(); + final length = calloc(); + final valueAddress = calloc>(); try { if (VerQueryValue(versionInfo, keyPath, valueAddress, length) == 0) { return null; } return valueAddress.value.unpackString(length.value); } finally { - free(keyPath); - free(length); - free(valueAddress); + calloc.free(keyPath); + calloc.free(length); + calloc.free(valueAddress); } } } @@ -54,7 +54,7 @@ class PathProviderWindows extends PathProviderPlatform { /// This is typically the same as the TMP environment variable. @override Future getTemporaryPath() async { - final buffer = allocate(count: MAX_PATH + 1).cast(); + final buffer = calloc(MAX_PATH + 1).cast(); String path; try { @@ -82,7 +82,7 @@ class PathProviderWindows extends PathProviderPlatform { return Future.value(path); } finally { - free(buffer); + calloc.free(buffer); } } @@ -115,7 +115,7 @@ class PathProviderWindows extends PathProviderPlatform { /// folderID is a GUID that represents a specific known folder ID, drawn from /// [WindowsKnownFolder]. Future getPath(String folderID) { - final pathPtrPtr = allocate>(); + final pathPtrPtr = calloc>(); final Pointer knownFolderID = calloc()..ref.setGUID(folderID); try { @@ -135,8 +135,8 @@ class PathProviderWindows extends PathProviderPlatform { final path = pathPtrPtr.value.unpackString(MAX_PATH); return Future.value(path); } finally { - free(pathPtrPtr); - free(knownFolderID); + calloc.free(pathPtrPtr); + calloc.free(knownFolderID); } } @@ -155,8 +155,8 @@ class PathProviderWindows extends PathProviderPlatform { String? productName; final Pointer moduleNameBuffer = - allocate(count: MAX_PATH + 1).cast(); - final Pointer unused = allocate(); + calloc(MAX_PATH + 1).cast(); + final Pointer unused = calloc(); Pointer? infoBuffer; try { // Get the module name. @@ -169,10 +169,10 @@ class PathProviderWindows extends PathProviderPlatform { // From that, load the VERSIONINFO resource int infoSize = GetFileVersionInfoSize(moduleNameBuffer, unused); if (infoSize != 0) { - infoBuffer = allocate(count: infoSize); + infoBuffer = calloc(infoSize); if (GetFileVersionInfo(moduleNameBuffer, 0, infoSize, infoBuffer) == 0) { - free(infoBuffer); + calloc.free(infoBuffer); infoBuffer = null; } } @@ -191,10 +191,10 @@ class PathProviderWindows extends PathProviderPlatform { ? path.join(companyName, productName) : productName; } finally { - free(moduleNameBuffer); - free(unused); + calloc.free(moduleNameBuffer); + calloc.free(unused); if (infoBuffer != null) { - free(infoBuffer); + calloc.free(infoBuffer); } } } diff --git a/packages/path_provider/path_provider_windows/pubspec.yaml b/packages/path_provider/path_provider_windows/pubspec.yaml index 578000682e63..922594a9bd2d 100644 --- a/packages/path_provider/path_provider_windows/pubspec.yaml +++ b/packages/path_provider/path_provider_windows/pubspec.yaml @@ -1,7 +1,7 @@ name: path_provider_windows description: Windows implementation of the path_provider plugin homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_windows -version: 0.1.0-nullsafety.1 +version: 0.1.0-nullsafety.2 flutter: plugin: @@ -16,8 +16,8 @@ dependencies: path: ^1.8.0-nullsafety.3 flutter: sdk: flutter - ffi: ^0.2.0-nullsafety.1 - win32: ^2.0.0-nullsafety.9 + ffi: '>=0.3.0-nullsafety.1 <2.0.0' + win32: ^2.0.0-nullsafety.10 dev_dependencies: flutter_test: @@ -25,5 +25,6 @@ dev_dependencies: pedantic: ^1.10.0-nullsafety.3 environment: - sdk: '>=2.12.0-0 <3.0.0' + sdk: '>=2.12.0-259.8.beta <3.0.0' flutter: ">=1.12.13+hotfix.4" + From 5aa082f8b2f01df41ae01210d30e254aea9dbea0 Mon Sep 17 00:00:00 2001 From: Hamdi Kahloun <32666446+hamdikahloun@users.noreply.github.com> Date: Fri, 5 Feb 2021 22:23:48 +0100 Subject: [PATCH 0100/1565] [wifi_info_flutter] Check Permissions in Android O or higher (#3234) * Check Permissions * Format * Update packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java Co-authored-by: Maurice Parrish * Update packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java Co-authored-by: Maurice Parrish * Update packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java Co-authored-by: Maurice Parrish * Update packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java Co-authored-by: Maurice Parrish * Update packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java Co-authored-by: Maurice Parrish * Update packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java Co-authored-by: Maurice Parrish * Update packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java Co-authored-by: Maurice Parrish * Update packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java Co-authored-by: Maurice Parrish Co-authored-by: Maurice Parrish --- .../wifi_info_flutter/CHANGELOG.md | 5 + .../wifi_info_flutter/WifiInfoFlutter.java | 103 +++++++++++++++++- .../WifiInfoFlutterPlugin.java | 2 +- .../android/app/src/main/AndroidManifest.xml | 4 + .../wifi_info_flutter/example/lib/main.dart | 14 +-- .../wifi_info_flutter/pubspec.yaml | 2 +- 6 files changed, 120 insertions(+), 10 deletions(-) diff --git a/packages/wifi_info_flutter/wifi_info_flutter/CHANGELOG.md b/packages/wifi_info_flutter/wifi_info_flutter/CHANGELOG.md index 5c3ea32e8ef9..fa68eed175b7 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/CHANGELOG.md +++ b/packages/wifi_info_flutter/wifi_info_flutter/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.0.4 + +* Android: Add Log warning for unsatisfied requirement(s) in Android P or higher. +* Android: Update Example project. + ## 1.0.3 * Fix README example. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java b/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java index f74e4f0f75e1..e5e33af715ca 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java +++ b/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java @@ -4,18 +4,31 @@ package io.flutter.plugins.wifi_info_flutter; +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.LocationManager; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; +import android.os.Build; +import androidx.core.content.ContextCompat; +import io.flutter.Log; /** Reports wifi information. */ class WifiInfoFlutter { private WifiManager wifiManager; + private Context context; + private static final String TAG = "WifiInfoFlutter"; - WifiInfoFlutter(WifiManager wifiManager) { + WifiInfoFlutter(WifiManager wifiManager, Context context) { this.wifiManager = wifiManager; + this.context = context; } String getWifiName() { + if (!checkPermissions()) { + return null; + } final WifiInfo wifiInfo = getWifiInfo(); String ssid = null; if (wifiInfo != null) ssid = wifiInfo.getSSID(); @@ -25,6 +38,9 @@ String getWifiName() { } String getWifiBSSID() { + if (!checkPermissions()) { + return null; + } final WifiInfo wifiInfo = getWifiInfo(); String bssid = null; if (wifiInfo != null) { @@ -53,4 +69,89 @@ String getWifiIPAddress() { private WifiInfo getWifiInfo() { return wifiManager == null ? null : wifiManager.getConnectionInfo(); } + + private Boolean checkPermissions() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + return true; + } + + boolean grantedChangeWifiState = + ContextCompat.checkSelfPermission(context, Manifest.permission.CHANGE_WIFI_STATE) + == PackageManager.PERMISSION_GRANTED; + + boolean grantedAccessFine = + ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) + == PackageManager.PERMISSION_GRANTED; + + boolean grantedAccessCoarse = + ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) + == PackageManager.PERMISSION_GRANTED; + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P + && !grantedChangeWifiState + && !grantedAccessFine + && !grantedAccessCoarse) { + Log.w( + TAG, + "Attempted to get Wi-Fi data that requires additional permission(s).\n" + + "To successfully get WiFi Name or Wi-Fi BSSID starting with Android O, please ensure your app has one of the following permissions:\n" + + "- CHANGE_WIFI_STATE\n" + + "- ACCESS_FINE_LOCATION\n" + + "- ACCESS_COARSE_LOCATION\n" + + "For more information about Wi-Fi Restrictions in Android 8.0 and above, please consult the following link:\n" + + "https://developer.android.com/guide/topics/connectivity/wifi-scan"); + return false; + } + + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.P && !grantedChangeWifiState) { + Log.w( + TAG, + "Attempted to get Wi-Fi data that requires additional permission(s).\n" + + "To successfully get WiFi Name or Wi-Fi BSSID starting with Android P, please ensure your app has the CHANGE_WIFI_STATE permission.\n" + + "For more information about Wi-Fi Restrictions in Android 9.0 and above, please consult the following link:\n" + + "https://developer.android.com/guide/topics/connectivity/wifi-scan"); + return false; + } + + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.P + && !grantedAccessFine + && !grantedAccessCoarse) { + Log.w( + TAG, + "Attempted to get Wi-Fi data that requires additional permission(s).\n" + + "To successfully get WiFi Name or Wi-Fi BSSID starting with Android P, additional to CHANGE_WIFI_STATE please ensure your app has one of the following permissions too:\n" + + "- ACCESS_FINE_LOCATION\n" + + "- ACCESS_COARSE_LOCATION\n" + + "For more information about Wi-Fi Restrictions in Android 9.0 and above, please consult the following link:\n" + + "https://developer.android.com/guide/topics/connectivity/wifi-scan"); + return false; + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q + && (!grantedAccessFine || !grantedChangeWifiState)) { + Log.w( + TAG, + "Attempted to get Wi-Fi data that requires additional permission(s).\n" + + "To successfully get WiFi Name or Wi-Fi BSSID starting with Android Q, please ensure your app has the CHANGE_WIFI_STATE and ACCESS_FINE_LOCATION permission.\n" + + "For more information about Wi-Fi Restrictions in Android 10.0 and above, please consult the following link:\n" + + "https://developer.android.com/guide/topics/connectivity/wifi-scan"); + return false; + } + + LocationManager locationManager = + (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + + boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && !gpsEnabled) { + Log.w( + TAG, + "Attempted to get Wi-Fi data that requires additional permission(s).\n" + + "To successfully get WiFi Name or Wi-Fi BSSID starting with Android P, please ensure Location services are enabled on the device (under Settings > Location).\n" + + "For more information about Wi-Fi Restrictions in Android 9.0 and above, please consult the following link:\n" + + "https://developer.android.com/guide/topics/connectivity/wifi-scan"); + return false; + } + return true; + } } diff --git a/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterPlugin.java b/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterPlugin.java index ea22e0bc88a5..1346617df53b 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterPlugin.java +++ b/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterPlugin.java @@ -37,7 +37,7 @@ private void setupChannels(BinaryMessenger messenger, Context context) { final WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE); - final WifiInfoFlutter wifiInfoFlutter = new WifiInfoFlutter(wifiManager); + final WifiInfoFlutter wifiInfoFlutter = new WifiInfoFlutter(wifiManager, context); final WifiInfoFlutterMethodChannelHandler methodChannelHandler = new WifiInfoFlutterMethodChannelHandler(wifiInfoFlutter); diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/android/app/src/main/AndroidManifest.xml b/packages/wifi_info_flutter/wifi_info_flutter/example/android/app/src/main/AndroidManifest.xml index 22158120a33f..bcecab36d14a 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/android/app/src/main/AndroidManifest.xml +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,9 @@ + + + + diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/lib/main.dart b/packages/wifi_info_flutter/wifi_info_flutter/example/lib/main.dart index 17a9e76ad946..8c64c5d9a421 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/lib/main.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/lib/main.dart @@ -114,12 +114,12 @@ class _MyHomePageState extends State { } if (status == LocationAuthorizationStatus.authorizedAlways || status == LocationAuthorizationStatus.authorizedWhenInUse) { - wifiName = await _connectivity.getWifiName(); + wifiName = await _wifiInfo.getWifiName(); } else { - wifiName = await _connectivity.getWifiName(); + wifiName = await _wifiInfo.getWifiName(); } } else { - wifiName = await _connectivity.getWifiName(); + wifiName = await _wifiInfo.getWifiName(); } } on PlatformException catch (e) { print(e.toString()); @@ -135,12 +135,12 @@ class _MyHomePageState extends State { } if (status == LocationAuthorizationStatus.authorizedAlways || status == LocationAuthorizationStatus.authorizedWhenInUse) { - wifiBSSID = await _connectivity.getWifiBSSID(); + wifiBSSID = await _wifiInfo.getWifiBSSID(); } else { - wifiBSSID = await _connectivity.getWifiBSSID(); + wifiBSSID = await _wifiInfo.getWifiBSSID(); } } else { - wifiBSSID = await _connectivity.getWifiBSSID(); + wifiBSSID = await _wifiInfo.getWifiBSSID(); } } on PlatformException catch (e) { print(e.toString()); @@ -148,7 +148,7 @@ class _MyHomePageState extends State { } try { - wifiIP = await _connectivity.getWifiIP(); + wifiIP = await _wifiInfo.getWifiIP(); } on PlatformException catch (e) { print(e.toString()); wifiIP = "Failed to get Wifi IP"; diff --git a/packages/wifi_info_flutter/wifi_info_flutter/pubspec.yaml b/packages/wifi_info_flutter/wifi_info_flutter/pubspec.yaml index 4f5ecafb50b4..b8306a0696d2 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/pubspec.yaml +++ b/packages/wifi_info_flutter/wifi_info_flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: wifi_info_flutter description: A new flutter plugin project. -version: 1.0.3 +version: 1.0.4 homepage: https://github.com/flutter/plugins/tree/master/packages/wifi_info_flutter/wifi_info_flutter environment: From 654a02589102a9c3cb71e0c43de63bd71c232a28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl?= <32639467+danielroek@users.noreply.github.com> Date: Sat, 6 Feb 2021 09:36:21 +0100 Subject: [PATCH 0101/1565] [camera_platform_interface] Added stopRecordingVideo (#3518) * Added stopRecordingVideo * Removed deprecation and made stopRecordingVideo return void * Removed unused import * Revert pubspec change * Updated documentation * removed stopRecordingVideo * Update packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart Co-authored-by: Maurits van Beusekom * fixed formatting * Remove coverage folders * Updated documentation * updated version Co-authored-by: Maurits van Beusekom --- .../camera_platform_interface/CHANGELOG.md | 4 ++ .../lib/src/events/camera_event.dart | 46 +++++++++++++++++++ .../method_channel/method_channel_camera.dart | 14 ++++++ .../platform_interface/camera_platform.dart | 8 +++- .../camera_platform_interface/pubspec.yaml | 2 +- 5 files changed, 72 insertions(+), 2 deletions(-) diff --git a/packages/camera/camera_platform_interface/CHANGELOG.md b/packages/camera/camera_platform_interface/CHANGELOG.md index d7442d4ac931..ff739918c53b 100644 --- a/packages/camera/camera_platform_interface/CHANGELOG.md +++ b/packages/camera/camera_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.0 + +- Added VideoRecordedEvent to support ending a video recording in the native implementation. + ## 1.5.0 - Introduces interface methods for locking and unlocking the capture orientation. diff --git a/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart b/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart index d60a0a39f608..ad9958381143 100644 --- a/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart +++ b/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart @@ -235,3 +235,49 @@ class CameraErrorEvent extends CameraEvent { @override int get hashCode => super.hashCode ^ description.hashCode; } + +/// An event fired when a video has finished recording. +class VideoRecordedEvent extends CameraEvent { + /// XFile of the recorded video. + final XFile file; + + /// Maximum duration of the recorded video. + final Duration maxVideoDuration; + + /// Build a VideoRecordedEvent triggered from the camera with the `cameraId`. + /// + /// The `file` represents the file of the video. + /// The `maxVideoDuration` shows if a maxVideoDuration shows if a maximum + /// video duration was set. + VideoRecordedEvent(int cameraId, this.file, this.maxVideoDuration) + : super(cameraId); + + /// Converts the supplied [Map] to an instance of the [VideoRecordedEvent] + /// class. + VideoRecordedEvent.fromJson(Map json) + : file = XFile(json['path']), + maxVideoDuration = json['maxVideoDuration'] != null + ? Duration(milliseconds: json['maxVideoDuration'] as int) + : null, + super(json['cameraId']); + + /// Converts the [VideoRecordedEvent] instance into a [Map] instance that can be + /// serialized to JSON. + Map toJson() => { + 'cameraId': cameraId, + 'path': file.path, + 'maxVideoDuration': maxVideoDuration?.inMilliseconds + }; + + @override + bool operator ==(Object other) => + identical(this, other) || + super == other && + other is VideoRecordedEvent && + runtimeType == other.runtimeType && + maxVideoDuration == other.maxVideoDuration; + + @override + int get hashCode => + super.hashCode ^ file.hashCode ^ maxVideoDuration.hashCode; +} diff --git a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart index e6f658c45365..36a2c92645f2 100644 --- a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart +++ b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart @@ -156,6 +156,11 @@ class MethodChannelCamera extends CameraPlatform { return _cameraEvents(cameraId).whereType(); } + @override + Stream onVideoRecordedEvent(int cameraId) { + return _cameraEvents(cameraId).whereType(); + } + @override Stream onDeviceOrientationChanged() { return deviceEventStreamController.stream @@ -433,6 +438,15 @@ class MethodChannelCamera extends CameraPlatform { cameraId, )); break; + case 'video_recorded': + cameraEventStreamController.add(VideoRecordedEvent( + cameraId, + XFile(call.arguments['path']), + call.arguments['maxVideoDuration'] != null + ? Duration(milliseconds: call.arguments['maxVideoDuration']) + : null, + )); + break; case 'error': cameraEventStreamController.add(CameraErrorEvent( cameraId, diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart index c1d6e09c3263..e1faecf374cd 100644 --- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart +++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart @@ -87,6 +87,11 @@ abstract class CameraPlatform extends PlatformInterface { throw UnimplementedError('onCameraError() is not implemented.'); } + /// The camera finished recording a video + Stream onVideoRecordedEvent(int cameraId) { + throw UnimplementedError('onCameraTimeLimitReached() is not implemented.'); + } + /// The device orientation changed. /// /// Implementations for this: @@ -123,7 +128,8 @@ abstract class CameraPlatform extends PlatformInterface { /// The length of the recording can be limited by specifying the [maxVideoDuration]. /// By default no maximum duration is specified, /// meaning the recording will continue until manually stopped. - /// The video is returned as a [XFile] after calling [stopVideoRecording]. + /// With [maxVideoDuration] set the video is returned in a [VideoRecordedEvent] + /// through the [onVideoRecordedEvent] stream when the set duration is reached. Future startVideoRecording(int cameraId, {Duration maxVideoDuration}) { throw UnimplementedError('startVideoRecording() is not implemented.'); } diff --git a/packages/camera/camera_platform_interface/pubspec.yaml b/packages/camera/camera_platform_interface/pubspec.yaml index 2a8d7ce9abe1..c7ec7209c838 100644 --- a/packages/camera/camera_platform_interface/pubspec.yaml +++ b/packages/camera/camera_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the camera plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.5.0 +version: 1.6.0 dependencies: flutter: From aa827e30ba37af3f2c49645b337dbe67c3ba9dbe Mon Sep 17 00:00:00 2001 From: max <19898639+vimaxwell@users.noreply.github.com> Date: Sat, 6 Feb 2021 21:16:37 +0700 Subject: [PATCH 0102/1565] [camera] Clockwise rotation of focus point in android (#3458) --- packages/camera/camera/CHANGELOG.md | 4 ++++ .../src/main/java/io/flutter/plugins/camera/Camera.java | 4 ++-- packages/camera/camera/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index a8dbe65e7453..622bd095b021 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.0+3 + +* Clockwise rotation of focus point in android + ## 0.7.0+2 * Fix example reference in README. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 1b6cce95d08c..a5f8647afb0b 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -786,7 +786,7 @@ public void setExposurePoint(@NonNull final Result result, Double x, Double y) } // Set the metering rectangle if (x == null || y == null) cameraRegions.resetAutoExposureMeteringRectangle(); - else cameraRegions.setAutoExposureMeteringRectangleFromPoint(x, y); + else cameraRegions.setAutoExposureMeteringRectangleFromPoint(y, 1 - x); // Apply it updateExposure(exposureMode); refreshPreviewCaptureSession( @@ -838,7 +838,7 @@ public void setFocusPoint(@NonNull final Result result, Double x, Double y) if (x == null || y == null) { cameraRegions.resetAutoFocusMeteringRectangle(); } else { - cameraRegions.setAutoFocusMeteringRectangleFromPoint(x, y); + cameraRegions.setAutoFocusMeteringRectangleFromPoint(y, 1 - x); } // Apply the new metering rectangle diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 2b6d163dfbeb..cebbb334c8f2 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.7.0+2 +version: 0.7.0+3 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From 0cec317a1c67c462dfd56d323aaf3a51e5d20d0a Mon Sep 17 00:00:00 2001 From: Sameer Kashyap <40424087+Sameerkash@users.noreply.github.com> Date: Mon, 8 Feb 2021 21:04:53 +0530 Subject: [PATCH 0103/1565] [shared_preferences_windows]-Migrate to null safety (#3516) Migrate shared_preferences_windows to null safety --- .../shared_preferences_windows/CHANGELOG.md | 5 +++ .../lib/shared_preferences_windows.dart | 45 +++++++++++-------- .../shared_preferences_windows/pubspec.yaml | 15 ++++--- .../test/shared_preferences_windows_test.dart | 20 ++++----- 4 files changed, 50 insertions(+), 35 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md b/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md index a8c3a85cd3ce..41119901f396 100644 --- a/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md @@ -1,3 +1,8 @@ + +## 0.0.3-nullsafety + +* Migrate to null-safety. + ## 0.0.2+3 * Remove 'ffi' dependency. diff --git a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart index dd9ab8a0c38f..b2678c49782b 100644 --- a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart +++ b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart @@ -27,42 +27,51 @@ class SharedPreferencesWindows extends SharedPreferencesStorePlatform { PathProviderWindows pathProvider = PathProviderWindows(); /// Local copy of preferences - Map _cachedPreferences; + Map? _cachedPreferences; /// Cached file for storing preferences. - File _localDataFilePath; + File? _localDataFilePath; /// Gets the file where the preferences are stored. - Future _getLocalDataFile() async { - if (_localDataFilePath == null) { - final directory = await pathProvider.getApplicationSupportPath(); - _localDataFilePath = - fs.file(path.join(directory, 'shared_preferences.json')); + Future _getLocalDataFile() async { + if (_localDataFilePath != null) { + return _localDataFilePath!; } - return _localDataFilePath; + final directory = await pathProvider.getApplicationSupportPath(); + if (directory == null) { + return null; + } + return _localDataFilePath = + fs.file(path.join(directory, 'shared_preferences.json')); } /// Gets the preferences from the stored file. Once read, the preferences are /// maintained in memory. Future> _readPreferences() async { - if (_cachedPreferences == null) { - _cachedPreferences = {}; - File localDataFile = await _getLocalDataFile(); - if (localDataFile.existsSync()) { - String stringMap = localDataFile.readAsStringSync(); - if (stringMap.isNotEmpty) { - _cachedPreferences = json.decode(stringMap) as Map; - } + if (_cachedPreferences != null) { + return _cachedPreferences!; + } + Map preferences = {}; + final File? localDataFile = await _getLocalDataFile(); + if (localDataFile != null && localDataFile.existsSync()) { + String stringMap = localDataFile.readAsStringSync(); + if (stringMap.isNotEmpty) { + preferences = json.decode(stringMap).cast(); } } - return _cachedPreferences; + _cachedPreferences = preferences; + return preferences; } /// Writes the cached preferences to disk. Returns [true] if the operation /// succeeded. Future _writePreferences(Map preferences) async { try { - File localDataFile = await _getLocalDataFile(); + final File? localDataFile = await _getLocalDataFile(); + if (localDataFile == null) { + print("Unable to determine where to write preferences."); + return false; + } if (!localDataFile.existsSync()) { localDataFile.createSync(recursive: true); } diff --git a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml index 6123300c9689..e2cf3d03f00d 100644 --- a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml @@ -1,7 +1,8 @@ name: shared_preferences_windows description: Windows implementation of shared_preferences homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_windows -version: 0.0.2+3 +version: 0.0.3-nullsafety + flutter: plugin: @@ -11,20 +12,20 @@ flutter: pluginClass: none environment: - sdk: ">=2.1.0 <3.0.0" + sdk: '>=2.12.0-0 <3.0.0' flutter: ">=1.12.8" dependencies: - shared_preferences_platform_interface: ^1.0.0 + shared_preferences_platform_interface: ^2.0.0-nullsafety flutter: sdk: flutter - file: ">=5.1.0 <7.0.0" + file: ^6.0.0-nullsafety.4 meta: ^1.1.7 path: ^1.6.4 - path_provider_platform_interface: ^1.0.3 - path_provider_windows: ^0.0.2 + path_provider_platform_interface: ^2.0.0-nullsafety + path_provider_windows: ^0.1.0-nullsafety.2 dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0-nullsafety.3 diff --git a/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart b/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart index b0827ca3b36b..785092f6fa16 100644 --- a/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart +++ b/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart @@ -10,8 +10,8 @@ import 'package:path_provider_windows/path_provider_windows.dart'; import 'package:shared_preferences_windows/shared_preferences_windows.dart'; void main() { - MemoryFileSystem fileSystem; - PathProviderWindows pathProvider; + late MemoryFileSystem fileSystem; + late PathProviderWindows pathProvider; setUp(() { fileSystem = MemoryFileSystem.test(); @@ -22,7 +22,7 @@ void main() { Future _getFilePath() async { final directory = await pathProvider.getApplicationSupportPath(); - return path.join(directory, 'shared_preferences.json'); + return path.join(directory!, 'shared_preferences.json'); } _writeTestFile(String value) async { @@ -87,23 +87,23 @@ void main() { /// path it returns is a root path that does not actually exist on Windows. class FakePathProviderWindows extends PathProviderPlatform implements PathProviderWindows { - VersionInfoQuerier versionInfoQuerier; + late VersionInfoQuerier versionInfoQuerier; @override - Future getApplicationSupportPath() async => r'C:\appsupport'; + Future getApplicationSupportPath() async => r'C:\appsupport'; @override - Future getTemporaryPath() async => null; + Future getTemporaryPath() async => null; @override - Future getLibraryPath() async => null; + Future getLibraryPath() async => null; @override - Future getApplicationDocumentsPath() async => null; + Future getApplicationDocumentsPath() async => null; @override - Future getDownloadsPath() async => null; + Future getDownloadsPath() async => null; @override - Future getPath(String folderID) async => null; + Future getPath(String folderID) async => ''; } From 3d704640ed98f8806db95983ce852e3a6538aa21 Mon Sep 17 00:00:00 2001 From: Sameer Kashyap <40424087+Sameerkash@users.noreply.github.com> Date: Mon, 8 Feb 2021 21:11:39 +0530 Subject: [PATCH 0104/1565] [image_picker] Migrate to null-safety (#3524) Migrate image_picker to null-safety --- .../image_picker/image_picker/CHANGELOG.md | 6 + .../image_picker/example/lib/main.dart | 97 ++--- .../image_picker/example/pubspec.yaml | 9 +- .../old_image_picker_test.dart | 2 + .../image_picker/lib/image_picker.dart | 105 +----- .../image_picker/image_picker/pubspec.yaml | 12 +- .../image_picker/test/image_picker_test.dart | 6 +- .../test/old_image_picker_test.dart | 340 ------------------ 8 files changed, 79 insertions(+), 498 deletions(-) delete mode 100644 packages/image_picker/image_picker/test/old_image_picker_test.dart diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md index 1a09758d13ef..c6b29f277ec3 100644 --- a/packages/image_picker/image_picker/CHANGELOG.md +++ b/packages/image_picker/image_picker/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.7.0-nullsafety +* Migrate to nullsafety +* Breaking Changes: + * Removed the deprecated methods: `ImagePicker.pickImage`, `ImagePicker.pickVideo`, +`ImagePicker.retrieveLostData` + ## 0.6.7+22 * iOS: update XCUITests to separate each test session. diff --git a/packages/image_picker/image_picker/example/lib/main.dart b/packages/image_picker/image_picker/example/lib/main.dart index 73327ef0caa6..54e3a1ae4cd2 100755 --- a/packages/image_picker/image_picker/example/lib/main.dart +++ b/packages/image_picker/image_picker/example/lib/main.dart @@ -29,60 +29,63 @@ class MyApp extends StatelessWidget { } class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); + MyHomePage({Key? key, this.title}) : super(key: key); - final String title; + final String? title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State { - PickedFile _imageFile; + PickedFile? _imageFile; dynamic _pickImageError; bool isVideo = false; - VideoPlayerController _controller; - VideoPlayerController _toBeDisposed; - String _retrieveDataError; + VideoPlayerController? _controller; + VideoPlayerController? _toBeDisposed; + String? _retrieveDataError; final ImagePicker _picker = ImagePicker(); final TextEditingController maxWidthController = TextEditingController(); final TextEditingController maxHeightController = TextEditingController(); final TextEditingController qualityController = TextEditingController(); - Future _playVideo(PickedFile file) async { + Future _playVideo(PickedFile? file) async { if (file != null && mounted) { await _disposeVideoController(); + late VideoPlayerController controller; if (kIsWeb) { - _controller = VideoPlayerController.network(file.path); - // In web, most browsers won't honor a programmatic call to .play - // if the video has a sound track (and is not muted). - // Mute the video so it auto-plays in web! - // This is not needed if the call to .play is the result of user - // interaction (clicking on a "play" button, for example). - await _controller.setVolume(0.0); + controller = VideoPlayerController.network(file.path); } else { - _controller = VideoPlayerController.file(File(file.path)); - await _controller.setVolume(1.0); + controller = VideoPlayerController.file(File(file.path)); } - await _controller.initialize(); - await _controller.setLooping(true); - await _controller.play(); + _controller = controller; + // In web, most browsers won't honor a programmatic call to .play + // if the video has a sound track (and is not muted). + // Mute the video so it auto-plays in web! + // This is not needed if the call to .play is the result of user + // interaction (clicking on a "play" button, for example). + final double volume = kIsWeb ? 0.0 : 1.0; + await controller.setVolume(volume); + await controller.initialize(); + await controller.setLooping(true); + await controller.play(); setState(() {}); } } - void _onImageButtonPressed(ImageSource source, {BuildContext context}) async { + void _onImageButtonPressed(ImageSource source, + {BuildContext? context}) async { if (_controller != null) { - await _controller.setVolume(0.0); + await _controller!.setVolume(0.0); } if (isVideo) { - final PickedFile file = await _picker.getVideo( + final PickedFile? file = await _picker.getVideo( source: source, maxDuration: const Duration(seconds: 10)); await _playVideo(file); } else { - await _displayPickImageDialog(context, - (double maxWidth, double maxHeight, int quality) async { + await _displayPickImageDialog(context!, + (double? maxWidth, double? maxHeight, int? quality) async { try { final pickedFile = await _picker.getImage( source: source, @@ -105,8 +108,8 @@ class _MyHomePageState extends State { @override void deactivate() { if (_controller != null) { - _controller.setVolume(0.0); - _controller.pause(); + _controller!.setVolume(0.0); + _controller!.pause(); } super.deactivate(); } @@ -122,14 +125,14 @@ class _MyHomePageState extends State { Future _disposeVideoController() async { if (_toBeDisposed != null) { - await _toBeDisposed.dispose(); + await _toBeDisposed!.dispose(); } _toBeDisposed = _controller; _controller = null; } Widget _previewVideo() { - final Text retrieveError = _getRetrieveErrorWidget(); + final Text? retrieveError = _getRetrieveErrorWidget(); if (retrieveError != null) { return retrieveError; } @@ -146,7 +149,7 @@ class _MyHomePageState extends State { } Widget _previewImage() { - final Text retrieveError = _getRetrieveErrorWidget(); + final Text? retrieveError = _getRetrieveErrorWidget(); if (retrieveError != null) { return retrieveError; } @@ -154,10 +157,10 @@ class _MyHomePageState extends State { if (kIsWeb) { // Why network? // See https://pub.dev/packages/image_picker#getting-ready-for-the-web-platform - return Image.network(_imageFile.path); + return Image.network(_imageFile!.path); } else { return Semantics( - child: Image.file(File(_imageFile.path)), + child: Image.file(File(_imageFile!.path)), label: 'image_picker_example_picked_image'); } } else if (_pickImageError != null) { @@ -189,7 +192,7 @@ class _MyHomePageState extends State { }); } } else { - _retrieveDataError = response.exception.code; + _retrieveDataError = response.exception!.code; } } @@ -197,7 +200,7 @@ class _MyHomePageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text(widget.title), + title: Text(widget.title!), ), body: Center( child: !kIsWeb && defaultTargetPlatform == TargetPlatform.android @@ -288,9 +291,9 @@ class _MyHomePageState extends State { ); } - Text _getRetrieveErrorWidget() { + Text? _getRetrieveErrorWidget() { if (_retrieveDataError != null) { - final Text result = Text(_retrieveDataError); + final Text result = Text(_retrieveDataError!); _retrieveDataError = null; return result; } @@ -336,13 +339,13 @@ class _MyHomePageState extends State { TextButton( child: const Text('PICK'), onPressed: () { - double width = maxWidthController.text.isNotEmpty + double? width = maxWidthController.text.isNotEmpty ? double.parse(maxWidthController.text) : null; - double height = maxHeightController.text.isNotEmpty + double? height = maxHeightController.text.isNotEmpty ? double.parse(maxHeightController.text) : null; - int quality = qualityController.text.isNotEmpty + int? quality = qualityController.text.isNotEmpty ? int.parse(qualityController.text) : null; onPick(width, height, quality); @@ -355,27 +358,27 @@ class _MyHomePageState extends State { } typedef void OnPickImageCallback( - double maxWidth, double maxHeight, int quality); + double? maxWidth, double? maxHeight, int? quality); class AspectRatioVideo extends StatefulWidget { AspectRatioVideo(this.controller); - final VideoPlayerController controller; + final VideoPlayerController? controller; @override AspectRatioVideoState createState() => AspectRatioVideoState(); } class AspectRatioVideoState extends State { - VideoPlayerController get controller => widget.controller; + VideoPlayerController? get controller => widget.controller; bool initialized = false; void _onVideoControllerUpdate() { if (!mounted) { return; } - if (initialized != controller.value.initialized) { - initialized = controller.value.initialized; + if (initialized != controller!.value.isInitialized) { + initialized = controller!.value.isInitialized; setState(() {}); } } @@ -383,12 +386,12 @@ class AspectRatioVideoState extends State { @override void initState() { super.initState(); - controller.addListener(_onVideoControllerUpdate); + controller!.addListener(_onVideoControllerUpdate); } @override void dispose() { - controller.removeListener(_onVideoControllerUpdate); + controller!.removeListener(_onVideoControllerUpdate); super.dispose(); } @@ -397,8 +400,8 @@ class AspectRatioVideoState extends State { if (initialized) { return Center( child: AspectRatio( - aspectRatio: controller.value?.aspectRatio, - child: VideoPlayer(controller), + aspectRatio: controller!.value.aspectRatio, + child: VideoPlayer(controller!), ), ); } else { diff --git a/packages/image_picker/image_picker/example/pubspec.yaml b/packages/image_picker/image_picker/example/pubspec.yaml index 0ff2f280e2ab..44364a1c19e7 100755 --- a/packages/image_picker/image_picker/example/pubspec.yaml +++ b/packages/image_picker/image_picker/example/pubspec.yaml @@ -3,24 +3,23 @@ description: Demonstrates how to use the image_picker plugin. author: Flutter Team dependencies: - video_player: ^0.10.3 + video_player: ^2.0.0-nullsafety.7 flutter: sdk: flutter - flutter_plugin_android_lifecycle: ^1.0.2 + flutter_plugin_android_lifecycle: ^2.0.0-nullsafety.2 image_picker: path: ../ - image_picker_for_web: ^0.1.0 dev_dependencies: flutter_driver: sdk: flutter integration_test: path: ../../../integration_test - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.0.0-dev.28.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.10.0 <2.0.0" diff --git a/packages/image_picker/image_picker/integration_test/old_image_picker_test.dart b/packages/image_picker/image_picker/integration_test/old_image_picker_test.dart index d21a4e0cdfa3..76c971c2881b 100644 --- a/packages/image_picker/image_picker/integration_test/old_image_picker_test.dart +++ b/packages/image_picker/image_picker/integration_test/old_image_picker_test.dart @@ -1,3 +1,5 @@ +// @dart=2.9 + import 'package:integration_test/integration_test.dart'; void main() { diff --git a/packages/image_picker/image_picker/lib/image_picker.dart b/packages/image_picker/image_picker/lib/image_picker.dart index 5c0683c3f29f..22315100c961 100755 --- a/packages/image_picker/image_picker/lib/image_picker.dart +++ b/packages/image_picker/image_picker/lib/image_picker.dart @@ -5,7 +5,6 @@ // ignore_for_file: deprecated_member_use, deprecated_member_use_from_same_package import 'dart:async'; -import 'dart:io'; import 'package:flutter/foundation.dart'; @@ -18,7 +17,6 @@ export 'package:image_picker_platform_interface/image_picker_platform_interface. ImageSource, CameraDevice, LostData, - LostDataResponse, PickedFile, RetrieveType; @@ -29,46 +27,6 @@ class ImagePicker { @visibleForTesting static ImagePickerPlatform get platform => ImagePickerPlatform.instance; - /// Returns a [File] object pointing to the image that was picked. - /// - /// The returned [File] is intended to be used within a single APP session. Do not save the file path and use it across sessions. - /// - /// The `source` argument controls where the image comes from. This can - /// be either [ImageSource.camera] or [ImageSource.gallery]. - /// - /// If specified, the image will be at most `maxWidth` wide and - /// `maxHeight` tall. Otherwise the image will be returned at it's - /// original width and height. - /// The `imageQuality` argument modifies the quality of the image, ranging from 0-100 - /// where 100 is the original/max quality. If `imageQuality` is null, the image with - /// the original quality will be returned. Compression is only supportted for certain - /// image types such as JPEG. If compression is not supported for the image that is picked, - /// an warning message will be logged. - /// - /// Use `preferredCameraDevice` to specify the camera to use when the `source` is [ImageSource.camera]. - /// The `preferredCameraDevice` is ignored when `source` is [ImageSource.gallery]. It is also ignored if the chosen camera is not supported on the device. - /// Defaults to [CameraDevice.rear]. - /// - /// In Android, the MainActivity can be destroyed for various reasons. If that happens, the result will be lost - /// in this call. You can then call [retrieveLostData] when your app relaunches to retrieve the lost data. - @Deprecated('Use imagePicker.getImage() method instead.') - static Future pickImage( - {@required ImageSource source, - double maxWidth, - double maxHeight, - int imageQuality, - CameraDevice preferredCameraDevice = CameraDevice.rear}) async { - String path = await platform.pickImagePath( - source: source, - maxWidth: maxWidth, - maxHeight: maxHeight, - imageQuality: imageQuality, - preferredCameraDevice: preferredCameraDevice, - ); - - return path == null ? null : File(path); - } - /// Returns a [PickedFile] object wrapping the image that was picked. /// /// The returned [PickedFile] is intended to be used within a single APP session. Do not save the file path and use it across sessions. @@ -96,11 +54,11 @@ class ImagePicker { /// /// In Android, the MainActivity can be destroyed for various reasons. If that happens, the result will be lost /// in this call. You can then call [getLostData] when your app relaunches to retrieve the lost data. - Future getImage({ - @required ImageSource source, - double maxWidth, - double maxHeight, - int imageQuality, + Future getImage({ + required ImageSource source, + double? maxWidth, + double? maxHeight, + int? imageQuality, CameraDevice preferredCameraDevice = CameraDevice.rear, }) { return platform.pickImage( @@ -112,36 +70,6 @@ class ImagePicker { ); } - /// Returns a [File] object pointing to the video that was picked. - /// - /// The returned [File] is intended to be used within a single APP session. Do not save the file path and use it across sessions. - /// - /// The [source] argument controls where the video comes from. This can - /// be either [ImageSource.camera] or [ImageSource.gallery]. - /// - /// The [maxDuration] argument specifies the maximum duration of the captured video. If no [maxDuration] is specified, - /// the maximum duration will be infinite. - /// - /// Use `preferredCameraDevice` to specify the camera to use when the `source` is [ImageSource.camera]. - /// The `preferredCameraDevice` is ignored when `source` is [ImageSource.gallery]. It is also ignored if the chosen camera is not supported on the device. - /// Defaults to [CameraDevice.rear]. - /// - /// In Android, the MainActivity can be destroyed for various fo reasons. If that happens, the result will be lost - /// in this call. You can then call [retrieveLostData] when your app relaunches to retrieve the lost data. - @Deprecated('Use imagePicker.getVideo() method instead.') - static Future pickVideo( - {@required ImageSource source, - CameraDevice preferredCameraDevice = CameraDevice.rear, - Duration maxDuration}) async { - String path = await platform.pickVideoPath( - source: source, - preferredCameraDevice: preferredCameraDevice, - maxDuration: maxDuration, - ); - - return path == null ? null : File(path); - } - /// Returns a [PickedFile] object wrapping the video that was picked. /// /// The returned [PickedFile] is intended to be used within a single APP session. Do not save the file path and use it across sessions. @@ -158,10 +86,10 @@ class ImagePicker { /// /// In Android, the MainActivity can be destroyed for various fo reasons. If that happens, the result will be lost /// in this call. You can then call [getLostData] when your app relaunches to retrieve the lost data. - Future getVideo({ - @required ImageSource source, + Future getVideo({ + required ImageSource source, CameraDevice preferredCameraDevice = CameraDevice.rear, - Duration maxDuration, + Duration? maxDuration, }) { return platform.pickVideo( source: source, @@ -170,23 +98,6 @@ class ImagePicker { ); } - /// Retrieve the lost image file when [pickImage] or [pickVideo] failed because the MainActivity is destroyed. (Android only) - /// - /// Image or video can be lost if the MainActivity is destroyed. And there is no guarantee that the MainActivity is always alive. - /// Call this method to retrieve the lost data and process the data according to your APP's business logic. - /// - /// Returns a [LostDataResponse] if successfully retrieved the lost data. The [LostDataResponse] can represent either a - /// successful image/video selection, or a failure. - /// - /// Calling this on a non-Android platform will throw [UnimplementedError] exception. - /// - /// See also: - /// * [LostDataResponse], for what's included in the response. - /// * [Android Activity Lifecycle](https://developer.android.com/reference/android/app/Activity.html), for more information on MainActivity destruction. - static Future retrieveLostData() { - return platform.retrieveLostDataAsDartIoFile(); - } - /// Retrieve the lost [PickedFile] when [selectImage] or [selectVideo] failed because the MainActivity is destroyed. (Android only) /// /// Image or video can be lost if the MainActivity is destroyed. And there is no guarantee that the MainActivity is always alive. diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index 075c90627bf4..75f9dca4e0ca 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker description: Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker -version: 0.6.7+22 +version: 0.7.0-nullsafety flutter: plugin: @@ -16,19 +16,19 @@ flutter: dependencies: flutter: sdk: flutter - flutter_plugin_android_lifecycle: ^1.0.2 - image_picker_platform_interface: ^1.1.0 + flutter_plugin_android_lifecycle: ^2.0.0-nullsafety.2 + image_picker_platform_interface: ^2.0.0-nullsafety dev_dependencies: - video_player: ^0.10.3 + video_player: ^2.0.0-nullsafety.7 flutter_test: sdk: flutter integration_test: path: ../../integration_test - mockito: ^4.1.3 + mockito: ^5.0.0-nullsafety.7 pedantic: ^1.8.0 plugin_platform_interface: ^1.0.3 environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.10.0" diff --git a/packages/image_picker/image_picker/test/image_picker_test.dart b/packages/image_picker/image_picker/test/image_picker_test.dart index 7172975ded5d..0508d257016d 100644 --- a/packages/image_picker/image_picker/test/image_picker_test.dart +++ b/packages/image_picker/image_picker/test/image_picker_test.dart @@ -310,7 +310,7 @@ void main() { }); final LostData response = await picker.getLostData(); expect(response.type, RetrieveType.image); - expect(response.file.path, '/example/path'); + expect(response.file!.path, '/example/path'); }); test('retrieveLostData get error response', () async { @@ -323,8 +323,8 @@ void main() { }); final LostData response = await picker.getLostData(); expect(response.type, RetrieveType.video); - expect(response.exception.code, 'test_error_code'); - expect(response.exception.message, 'test_error_message'); + expect(response.exception!.code, 'test_error_code'); + expect(response.exception!.message, 'test_error_message'); }); test('retrieveLostData get null response', () async { diff --git a/packages/image_picker/image_picker/test/old_image_picker_test.dart b/packages/image_picker/image_picker/test/old_image_picker_test.dart deleted file mode 100644 index 8d4e068a261c..000000000000 --- a/packages/image_picker/image_picker/test/old_image_picker_test.dart +++ /dev/null @@ -1,340 +0,0 @@ -// Copyright 2019 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. - -// ignore_for_file: deprecated_member_use, deprecated_member_use_from_same_package - -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:image_picker/image_picker.dart'; - -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - - group('$ImagePicker', () { - const MethodChannel channel = - MethodChannel('plugins.flutter.io/image_picker'); - - final List log = []; - - setUp(() { - channel.setMockMethodCallHandler((MethodCall methodCall) async { - log.add(methodCall); - return ''; - }); - - log.clear(); - }); - - group('#pickImage', () { - test('passes the image source argument correctly', () async { - await ImagePicker.pickImage(source: ImageSource.camera); - await ImagePicker.pickImage(source: ImageSource.gallery); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0 - }), - isMethodCall('pickImage', arguments: { - 'source': 1, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0 - }), - ], - ); - }); - - test('passes the width and height arguments correctly', () async { - await ImagePicker.pickImage(source: ImageSource.camera); - await ImagePicker.pickImage( - source: ImageSource.camera, - maxWidth: 10.0, - ); - await ImagePicker.pickImage( - source: ImageSource.camera, - maxHeight: 10.0, - ); - await ImagePicker.pickImage( - source: ImageSource.camera, - maxWidth: 10.0, - maxHeight: 20.0, - ); - await ImagePicker.pickImage( - source: ImageSource.camera, maxWidth: 10.0, imageQuality: 70); - await ImagePicker.pickImage( - source: ImageSource.camera, maxHeight: 10.0, imageQuality: 70); - await ImagePicker.pickImage( - source: ImageSource.camera, - maxWidth: 10.0, - maxHeight: 20.0, - imageQuality: 70); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0 - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0 - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': 10.0, - 'imageQuality': null, - 'cameraDevice': 0 - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': 20.0, - 'imageQuality': null, - 'cameraDevice': 0 - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': null, - 'imageQuality': 70, - 'cameraDevice': 0 - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': 10.0, - 'imageQuality': 70, - 'cameraDevice': 0 - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': 20.0, - 'imageQuality': 70, - 'cameraDevice': 0 - }), - ], - ); - }); - - test('does not accept a negative width or height argument', () { - expect( - ImagePicker.pickImage(source: ImageSource.camera, maxWidth: -1.0), - throwsArgumentError, - ); - - expect( - ImagePicker.pickImage(source: ImageSource.camera, maxHeight: -1.0), - throwsArgumentError, - ); - }); - - test('handles a null image path response gracefully', () async { - channel.setMockMethodCallHandler((MethodCall methodCall) => null); - - expect( - await ImagePicker.pickImage(source: ImageSource.gallery), isNull); - expect(await ImagePicker.pickImage(source: ImageSource.camera), isNull); - }); - - test('camera position defaults to back', () async { - await ImagePicker.pickImage(source: ImageSource.camera); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0, - }), - ], - ); - }); - - test('camera position can set to front', () async { - await ImagePicker.pickImage( - source: ImageSource.camera, - preferredCameraDevice: CameraDevice.front); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 1, - }), - ], - ); - }); - }); - - group('#pickVideo', () { - test('passes the image source argument correctly', () async { - await ImagePicker.pickVideo(source: ImageSource.camera); - await ImagePicker.pickVideo(source: ImageSource.gallery); - - expect( - log, - [ - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'cameraDevice': 0, - 'maxDuration': null, - }), - isMethodCall('pickVideo', arguments: { - 'source': 1, - 'cameraDevice': 0, - 'maxDuration': null, - }), - ], - ); - }); - - test('passes the duration argument correctly', () async { - await ImagePicker.pickVideo(source: ImageSource.camera); - await ImagePicker.pickVideo( - source: ImageSource.camera, - maxDuration: const Duration(seconds: 10)); - await ImagePicker.pickVideo( - source: ImageSource.camera, - maxDuration: const Duration(minutes: 1)); - await ImagePicker.pickVideo( - source: ImageSource.camera, maxDuration: const Duration(hours: 1)); - expect( - log, - [ - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': null, - 'cameraDevice': 0, - }), - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': 10, - 'cameraDevice': 0, - }), - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': 60, - 'cameraDevice': 0, - }), - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': 3600, - 'cameraDevice': 0, - }), - ], - ); - }); - - test('handles a null video path response gracefully', () async { - channel.setMockMethodCallHandler((MethodCall methodCall) => null); - - expect( - await ImagePicker.pickVideo(source: ImageSource.gallery), isNull); - expect(await ImagePicker.pickVideo(source: ImageSource.camera), isNull); - }); - - test('camera position defaults to back', () async { - await ImagePicker.pickVideo(source: ImageSource.camera); - - expect( - log, - [ - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'cameraDevice': 0, - 'maxDuration': null, - }), - ], - ); - }); - - test('camera position can set to front', () async { - await ImagePicker.pickVideo( - source: ImageSource.camera, - preferredCameraDevice: CameraDevice.front); - - expect( - log, - [ - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': null, - 'cameraDevice': 1, - }), - ], - ); - }); - }); - - group('#retrieveLostData', () { - test('retrieveLostData get success response', () async { - channel.setMockMethodCallHandler((MethodCall methodCall) async { - return { - 'type': 'image', - 'path': '/example/path', - }; - }); - final LostDataResponse response = await ImagePicker.retrieveLostData(); - expect(response.type, RetrieveType.image); - expect(response.file.path, '/example/path'); - }); - - test('retrieveLostData get error response', () async { - channel.setMockMethodCallHandler((MethodCall methodCall) async { - return { - 'type': 'video', - 'errorCode': 'test_error_code', - 'errorMessage': 'test_error_message', - }; - }); - final LostDataResponse response = await ImagePicker.retrieveLostData(); - expect(response.type, RetrieveType.video); - expect(response.exception.code, 'test_error_code'); - expect(response.exception.message, 'test_error_message'); - }); - - test('retrieveLostData get null response', () async { - channel.setMockMethodCallHandler((MethodCall methodCall) async { - return null; - }); - expect((await ImagePicker.retrieveLostData()).isEmpty, true); - }); - - test('retrieveLostData get both path and error should throw', () async { - channel.setMockMethodCallHandler((MethodCall methodCall) async { - return { - 'type': 'video', - 'errorCode': 'test_error_code', - 'errorMessage': 'test_error_message', - 'path': '/example/path', - }; - }); - expect(ImagePicker.retrieveLostData(), throwsAssertionError); - }); - }); - }); -} From 7adfc2f7cd1276d1dfaf630a965df264c56ff1d7 Mon Sep 17 00:00:00 2001 From: Darshan Rander Date: Mon, 8 Feb 2021 21:12:26 +0530 Subject: [PATCH 0105/1565] [file_selector_platform_interface] File selector nnbd (#3509) Migrating file_selector_interface to null-safety --- .../CHANGELOG.md | 4 ++ .../method_channel_file_selector.dart | 44 +++++++++---------- .../file_selector_interface.dart | 33 +++++++------- .../src/types/x_type_group/x_type_group.dart | 10 ++--- .../lib/src/web_helpers/web_helpers.dart | 4 +- .../pubspec.yaml | 12 ++--- .../file_selector_web/pubspec.yaml | 4 +- script/nnbd_plugins.sh | 2 +- 8 files changed, 60 insertions(+), 53 deletions(-) diff --git a/packages/file_selector/file_selector_platform_interface/CHANGELOG.md b/packages/file_selector/file_selector_platform_interface/CHANGELOG.md index aafe4db278d8..2fbe18db7bfd 100644 --- a/packages/file_selector/file_selector_platform_interface/CHANGELOG.md +++ b/packages/file_selector/file_selector_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.0 + +* Migration to null-safety + ## 1.0.3+1 * Bump the [cross_file](https://pub.dev/packages/cross_file) package version. diff --git a/packages/file_selector/file_selector_platform_interface/lib/src/method_channel/method_channel_file_selector.dart b/packages/file_selector/file_selector_platform_interface/lib/src/method_channel/method_channel_file_selector.dart index 586b1abcae1e..e14239f51690 100644 --- a/packages/file_selector/file_selector_platform_interface/lib/src/method_channel/method_channel_file_selector.dart +++ b/packages/file_selector/file_selector_platform_interface/lib/src/method_channel/method_channel_file_selector.dart @@ -19,57 +19,57 @@ class MethodChannelFileSelector extends FileSelectorPlatform { /// Load a file from user's computer and return it as an XFile @override - Future openFile({ - List acceptedTypeGroups, - String initialDirectory, - String confirmButtonText, + Future openFile({ + List? acceptedTypeGroups, + String? initialDirectory, + String? confirmButtonText, }) async { - final List path = await _channel.invokeListMethod( + final List? path = await _channel.invokeListMethod( 'openFile', { 'acceptedTypeGroups': - acceptedTypeGroups?.map((group) => group.toJSON())?.toList(), + acceptedTypeGroups?.map((group) => group.toJSON()).toList(), 'initialDirectory': initialDirectory, 'confirmButtonText': confirmButtonText, 'multiple': false, }, ); - return path == null ? null : XFile(path?.first); + return path == null ? null : XFile(path.first); } /// Load multiple files from user's computer and return it as an XFile @override Future> openFiles({ - List acceptedTypeGroups, - String initialDirectory, - String confirmButtonText, + List? acceptedTypeGroups, + String? initialDirectory, + String? confirmButtonText, }) async { - final List pathList = await _channel.invokeListMethod( + final List? pathList = await _channel.invokeListMethod( 'openFile', { 'acceptedTypeGroups': - acceptedTypeGroups?.map((group) => group.toJSON())?.toList(), + acceptedTypeGroups?.map((group) => group.toJSON()).toList(), 'initialDirectory': initialDirectory, 'confirmButtonText': confirmButtonText, 'multiple': true, }, ); - return pathList?.map((path) => XFile(path))?.toList() ?? []; + return pathList?.map((path) => XFile(path)).toList() ?? []; } /// Gets the path from a save dialog @override - Future getSavePath({ - List acceptedTypeGroups, - String initialDirectory, - String suggestedName, - String confirmButtonText, + Future getSavePath({ + List? acceptedTypeGroups, + String? initialDirectory, + String? suggestedName, + String? confirmButtonText, }) async { return _channel.invokeMethod( 'getSavePath', { 'acceptedTypeGroups': - acceptedTypeGroups?.map((group) => group.toJSON())?.toList(), + acceptedTypeGroups?.map((group) => group.toJSON()).toList(), 'initialDirectory': initialDirectory, 'suggestedName': suggestedName, 'confirmButtonText': confirmButtonText, @@ -79,9 +79,9 @@ class MethodChannelFileSelector extends FileSelectorPlatform { /// Gets a directory path from a dialog @override - Future getDirectoryPath({ - String initialDirectory, - String confirmButtonText, + Future getDirectoryPath({ + String? initialDirectory, + String? confirmButtonText, }) async { return _channel.invokeMethod( 'getDirectoryPath', diff --git a/packages/file_selector/file_selector_platform_interface/lib/src/platform_interface/file_selector_interface.dart b/packages/file_selector/file_selector_platform_interface/lib/src/platform_interface/file_selector_interface.dart index e7b32631a58b..0be02c2185dd 100644 --- a/packages/file_selector/file_selector_platform_interface/lib/src/platform_interface/file_selector_interface.dart +++ b/packages/file_selector/file_selector_platform_interface/lib/src/platform_interface/file_selector_interface.dart @@ -38,37 +38,40 @@ abstract class FileSelectorPlatform extends PlatformInterface { } /// Open file dialog for loading files and return a file path - Future openFile({ - List acceptedTypeGroups, - String initialDirectory, - String confirmButtonText, + /// Returns `null` if user cancels the operation. + Future openFile({ + List? acceptedTypeGroups, + String? initialDirectory, + String? confirmButtonText, }) { throw UnimplementedError('openFile() has not been implemented.'); } /// Open file dialog for loading files and return a list of file paths Future> openFiles({ - List acceptedTypeGroups, - String initialDirectory, - String confirmButtonText, + List? acceptedTypeGroups, + String? initialDirectory, + String? confirmButtonText, }) { throw UnimplementedError('openFiles() has not been implemented.'); } /// Open file dialog for saving files and return a file path at which to save - Future getSavePath({ - List acceptedTypeGroups, - String initialDirectory, - String suggestedName, - String confirmButtonText, + /// Returns `null` if user cancels the operation. + Future getSavePath({ + List? acceptedTypeGroups, + String? initialDirectory, + String? suggestedName, + String? confirmButtonText, }) { throw UnimplementedError('getSavePath() has not been implemented.'); } /// Open file dialog for loading directories and return a directory path - Future getDirectoryPath({ - String initialDirectory, - String confirmButtonText, + /// Returns `null` if user cancels the operation. + Future getDirectoryPath({ + String? initialDirectory, + String? confirmButtonText, }) { throw UnimplementedError('getDirectoryPath() has not been implemented.'); } diff --git a/packages/file_selector/file_selector_platform_interface/lib/src/types/x_type_group/x_type_group.dart b/packages/file_selector/file_selector_platform_interface/lib/src/types/x_type_group/x_type_group.dart index fb591f2b248a..f3f05e2ab3a6 100644 --- a/packages/file_selector/file_selector_platform_interface/lib/src/types/x_type_group/x_type_group.dart +++ b/packages/file_selector/file_selector_platform_interface/lib/src/types/x_type_group/x_type_group.dart @@ -17,19 +17,19 @@ class XTypeGroup { }); /// The 'name' or reference to this group of types - final String label; + final String? label; /// The extensions for this group - final List extensions; + final List? extensions; /// The MIME types for this group - final List mimeTypes; + final List? mimeTypes; /// The UTIs for this group - final List macUTIs; + final List? macUTIs; /// The web wild cards for this group (ex: image/*, video/*) - final List webWildCards; + final List? webWildCards; /// Converts this object into a JSON formatted object Map toJSON() { diff --git a/packages/file_selector/file_selector_platform_interface/lib/src/web_helpers/web_helpers.dart b/packages/file_selector/file_selector_platform_interface/lib/src/web_helpers/web_helpers.dart index 9e40e562bc9a..5330c5cf6dcd 100644 --- a/packages/file_selector/file_selector_platform_interface/lib/src/web_helpers/web_helpers.dart +++ b/packages/file_selector/file_selector_platform_interface/lib/src/web_helpers/web_helpers.dart @@ -1,7 +1,7 @@ import 'dart:html'; /// Create anchor element with download attribute -AnchorElement createAnchorElement(String href, String suggestedName) { +AnchorElement createAnchorElement(String href, String? suggestedName) { final element = AnchorElement(href: href); if (suggestedName == null) { @@ -27,7 +27,7 @@ Element ensureInitialized(String id) { if (target == null) { final Element targetElement = Element.tag('flt-x-file')..id = id; - querySelector('body').children.add(targetElement); + querySelector('body')!.children.add(targetElement); target = targetElement; } return target; diff --git a/packages/file_selector/file_selector_platform_interface/pubspec.yaml b/packages/file_selector/file_selector_platform_interface/pubspec.yaml index f1d0038a5062..9735bced03fb 100644 --- a/packages/file_selector/file_selector_platform_interface/pubspec.yaml +++ b/packages/file_selector/file_selector_platform_interface/pubspec.yaml @@ -3,23 +3,23 @@ description: A common platform interface for the file_selector plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/file_selector/file_selector_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.0.3+1 +version: 2.0.0-nullsafety.0 dependencies: flutter: sdk: flutter meta: ^1.0.5 - http: ^0.12.0+1 - plugin_platform_interface: ^1.0.1 - cross_file: ^0.2.0 + http: ^0.13.0-nullsafety.0 + plugin_platform_interface: ^1.1.0-nullsafety.2 + cross_file: ^0.3.0-nullsafety dev_dependencies: test: ^1.15.0 flutter_test: sdk: flutter - mockito: ^4.1.1 + mockito: ^5.0.0-nullsafety.5 pedantic: ^1.8.0 environment: - sdk: ">=2.1.0 <3.0.0" + sdk: '>=2.12.0-0 <3.0.0' flutter: ">=1.9.1+hotfix.4" diff --git a/packages/file_selector/file_selector_web/pubspec.yaml b/packages/file_selector/file_selector_web/pubspec.yaml index a170d5f39607..79181e821cec 100644 --- a/packages/file_selector/file_selector_web/pubspec.yaml +++ b/packages/file_selector/file_selector_web/pubspec.yaml @@ -22,8 +22,8 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - mockito: ^4.1.1 - pedantic: ^1.8.0 + mockito: ^5.0.0-nullsafety.5 + pedantic: ^1.10.0-nullsafety.3 integration_test: path: ../../integration_test diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index 742487ad7bfa..1e57db96a648 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -10,6 +10,7 @@ readonly NNBD_PLUGINS_LIST=( "connectivity" "cross_file" "device_info" + "file_selector" "flutter_plugin_android_lifecycle" "flutter_webview" "google_sign_in" @@ -32,7 +33,6 @@ readonly NNBD_PLUGINS_LIST=( readonly NON_NNBD_PLUGINS_LIST=( # "android_alarm_manager" "camera" - # "file_selector" # "google_maps_flutter" # "image_picker" # "in_app_purchase" From 2b6addf678a204d3f09c974e34b49d5b3eb866c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan?= Date: Mon, 8 Feb 2021 19:59:25 +0100 Subject: [PATCH 0106/1565] [shared_preferences] Migrate platform plugins to null-safety (#3523) Migrates shared_preferences_linux and shared_preferences_web to null-safety. --- .../shared_preferences_linux/CHANGELOG.md | 4 + .../shared_preferences_test.dart | 87 ++++++++++--------- .../example/pubspec.yaml | 7 -- .../lib/shared_preferences_linux.dart | 23 +++-- .../shared_preferences_linux/pubspec.yaml | 12 +-- .../test/shared_preferences_linux_test.dart | 6 +- .../shared_preferences_web/CHANGELOG.md | 4 + .../lib/shared_preferences_web.dart | 21 ++--- .../shared_preferences_web/pubspec.yaml | 6 +- .../test/shared_preferences_web_test.dart | 6 +- 10 files changed, 93 insertions(+), 83 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md b/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md index 9821b79c5cc2..2be9c8ca075a 100644 --- a/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.4-nullsafety + +* Migrate to null-safety. + ## 0.0.3+1 * Update Flutter SDK constraint. diff --git a/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart index e43d4e3ae0c2..3aedccd0feba 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart @@ -1,12 +1,13 @@ import 'dart:async'; + import 'package:flutter_test/flutter_test.dart'; -import 'package:shared_preferences/shared_preferences.dart'; import 'package:integration_test/integration_test.dart'; +import 'package:shared_preferences_linux/shared_preferences_linux.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - group('$SharedPreferences', () { + group('SharedPreferencesLinux', () { const Map kTestValues = { 'flutter.String': 'hello world', 'flutter.bool': true, @@ -23,10 +24,10 @@ void main() { 'flutter.List': ['baz', 'quox'], }; - SharedPreferences preferences; + SharedPreferencesLinux preferences; setUp(() async { - preferences = await SharedPreferences.getInstance(); + preferences = SharedPreferencesLinux.instance; }); tearDown(() { @@ -34,56 +35,62 @@ void main() { }); testWidgets('reading', (WidgetTester _) async { - expect(preferences.get('String'), isNull); - expect(preferences.get('bool'), isNull); - expect(preferences.get('int'), isNull); - expect(preferences.get('double'), isNull); - expect(preferences.get('List'), isNull); - expect(preferences.getString('String'), isNull); - expect(preferences.getBool('bool'), isNull); - expect(preferences.getInt('int'), isNull); - expect(preferences.getDouble('double'), isNull); - expect(preferences.getStringList('List'), isNull); + final all = await preferences.getAll(); + expect(all['String'], isNull); + expect(all['bool'], isNull); + expect(all['int'], isNull); + expect(all['double'], isNull); + expect(all['List'], isNull); }); testWidgets('writing', (WidgetTester _) async { await Future.wait(>[ - preferences.setString('String', kTestValues2['flutter.String']), - preferences.setBool('bool', kTestValues2['flutter.bool']), - preferences.setInt('int', kTestValues2['flutter.int']), - preferences.setDouble('double', kTestValues2['flutter.double']), - preferences.setStringList('List', kTestValues2['flutter.List']) + preferences.setValue( + 'String', 'String', kTestValues2['flutter.String']), + preferences.setValue('Bool', 'bool', kTestValues2['flutter.bool']), + preferences.setValue('Int', 'int', kTestValues2['flutter.int']), + preferences.setValue( + 'Double', 'double', kTestValues2['flutter.double']), + preferences.setValue('StringList', 'List', kTestValues2['flutter.List']) ]); - expect(preferences.getString('String'), kTestValues2['flutter.String']); - expect(preferences.getBool('bool'), kTestValues2['flutter.bool']); - expect(preferences.getInt('int'), kTestValues2['flutter.int']); - expect(preferences.getDouble('double'), kTestValues2['flutter.double']); - expect(preferences.getStringList('List'), kTestValues2['flutter.List']); + final all = await preferences.getAll(); + expect(all['String'], kTestValues2['flutter.String']); + expect(all['bool'], kTestValues2['flutter.bool']); + expect(all['int'], kTestValues2['flutter.int']); + expect(all['double'], kTestValues2['flutter.double']); + expect(all['List'], kTestValues2['flutter.List']); }); testWidgets('removing', (WidgetTester _) async { const String key = 'testKey'; - await preferences.setString(key, kTestValues['flutter.String']); - await preferences.setBool(key, kTestValues['flutter.bool']); - await preferences.setInt(key, kTestValues['flutter.int']); - await preferences.setDouble(key, kTestValues['flutter.double']); - await preferences.setStringList(key, kTestValues['flutter.List']); + + await Future.wait([ + preferences.setValue('String', key, kTestValues['flutter.String']), + preferences.setValue('Bool', key, kTestValues['flutter.bool']), + preferences.setValue('Int', key, kTestValues['flutter.int']), + preferences.setValue('Double', key, kTestValues['flutter.double']), + preferences.setValue('StringList', key, kTestValues['flutter.List']) + ]); await preferences.remove(key); - expect(preferences.get('testKey'), isNull); + final all = await preferences.getAll(); + expect(all['testKey'], isNull); }); testWidgets('clearing', (WidgetTester _) async { - await preferences.setString('String', kTestValues['flutter.String']); - await preferences.setBool('bool', kTestValues['flutter.bool']); - await preferences.setInt('int', kTestValues['flutter.int']); - await preferences.setDouble('double', kTestValues['flutter.double']); - await preferences.setStringList('List', kTestValues['flutter.List']); + await Future.wait(>[ + preferences.setValue('String', 'String', kTestValues['flutter.String']), + preferences.setValue('Bool', 'bool', kTestValues['flutter.bool']), + preferences.setValue('Int', 'int', kTestValues['flutter.int']), + preferences.setValue('Double', 'double', kTestValues['flutter.double']), + preferences.setValue('StringList', 'List', kTestValues['flutter.List']) + ]); await preferences.clear(); - expect(preferences.getString('String'), null); - expect(preferences.getBool('bool'), null); - expect(preferences.getInt('int'), null); - expect(preferences.getDouble('double'), null); - expect(preferences.getStringList('List'), null); + final all = await preferences.getAll(); + expect(all['String'], null); + expect(all['bool'], null); + expect(all['int'], null); + expect(all['double'], null); + expect(all['List'], null); }); }); } diff --git a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml index fb79444dc6cd..591aad4c2c57 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml @@ -4,15 +4,8 @@ description: Demonstrates how to use the shared_preferences_linux plugin. dependencies: flutter: sdk: flutter - shared_preferences: any - shared_preferences_linux: ^0.1.0 - -dependency_overrides: shared_preferences_linux: path: ../ - # Remove this override once the endorsement is published. - shared_preferences: - path: ../../shared_preferences/ dev_dependencies: flutter_driver: diff --git a/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart b/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart index c975ad1a7544..5a694658cdf5 100644 --- a/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart +++ b/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart @@ -20,16 +20,17 @@ class SharedPreferencesLinux extends SharedPreferencesStorePlatform { static SharedPreferencesLinux instance = SharedPreferencesLinux(); /// Local copy of preferences - Map _cachedPreferences; + Map? _cachedPreferences; /// File system used to store to disk. Exposed for testing only. @visibleForTesting FileSystem fs = LocalFileSystem(); /// Gets the file where the preferences are stored. - Future _getLocalDataFile() async { + Future _getLocalDataFile() async { final pathProvider = PathProviderLinux(); final directory = await pathProvider.getApplicationSupportPath(); + if (directory == null) return null; return fs.file(path.join(directory, 'shared_preferences.json')); } @@ -37,19 +38,19 @@ class SharedPreferencesLinux extends SharedPreferencesStorePlatform { /// maintained in memory. Future> _readPreferences() async { if (_cachedPreferences != null) { - return _cachedPreferences; + return _cachedPreferences!; } - _cachedPreferences = {}; - var localDataFile = await _getLocalDataFile(); - if (localDataFile.existsSync()) { + Map preferences = {}; + final File? localDataFile = await _getLocalDataFile(); + if (localDataFile != null && localDataFile.existsSync()) { String stringMap = localDataFile.readAsStringSync(); if (stringMap.isNotEmpty) { - _cachedPreferences = json.decode(stringMap) as Map; + preferences = json.decode(stringMap).cast(); } } - - return _cachedPreferences; + _cachedPreferences = preferences; + return preferences; } /// Writes the cached preferences to disk. Returns [true] if the operation @@ -57,6 +58,10 @@ class SharedPreferencesLinux extends SharedPreferencesStorePlatform { Future _writePreferences(Map preferences) async { try { var localDataFile = await _getLocalDataFile(); + if (localDataFile == null) { + print("Unable to determine where to write preferences."); + return false; + } if (!localDataFile.existsSync()) { localDataFile.createSync(recursive: true); } diff --git a/packages/shared_preferences/shared_preferences_linux/pubspec.yaml b/packages/shared_preferences/shared_preferences_linux/pubspec.yaml index 50709aac5f8a..df4b5db23b7f 100644 --- a/packages/shared_preferences/shared_preferences_linux/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_linux/pubspec.yaml @@ -1,6 +1,6 @@ name: shared_preferences_linux description: Linux implementation of the shared_preferences plugin -version: 0.0.3+1 +version: 0.0.4-nullsafety homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_linux flutter: @@ -11,17 +11,17 @@ flutter: pluginClass: none environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.12.8" dependencies: - file: ">=5.1.0 <7.0.0" flutter: sdk: flutter + file: ^6.0.0-nullsafety.4 meta: ^1.0.4 - path: ^1.6.4 - path_provider_linux: ^0.0.1 - shared_preferences_platform_interface: ^1.0.0 + path: ^1.8.0-nullsafety.3 + path_provider_linux: ^0.2.0-nullsafety + shared_preferences_platform_interface: ^2.0.0-nullsafety dev_dependencies: flutter_test: diff --git a/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart b/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart index 8c659f212aa5..cf0bc80e3ec2 100644 --- a/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart +++ b/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart @@ -7,9 +7,9 @@ import 'package:path/path.dart' as path; import 'package:path_provider_linux/path_provider_linux.dart'; import 'package:shared_preferences_linux/shared_preferences_linux.dart'; -MemoryFileSystem fs; - void main() { + late MemoryFileSystem fs; + setUp(() { fs = MemoryFileSystem.test(); }); @@ -19,7 +19,7 @@ void main() { Future _getFilePath() async { final pathProvider = PathProviderLinux(); final directory = await pathProvider.getApplicationSupportPath(); - return path.join(directory, 'shared_preferences.json'); + return path.join(directory!, 'shared_preferences.json'); } _writeTestFile(String value) async { diff --git a/packages/shared_preferences/shared_preferences_web/CHANGELOG.md b/packages/shared_preferences/shared_preferences_web/CHANGELOG.md index 2ba877856da6..0194ef8ade37 100644 --- a/packages/shared_preferences/shared_preferences_web/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_web/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.0-nullsafety + +* Migrate to null-safety. + ## 0.1.2+8 * Update Flutter SDK constraint. diff --git a/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart b/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart index 8a0f137ddcc8..346877e8a120 100644 --- a/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart +++ b/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart @@ -14,7 +14,7 @@ import 'package:shared_preferences_platform_interface/shared_preferences_platfor /// This class implements the `package:shared_preferences` functionality for the web. class SharedPreferencesPlugin extends SharedPreferencesStorePlatform { /// Registers this class as the default instance of [SharedPreferencesStorePlatform]. - static void registerWith(Registrar registrar) { + static void registerWith(Registrar? registrar) { SharedPreferencesStorePlatform.instance = SharedPreferencesPlugin(); } @@ -31,9 +31,9 @@ class SharedPreferencesPlugin extends SharedPreferencesStorePlatform { @override Future> getAll() async { - final Map allData = {}; + final Map allData = {}; for (String key in _storedFlutterKeys) { - allData[key] = _decodeValue(html.window.localStorage[key]); + allData[key] = _decodeValue(html.window.localStorage[key]!); } return allData; } @@ -46,7 +46,7 @@ class SharedPreferencesPlugin extends SharedPreferencesStorePlatform { } @override - Future setValue(String valueType, String key, Object value) async { + Future setValue(String valueType, String key, Object? value) async { _checkPrefix(key); html.window.localStorage[key] = _encodeValue(value); return true; @@ -62,17 +62,12 @@ class SharedPreferencesPlugin extends SharedPreferencesStorePlatform { } } - List get _storedFlutterKeys { - final List keys = []; - for (String key in html.window.localStorage.keys) { - if (key.startsWith('flutter.')) { - keys.add(key); - } - } - return keys; + Iterable get _storedFlutterKeys { + return html.window.localStorage.keys + .where((key) => key.startsWith('flutter.')); } - String _encodeValue(Object value) { + String _encodeValue(Object? value) { return json.encode(value); } diff --git a/packages/shared_preferences/shared_preferences_web/pubspec.yaml b/packages/shared_preferences/shared_preferences_web/pubspec.yaml index d657b2300727..60892bcf277c 100644 --- a/packages/shared_preferences/shared_preferences_web/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_web/pubspec.yaml @@ -4,7 +4,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/shared_prefere # 0.1.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.1.2+8 +version: 0.2.0-nullsafety flutter: plugin: @@ -14,7 +14,7 @@ flutter: fileName: shared_preferences_web.dart dependencies: - shared_preferences_platform_interface: ^1.0.0 + shared_preferences_platform_interface: ^2.0.0-nullsafety flutter: sdk: flutter flutter_web_plugins: @@ -27,5 +27,5 @@ dev_dependencies: pedantic: ^1.8.0 environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.12.13+hotfix.4" diff --git a/packages/shared_preferences/shared_preferences_web/test/shared_preferences_web_test.dart b/packages/shared_preferences/shared_preferences_web/test/shared_preferences_web_test.dart index 951f04cbce5a..c0cf92cc1bf0 100644 --- a/packages/shared_preferences/shared_preferences_web/test/shared_preferences_web_test.dart +++ b/packages/shared_preferences/shared_preferences_web/test/shared_preferences_web_test.dart @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@TestOn('chrome') // Uses web-only Flutter SDK - +@TestOn('chrome') import 'dart:convert' show json; import 'dart:html' as html; import 'package:flutter_test/flutter_test.dart'; +import 'package:shared_preferences_platform_interface/method_channel_shared_preferences.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; import 'package:shared_preferences_web/shared_preferences_web.dart'; @@ -26,6 +26,8 @@ void main() { }); test('registers itself', () { + SharedPreferencesStorePlatform.instance = + MethodChannelSharedPreferencesStore(); expect(SharedPreferencesStorePlatform.instance, isNot(isA())); SharedPreferencesPlugin.registerWith(null); From 545c97f30ebec77d8baead2df87ef52c12bb2e69 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Mon, 8 Feb 2021 21:15:45 +0100 Subject: [PATCH 0107/1565] [camera_platform_interface] Migrate to null safety (#3497) --- .../camera_platform_interface/CHANGELOG.md | 4 + .../lib/src/events/camera_event.dart | 10 +- .../method_channel/method_channel_camera.dart | 165 +++++++++++------- .../platform_interface/camera_platform.dart | 22 ++- .../lib/src/types/camera_description.dart | 6 +- .../lib/src/types/camera_exception.dart | 2 +- .../lib/src/types/exposure_mode.dart | 2 - .../lib/src/types/focus_mode.dart | 2 - .../camera_platform_interface/pubspec.yaml | 18 +- .../test/camera_platform_interface_test.dart | 23 ++- .../method_channel_camera_test.dart | 52 ++++-- .../test/utils/method_channel_mock.dart | 6 +- script/nnbd_plugins.sh | 1 + 13 files changed, 205 insertions(+), 108 deletions(-) diff --git a/packages/camera/camera_platform_interface/CHANGELOG.md b/packages/camera/camera_platform_interface/CHANGELOG.md index ff739918c53b..ab3d559bf2fb 100644 --- a/packages/camera/camera_platform_interface/CHANGELOG.md +++ b/packages/camera/camera_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +- Migrate to null safety. + ## 1.6.0 - Added VideoRecordedEvent to support ending a video recording in the native implementation. diff --git a/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart b/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart index ad9958381143..20aa41c5ce40 100644 --- a/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart +++ b/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart @@ -70,12 +70,12 @@ class CameraInitializedEvent extends CameraEvent { CameraInitializedEvent( int cameraId, this.previewWidth, - this.previewHeight, [ + this.previewHeight, this.exposureMode, - this.exposurePointSupported = false, + this.exposurePointSupported, this.focusMode, - this.focusPointSupported = false, - ]) : super(cameraId); + this.focusPointSupported, + ) : super(cameraId); /// Converts the supplied [Map] to an instance of the [CameraInitializedEvent] /// class. @@ -242,7 +242,7 @@ class VideoRecordedEvent extends CameraEvent { final XFile file; /// Maximum duration of the recorded video. - final Duration maxVideoDuration; + final Duration? maxVideoDuration; /// Build a VideoRecordedEvent triggered from the camera with the `cameraId`. /// diff --git a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart index 36a2c92645f2..3537a5ca40a9 100644 --- a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart +++ b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart @@ -11,6 +11,7 @@ import 'package:camera_platform_interface/src/types/focus_mode.dart'; import 'package:camera_platform_interface/src/types/image_format_group.dart'; import 'package:camera_platform_interface/src/utils/utils.dart'; import 'package:cross_file/cross_file.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:meta/meta.dart'; @@ -58,8 +59,13 @@ class MethodChannelCamera extends CameraPlatform { @override Future> availableCameras() async { try { - final List> cameras = await _channel + final cameras = await _channel .invokeListMethod>('availableCameras'); + + if (cameras == null) { + return []; + } + return cameras.map((Map camera) { return CameraDescription( name: camera['name'], @@ -75,30 +81,30 @@ class MethodChannelCamera extends CameraPlatform { @override Future createCamera( CameraDescription cameraDescription, - ResolutionPreset resolutionPreset, { - bool enableAudio, + ResolutionPreset? resolutionPreset, { + bool enableAudio = true, }) async { try { - final Map reply = - await _channel.invokeMapMethod( - 'create', - { - 'cameraName': cameraDescription.name, - 'resolutionPreset': resolutionPreset != null - ? _serializeResolutionPreset(resolutionPreset) - : null, - 'enableAudio': enableAudio, - }, - ); - return reply['cameraId']; + final reply = await _channel + .invokeMapMethod('create', { + 'cameraName': cameraDescription.name, + 'resolutionPreset': resolutionPreset != null + ? _serializeResolutionPreset(resolutionPreset) + : null, + 'enableAudio': enableAudio, + }); + + return reply!['cameraId']; } on PlatformException catch (e) { throw CameraException(e.code, e.message); } } @override - Future initializeCamera(int cameraId, - {ImageFormatGroup imageFormatGroup}) { + Future initializeCamera( + int cameraId, { + ImageFormatGroup imageFormatGroup = ImageFormatGroup.unknown, + }) { _channels.putIfAbsent(cameraId, () { final channel = MethodChannel('flutter.io/cameraPlugin/camera$cameraId'); channel.setMethodCallHandler( @@ -125,15 +131,16 @@ class MethodChannelCamera extends CameraPlatform { @override Future dispose(int cameraId) async { + if (_channels.containsKey(cameraId)) { + final cameraChannel = _channels[cameraId]; + cameraChannel?.setMethodCallHandler(null); + _channels.remove(cameraId); + } + await _channel.invokeMethod( 'dispose', {'cameraId': cameraId}, ); - - if (_channels.containsKey(cameraId)) { - _channels[cameraId].setMethodCallHandler(null); - _channels.remove(cameraId); - } } @override @@ -169,7 +176,9 @@ class MethodChannelCamera extends CameraPlatform { @override Future lockCaptureOrientation( - int cameraId, DeviceOrientation orientation) async { + int cameraId, + DeviceOrientation orientation, + ) async { await _channel.invokeMethod( 'lockCaptureOrientation', { @@ -189,10 +198,18 @@ class MethodChannelCamera extends CameraPlatform { @override Future takePicture(int cameraId) async { - String path = await _channel.invokeMethod( + final path = await _channel.invokeMethod( 'takePicture', {'cameraId': cameraId}, ); + + if (path == null) { + throw CameraException( + 'INVALID_PATH', + 'The platform "$defaultTargetPlatform" did not return a path while reporting success. The platform should always return a valid path or report an error.', + ); + } + return XFile(path); } @@ -202,7 +219,7 @@ class MethodChannelCamera extends CameraPlatform { @override Future startVideoRecording(int cameraId, - {Duration maxVideoDuration}) async { + {Duration? maxVideoDuration}) async { await _channel.invokeMethod( 'startVideoRecording', { @@ -214,10 +231,18 @@ class MethodChannelCamera extends CameraPlatform { @override Future stopVideoRecording(int cameraId) async { - String path = await _channel.invokeMethod( + final path = await _channel.invokeMethod( 'stopVideoRecording', {'cameraId': cameraId}, ); + + if (path == null) { + throw CameraException( + 'INVALID_PATH', + 'The platform "$defaultTargetPlatform" did not return a path while reporting success. The platform should always return a valid path or report an error.', + ); + } + return XFile(path); } @@ -255,9 +280,10 @@ class MethodChannelCamera extends CameraPlatform { ); @override - Future setExposurePoint(int cameraId, Point point) { + Future setExposurePoint(int cameraId, Point? point) { assert(point == null || point.x >= 0 && point.x <= 1); assert(point == null || point.y >= 0 && point.y <= 1); + return _channel.invokeMethod( 'setExposurePoint', { @@ -270,35 +296,47 @@ class MethodChannelCamera extends CameraPlatform { } @override - Future getMinExposureOffset(int cameraId) => - _channel.invokeMethod( - 'getMinExposureOffset', - {'cameraId': cameraId}, - ); + Future getMinExposureOffset(int cameraId) async { + final minExposureOffset = await _channel.invokeMethod( + 'getMinExposureOffset', + {'cameraId': cameraId}, + ); + + return minExposureOffset!; + } @override - Future getMaxExposureOffset(int cameraId) => - _channel.invokeMethod( - 'getMaxExposureOffset', - {'cameraId': cameraId}, - ); + Future getMaxExposureOffset(int cameraId) async { + final maxExposureOffset = await _channel.invokeMethod( + 'getMaxExposureOffset', + {'cameraId': cameraId}, + ); + + return maxExposureOffset!; + } @override - Future getExposureOffsetStepSize(int cameraId) => - _channel.invokeMethod( - 'getExposureOffsetStepSize', - {'cameraId': cameraId}, - ); + Future getExposureOffsetStepSize(int cameraId) async { + final stepSize = await _channel.invokeMethod( + 'getExposureOffsetStepSize', + {'cameraId': cameraId}, + ); + + return stepSize!; + } @override - Future setExposureOffset(int cameraId, double offset) => - _channel.invokeMethod( - 'setExposureOffset', - { - 'cameraId': cameraId, - 'offset': offset, - }, - ); + Future setExposureOffset(int cameraId, double offset) async { + final appliedOffset = await _channel.invokeMethod( + 'setExposureOffset', + { + 'cameraId': cameraId, + 'offset': offset, + }, + ); + + return appliedOffset!; + } @override Future setFocusMode(int cameraId, FocusMode mode) => @@ -311,9 +349,10 @@ class MethodChannelCamera extends CameraPlatform { ); @override - Future setFocusPoint(int cameraId, Point point) { + Future setFocusPoint(int cameraId, Point? point) { assert(point == null || point.x >= 0 && point.x <= 1); assert(point == null || point.y >= 0 && point.y <= 1); + return _channel.invokeMethod( 'setFocusPoint', { @@ -326,16 +365,24 @@ class MethodChannelCamera extends CameraPlatform { } @override - Future getMaxZoomLevel(int cameraId) => _channel.invokeMethod( - 'getMaxZoomLevel', - {'cameraId': cameraId}, - ); + Future getMaxZoomLevel(int cameraId) async { + final maxZoomLevel = await _channel.invokeMethod( + 'getMaxZoomLevel', + {'cameraId': cameraId}, + ); + + return maxZoomLevel!; + } @override - Future getMinZoomLevel(int cameraId) => _channel.invokeMethod( - 'getMinZoomLevel', - {'cameraId': cameraId}, - ); + Future getMinZoomLevel(int cameraId) async { + final minZoomLevel = await _channel.invokeMethod( + 'getMinZoomLevel', + {'cameraId': cameraId}, + ); + + return minZoomLevel!; + } @override Future setZoomLevel(int cameraId, double zoom) async { diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart index e1faecf374cd..916922ff29fa 100644 --- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart +++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart @@ -51,8 +51,8 @@ abstract class CameraPlatform extends PlatformInterface { /// Creates an uninitialized camera instance and returns the cameraId. Future createCamera( CameraDescription cameraDescription, - ResolutionPreset resolutionPreset, { - bool enableAudio, + ResolutionPreset? resolutionPreset, { + bool enableAudio = true, }) { throw UnimplementedError('createCamera() is not implemented.'); } @@ -62,8 +62,10 @@ abstract class CameraPlatform extends PlatformInterface { /// [imageFormatGroup] is used to specify the image formatting used. /// On Android this defaults to ImageFormat.YUV_420_888 and applies only to the imageStream. /// On iOS this defaults to kCVPixelFormatType_32BGRA. - Future initializeCamera(int cameraId, - {ImageFormatGroup imageFormatGroup}) { + Future initializeCamera( + int cameraId, { + ImageFormatGroup imageFormatGroup = ImageFormatGroup.unknown, + }) { throw UnimplementedError('initializeCamera() is not implemented.'); } @@ -130,7 +132,7 @@ abstract class CameraPlatform extends PlatformInterface { /// meaning the recording will continue until manually stopped. /// With [maxVideoDuration] set the video is returned in a [VideoRecordedEvent] /// through the [onVideoRecordedEvent] stream when the set duration is reached. - Future startVideoRecording(int cameraId, {Duration maxVideoDuration}) { + Future startVideoRecording(int cameraId, {Duration? maxVideoDuration}) { throw UnimplementedError('startVideoRecording() is not implemented.'); } @@ -160,7 +162,10 @@ abstract class CameraPlatform extends PlatformInterface { } /// Sets the exposure point for automatically determining the exposure values. - Future setExposurePoint(int cameraId, Point point) { + /// + /// Supplying `null` for the [point] argument will result in resetting to the + /// original exposure point value. + Future setExposurePoint(int cameraId, Point? point) { throw UnimplementedError('setExposurePoint() is not implemented.'); } @@ -202,7 +207,10 @@ abstract class CameraPlatform extends PlatformInterface { } /// Sets the focus point for automatically determining the focus values. - Future setFocusPoint(int cameraId, Point point) { + /// + /// Supplying `null` for the [point] argument will result in resetting to the + /// original focus point value. + Future setFocusPoint(int cameraId, Point? point) { throw UnimplementedError('setFocusPoint() is not implemented.'); } diff --git a/packages/camera/camera_platform_interface/lib/src/types/camera_description.dart b/packages/camera/camera_platform_interface/lib/src/types/camera_description.dart index c19af1f50d1c..9707bd34d0d2 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/camera_description.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/camera_description.dart @@ -17,7 +17,11 @@ enum CameraLensDirection { /// Properties of a camera device. class CameraDescription { /// Creates a new camera description with the given properties. - CameraDescription({this.name, this.lensDirection, this.sensorOrientation}); + CameraDescription({ + required this.name, + required this.lensDirection, + required this.sensorOrientation, + }); /// The name of the camera device. final String name; diff --git a/packages/camera/camera_platform_interface/lib/src/types/camera_exception.dart b/packages/camera/camera_platform_interface/lib/src/types/camera_exception.dart index 3da659f7021d..59f3e4e6647e 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/camera_exception.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/camera_exception.dart @@ -13,7 +13,7 @@ class CameraException implements Exception { String code; /// Textual description of the error. - String description; + String? description; @override String toString() => 'CameraException($code, $description)'; diff --git a/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart b/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart index 7fbfbaf5f4a9..836f53826479 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart @@ -13,7 +13,6 @@ enum ExposureMode { /// Returns the exposure mode as a String. String serializeExposureMode(ExposureMode exposureMode) { - if (exposureMode == null) return null; switch (exposureMode) { case ExposureMode.locked: return 'locked'; @@ -26,7 +25,6 @@ String serializeExposureMode(ExposureMode exposureMode) { /// Returns the exposure mode for a given String. ExposureMode deserializeExposureMode(String str) { - if (str == null) return null; switch (str) { case "locked": return ExposureMode.locked; diff --git a/packages/camera/camera_platform_interface/lib/src/types/focus_mode.dart b/packages/camera/camera_platform_interface/lib/src/types/focus_mode.dart index ad5e9a2d46f1..8da2a90fa858 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/focus_mode.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/focus_mode.dart @@ -13,7 +13,6 @@ enum FocusMode { /// Returns the focus mode as a String. String serializeFocusMode(FocusMode focusMode) { - if (focusMode == null) return null; switch (focusMode) { case FocusMode.locked: return 'locked'; @@ -26,7 +25,6 @@ String serializeFocusMode(FocusMode focusMode) { /// Returns the focus mode for a given String. FocusMode deserializeFocusMode(String str) { - if (str == null) return null; switch (str) { case "locked": return FocusMode.locked; diff --git a/packages/camera/camera_platform_interface/pubspec.yaml b/packages/camera/camera_platform_interface/pubspec.yaml index c7ec7209c838..a063765af63b 100644 --- a/packages/camera/camera_platform_interface/pubspec.yaml +++ b/packages/camera/camera_platform_interface/pubspec.yaml @@ -3,23 +3,23 @@ description: A common platform interface for the camera plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.6.0 +version: 2.0.0-nullsafety dependencies: flutter: sdk: flutter - meta: ^1.0.5 - plugin_platform_interface: ^1.0.1 - cross_file: ^0.1.0 - stream_transform: ^1.2.0 + meta: ^1.3.0-nullsafety.6 + plugin_platform_interface: ^1.1.0-nullsafety.2 + cross_file: ^0.3.0-nullsafety + stream_transform: ^2.0.0-nullsafety.0 dev_dependencies: flutter_test: sdk: flutter - async: ^2.4.2 - mockito: ^4.1.1 - pedantic: ^1.8.0 + async: ^2.5.0-nullsafety.3 + mockito: ^5.0.0-nullsafety.5 + pedantic: ^1.10.0-nullsafety.3 environment: - sdk: ">=2.7.0 <3.0.0" + sdk: '>=2.12.0-0 <3.0.0' flutter: ">=1.22.0" diff --git a/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart b/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart index 8baf5da34159..a96df845844a 100644 --- a/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart +++ b/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart @@ -4,6 +4,7 @@ import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:camera_platform_interface/src/method_channel/method_channel_camera.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; @@ -117,7 +118,8 @@ void main() { // Act & Assert expect( - () => cameraPlatform.lockCaptureOrientation(1, null), + () => cameraPlatform.lockCaptureOrientation( + 1, DeviceOrientation.portraitUp), throwsUnimplementedError, ); }); @@ -155,7 +157,14 @@ void main() { // Act & Assert expect( - () => cameraPlatform.createCamera(null, null), + () => cameraPlatform.createCamera( + CameraDescription( + name: 'back', + lensDirection: CameraLensDirection.back, + sensorOrientation: 0, + ), + ResolutionPreset.high, + ), throwsUnimplementedError, ); }); @@ -168,7 +177,7 @@ void main() { // Act & Assert expect( - () => cameraPlatform.initializeCamera(null), + () => cameraPlatform.initializeCamera(1), throwsUnimplementedError, ); }); @@ -220,7 +229,7 @@ void main() { // Act & Assert expect( - () => cameraPlatform.setFlashMode(1, null), + () => cameraPlatform.setFlashMode(1, FlashMode.auto), throwsUnimplementedError, ); }); @@ -233,7 +242,7 @@ void main() { // Act & Assert expect( - () => cameraPlatform.setExposureMode(1, null), + () => cameraPlatform.setExposureMode(1, ExposureMode.auto), throwsUnimplementedError, ); }); @@ -298,7 +307,7 @@ void main() { // Act & Assert expect( - () => cameraPlatform.setExposureOffset(1, null), + () => cameraPlatform.setExposureOffset(1, 2.0), throwsUnimplementedError, ); }); @@ -311,7 +320,7 @@ void main() { // Act & Assert expect( - () => cameraPlatform.setFocusMode(1, null), + () => cameraPlatform.setFocusMode(1, FocusMode.auto), throwsUnimplementedError, ); }); diff --git a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart index 7e9146344206..7633de8626a6 100644 --- a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart +++ b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart @@ -37,7 +37,10 @@ void main() { // Act final cameraId = await camera.createCamera( - CameraDescription(name: 'Test'), + CameraDescription( + name: 'Test', + lensDirection: CameraLensDirection.back, + sensorOrientation: 0), ResolutionPreset.high, ); @@ -48,7 +51,7 @@ void main() { arguments: { 'cameraName': 'Test', 'resolutionPreset': 'high', - 'enableAudio': null + 'enableAudio': true }, ), ]); @@ -70,7 +73,11 @@ void main() { // Act expect( () => camera.createCamera( - CameraDescription(name: 'Test'), + CameraDescription( + name: 'Test', + lensDirection: CameraLensDirection.back, + sensorOrientation: 0, + ), ResolutionPreset.high, ), throwsA( @@ -97,7 +104,11 @@ void main() { // Act expect( () => camera.createCamera( - CameraDescription(name: 'Test'), + CameraDescription( + name: 'Test', + lensDirection: CameraLensDirection.back, + sensorOrientation: 0, + ), ResolutionPreset.high, ), throwsA( @@ -122,7 +133,11 @@ void main() { }); final camera = MethodChannelCamera(); final cameraId = await camera.createCamera( - CameraDescription(name: 'Test'), + CameraDescription( + name: 'Test', + lensDirection: CameraLensDirection.back, + sensorOrientation: 0, + ), ResolutionPreset.high, ); @@ -165,7 +180,11 @@ void main() { final camera = MethodChannelCamera(); final cameraId = await camera.createCamera( - CameraDescription(name: 'Test'), + CameraDescription( + name: 'Test', + lensDirection: CameraLensDirection.back, + sensorOrientation: 0, + ), ResolutionPreset.high, ); Future initializeFuture = camera.initializeCamera(cameraId); @@ -197,8 +216,8 @@ void main() { }); group('Event Tests', () { - MethodChannelCamera camera; - int cameraId; + late MethodChannelCamera camera; + late int cameraId; setUp(() async { MethodChannelMock( channelName: 'plugins.flutter.io/camera', @@ -209,7 +228,11 @@ void main() { ); camera = MethodChannelCamera(); cameraId = await camera.createCamera( - CameraDescription(name: 'Test'), + CameraDescription( + name: 'Test', + lensDirection: CameraLensDirection.back, + sensorOrientation: 0, + ), ResolutionPreset.high, ); Future initializeFuture = camera.initializeCamera(cameraId); @@ -352,8 +375,9 @@ void main() { }); group('Function Tests', () { - MethodChannelCamera camera; - int cameraId; + late MethodChannelCamera camera; + late int cameraId; + setUp(() async { MethodChannelMock( channelName: 'plugins.flutter.io/camera', @@ -364,7 +388,11 @@ void main() { ); camera = MethodChannelCamera(); cameraId = await camera.createCamera( - CameraDescription(name: 'Test'), + CameraDescription( + name: 'Test', + lensDirection: CameraLensDirection.back, + sensorOrientation: 0, + ), ResolutionPreset.high, ); Future initializeFuture = camera.initializeCamera(cameraId); diff --git a/packages/camera/camera_platform_interface/test/utils/method_channel_mock.dart b/packages/camera/camera_platform_interface/test/utils/method_channel_mock.dart index cdf393f82b5f..fdbd9a18f29c 100644 --- a/packages/camera/camera_platform_interface/test/utils/method_channel_mock.dart +++ b/packages/camera/camera_platform_interface/test/utils/method_channel_mock.dart @@ -5,15 +5,15 @@ import 'package:flutter/services.dart'; class MethodChannelMock { - final Duration delay; + final Duration? delay; final MethodChannel methodChannel; final Map methods; final log = []; MethodChannelMock({ - String channelName, + required String channelName, this.delay, - this.methods, + required this.methods, }) : methodChannel = MethodChannel(channelName) { methodChannel.setMockMethodCallHandler(_handler); } diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index 1e57db96a648..81ec693af41e 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -7,6 +7,7 @@ readonly NNBD_PLUGINS_LIST=( "android_intent" "battery" + "camera" "connectivity" "cross_file" "device_info" From 8d2594dc08514b5410022ef0c6b820a0eb4b9ca3 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Mon, 8 Feb 2021 15:23:43 -0800 Subject: [PATCH 0108/1565] [ios_platform_images] Migrate to null safety (#3381) --- packages/ios_platform_images/CHANGELOG.md | 4 ++ .../ios_platform_images/example/lib/main.dart | 3 +- .../lib/ios_platform_images.dart | 42 ++++++++++++------- packages/ios_platform_images/pubspec.yaml | 6 +-- .../test/ios_platform_images_test.dart | 4 ++ script/nnbd_plugins.sh | 1 + 6 files changed, 41 insertions(+), 19 deletions(-) diff --git a/packages/ios_platform_images/CHANGELOG.md b/packages/ios_platform_images/CHANGELOG.md index 4b11b40f5510..bae98440f668 100644 --- a/packages/ios_platform_images/CHANGELOG.md +++ b/packages/ios_platform_images/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.0-nullsafety + +* Migrate to null safety. + ## 0.1.2+4 * Update Flutter SDK constraint. diff --git a/packages/ios_platform_images/example/lib/main.dart b/packages/ios_platform_images/example/lib/main.dart index 655380f8d125..394d983ab66c 100644 --- a/packages/ios_platform_images/example/lib/main.dart +++ b/packages/ios_platform_images/example/lib/main.dart @@ -14,8 +14,7 @@ class _MyAppState extends State { void initState() { super.initState(); - IosPlatformImages.resolveURL("textfile", null) - .then((value) => print(value)); + IosPlatformImages.resolveURL("textfile").then((value) => print(value)); } @override diff --git a/packages/ios_platform_images/lib/ios_platform_images.dart b/packages/ios_platform_images/lib/ios_platform_images.dart index c7c12616ec36..d4599be94a64 100644 --- a/packages/ios_platform_images/lib/ios_platform_images.dart +++ b/packages/ios_platform_images/lib/ios_platform_images.dart @@ -1,3 +1,7 @@ +// Copyright 2020 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. + import 'dart:async'; import 'dart:typed_data'; import 'dart:ui' as ui; @@ -9,13 +13,11 @@ import 'package:flutter/foundation.dart' show SynchronousFuture, describeIdentity; class _FutureImageStreamCompleter extends ImageStreamCompleter { - final Future futureScale; - final InformationCollector informationCollector; - - _FutureImageStreamCompleter( - {Future codec, this.futureScale, this.informationCollector}) - : assert(codec != null), - assert(futureScale != null) { + _FutureImageStreamCompleter({ + required Future codec, + required this.futureScale, + this.informationCollector, + }) { codec.then(_onCodecReady, onError: (dynamic error, StackTrace stack) { reportError( context: ErrorDescription('resolving a single-frame image stream'), @@ -27,6 +29,9 @@ class _FutureImageStreamCompleter extends ImageStreamCompleter { }); } + final Future futureScale; + final InformationCollector? informationCollector; + Future _onCodecReady(ui.Codec codec) async { try { ui.FrameInfo nextFrame = await codec.getNextFrame(); @@ -50,9 +55,7 @@ class _FutureMemoryImage extends ImageProvider<_FutureMemoryImage> { /// Constructor for FutureMemoryImage. [_futureBytes] is the bytes that will /// be loaded into an image and [_futureScale] is the scale that will be applied to /// that image to account for high-resolution images. - const _FutureMemoryImage(this._futureBytes, this._futureScale) - : assert(_futureBytes != null), - assert(_futureScale != null); + const _FutureMemoryImage(this._futureBytes, this._futureScale); final Future _futureBytes; final Future _futureScale; @@ -73,7 +76,9 @@ class _FutureMemoryImage extends ImageProvider<_FutureMemoryImage> { } Future _loadAsync( - _FutureMemoryImage key, DecoderCallback decode) async { + _FutureMemoryImage key, + DecoderCallback decode, + ) async { assert(key == this); return _futureBytes.then((Uint8List bytes) { return decode(bytes); @@ -113,10 +118,19 @@ class IosPlatformImages { /// /// See [https://developer.apple.com/documentation/uikit/uiimage/1624146-imagenamed?language=objc] static ImageProvider load(String name) { - Future loadInfo = _channel.invokeMethod('loadImage', name); + Future loadInfo = _channel.invokeMapMethod('loadImage', name); Completer bytesCompleter = Completer(); Completer scaleCompleter = Completer(); loadInfo.then((map) { + if (map == null) { + scaleCompleter.completeError( + Exception("Image couldn't be found: $name"), + ); + bytesCompleter.completeError( + Exception("Image couldn't be found: $name"), + ); + return; + } scaleCompleter.complete(map["scale"]); bytesCompleter.complete(map["data"]); }); @@ -129,7 +143,7 @@ class IosPlatformImages { /// Returns null if the resource can't be found. /// /// See [https://developer.apple.com/documentation/foundation/nsbundle/1411540-urlforresource?language=objc] - static Future resolveURL(String name, [String ext]) { - return _channel.invokeMethod('resolveURL', [name, ext]); + static Future resolveURL(String name, {String? extension}) { + return _channel.invokeMethod('resolveURL', [name, extension]); } } diff --git a/packages/ios_platform_images/pubspec.yaml b/packages/ios_platform_images/pubspec.yaml index 7049b62cf00a..6284f7c96871 100644 --- a/packages/ios_platform_images/pubspec.yaml +++ b/packages/ios_platform_images/pubspec.yaml @@ -1,10 +1,10 @@ name: ios_platform_images description: A plugin to share images between Flutter and iOS in add-to-app setups. -version: 0.1.2+4 +version: 0.2.0-nullsafety homepage: https://github.com/flutter/plugins/tree/master/packages/ios_platform_images/ios_platform_images environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.12.13+hotfix.5" dependencies: @@ -14,7 +14,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0-nullsafety # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/packages/ios_platform_images/test/ios_platform_images_test.dart b/packages/ios_platform_images/test/ios_platform_images_test.dart index fd87180e9ac0..6ed7714e95c2 100644 --- a/packages/ios_platform_images/test/ios_platform_images_test.dart +++ b/packages/ios_platform_images/test/ios_platform_images_test.dart @@ -1,3 +1,7 @@ +// Copyright 2020 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. + import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:ios_platform_images/ios_platform_images.dart'; diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index 81ec693af41e..c6765730ddeb 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -15,6 +15,7 @@ readonly NNBD_PLUGINS_LIST=( "flutter_plugin_android_lifecycle" "flutter_webview" "google_sign_in" + "ios_platform_images" "local_auth" "path_provider" "package_info" From cf49441b00ba1268b627dff117f698b6a1e1384a Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Mon, 8 Feb 2021 15:54:11 -0800 Subject: [PATCH 0109/1565] [file_selector_web] Fix typo in pubspec. (#3528) (Introduced by mistake in https://github.com/flutter/plugins/pull/3509) --- packages/file_selector/file_selector_web/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/file_selector/file_selector_web/pubspec.yaml b/packages/file_selector/file_selector_web/pubspec.yaml index 79181e821cec..a170d5f39607 100644 --- a/packages/file_selector/file_selector_web/pubspec.yaml +++ b/packages/file_selector/file_selector_web/pubspec.yaml @@ -22,8 +22,8 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - mockito: ^5.0.0-nullsafety.5 - pedantic: ^1.10.0-nullsafety.3 + mockito: ^4.1.1 + pedantic: ^1.8.0 integration_test: path: ../../integration_test From e68b15f218a90a389504b7a486c59bf9115abc31 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Mon, 8 Feb 2021 16:37:24 -0800 Subject: [PATCH 0110/1565] [sensors] Migrate to null safety (#3423) --- packages/sensors/CHANGELOG.md | 4 ++ .../integration_test/sensors_test.dart | 2 + packages/sensors/lib/sensors.dart | 52 ++++++++++++------- packages/sensors/pubspec.yaml | 10 ++-- packages/sensors/test/sensors_test.dart | 10 ++-- script/nnbd_plugins.sh | 1 + 6 files changed, 49 insertions(+), 30 deletions(-) diff --git a/packages/sensors/CHANGELOG.md b/packages/sensors/CHANGELOG.md index 8970f1e76e5d..682d377a6b84 100644 --- a/packages/sensors/CHANGELOG.md +++ b/packages/sensors/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.0-nullsafety + +* Migrate to null safety. + ## 0.4.2+8 * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) diff --git a/packages/sensors/integration_test/sensors_test.dart b/packages/sensors/integration_test/sensors_test.dart index ea1db0375f38..348bda00d86e 100644 --- a/packages/sensors/integration_test/sensors_test.dart +++ b/packages/sensors/integration_test/sensors_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 'package:flutter_test/flutter_test.dart'; import 'package:sensors/sensors.dart'; diff --git a/packages/sensors/lib/sensors.dart b/packages/sensors/lib/sensors.dart index 0b6f1b5a6067..8f69255bcec7 100644 --- a/packages/sensors/lib/sensors.dart +++ b/packages/sensors/lib/sensors.dart @@ -121,38 +121,50 @@ GyroscopeEvent _listToGyroscopeEvent(List list) { return GyroscopeEvent(list[0], list[1], list[2]); } -Stream _accelerometerEvents; -Stream _gyroscopeEvents; -Stream _userAccelerometerEvents; +Stream? _accelerometerEvents; +Stream? _gyroscopeEvents; +Stream? _userAccelerometerEvents; /// A broadcast stream of events from the device accelerometer. Stream get accelerometerEvents { - if (_accelerometerEvents == null) { - _accelerometerEvents = _accelerometerEventChannel - .receiveBroadcastStream() - .map( - (dynamic event) => _listToAccelerometerEvent(event.cast())); + Stream? accelerometerEvents = _accelerometerEvents; + if (accelerometerEvents == null) { + accelerometerEvents = + _accelerometerEventChannel.receiveBroadcastStream().map( + (dynamic event) => + _listToAccelerometerEvent(event.cast()), + ); + _accelerometerEvents = accelerometerEvents; } - return _accelerometerEvents; + + return accelerometerEvents; } /// A broadcast stream of events from the device gyroscope. Stream get gyroscopeEvents { - if (_gyroscopeEvents == null) { - _gyroscopeEvents = _gyroscopeEventChannel - .receiveBroadcastStream() - .map((dynamic event) => _listToGyroscopeEvent(event.cast())); + Stream? gyroscopeEvents = _gyroscopeEvents; + if (gyroscopeEvents == null) { + gyroscopeEvents = _gyroscopeEventChannel.receiveBroadcastStream().map( + (dynamic event) => _listToGyroscopeEvent(event.cast()), + ); + _gyroscopeEvents = gyroscopeEvents; } - return _gyroscopeEvents; + + return gyroscopeEvents; } /// Events from the device accelerometer with gravity removed. Stream get userAccelerometerEvents { - if (_userAccelerometerEvents == null) { - _userAccelerometerEvents = _userAccelerometerEventChannel - .receiveBroadcastStream() - .map((dynamic event) => - _listToUserAccelerometerEvent(event.cast())); + Stream? userAccelerometerEvents = + _userAccelerometerEvents; + if (userAccelerometerEvents == null) { + userAccelerometerEvents = + _userAccelerometerEventChannel.receiveBroadcastStream().map( + (dynamic event) => + _listToUserAccelerometerEvent(event.cast()), + ); + _userAccelerometerEvents = userAccelerometerEvents; } - return _userAccelerometerEvents; + + return userAccelerometerEvents; } diff --git a/packages/sensors/pubspec.yaml b/packages/sensors/pubspec.yaml index 35feb4b1ed56..e9b0392bae8d 100644 --- a/packages/sensors/pubspec.yaml +++ b/packages/sensors/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/sensors # 0.4.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.4.2+8 +version: 0.5.0-nullsafety flutter: plugin: @@ -21,14 +21,14 @@ dependencies: sdk: flutter dev_dependencies: - test: ^1.3.0 + test: ^1.16.0-nullsafety flutter_test: sdk: flutter integration_test: path: ../integration_test - mockito: ^4.1.1 - pedantic: ^1.8.0 + mockito: ^5.0.0-nullsafety.0 + pedantic: ^1.10.0-nullsafety environment: - sdk: ">=2.1.0<3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/sensors/test/sensors_test.dart b/packages/sensors/test/sensors_test.dart index 832a2f8524b7..93e0959befed 100644 --- a/packages/sensors/test/sensors_test.dart +++ b/packages/sensors/test/sensors_test.dart @@ -52,16 +52,16 @@ void main() { void _initializeFakeSensorChannel(String channelName, List sensorData) { const StandardMethodCodec standardMethod = StandardMethodCodec(); - void _emitEvent(ByteData event) { - ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage( + void _emitEvent(ByteData? event) { + ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage( channelName, event, - (ByteData reply) {}, + (ByteData? reply) {}, ); } - ServicesBinding.instance.defaultBinaryMessenger - .setMockMessageHandler(channelName, (ByteData message) async { + ServicesBinding.instance!.defaultBinaryMessenger + .setMockMessageHandler(channelName, (ByteData? message) async { final MethodCall methodCall = standardMethod.decodeMethodCall(message); if (methodCall.method == 'listen') { _emitEvent(standardMethod.encodeSuccessEnvelope(sensorData)); diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index c6765730ddeb..0e1d3c4bfac5 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -20,6 +20,7 @@ readonly NNBD_PLUGINS_LIST=( "path_provider" "package_info" "plugin_platform_interface" + "sensors" "share" "shared_preferences" "url_launcher" From bb21db859f26eb3871a555e7ae9720707be2d808 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Mon, 8 Feb 2021 19:03:20 -0800 Subject: [PATCH 0111/1565] [quick_actions] Migrate to null safety (#3421) --- packages/quick_actions/CHANGELOG.md | 4 ++++ packages/quick_actions/lib/quick_actions.dart | 15 ++++++++------- packages/quick_actions/pubspec.yaml | 12 ++++++------ .../quick_actions/test/quick_actions_test.dart | 2 +- script/nnbd_plugins.sh | 1 + 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/packages/quick_actions/CHANGELOG.md b/packages/quick_actions/CHANGELOG.md index a0c1b1f43c66..774ccac1bb44 100644 --- a/packages/quick_actions/CHANGELOG.md +++ b/packages/quick_actions/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.0-nullsafety + +* Migrate to null safety. + ## 0.4.0+12 * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) diff --git a/packages/quick_actions/lib/quick_actions.dart b/packages/quick_actions/lib/quick_actions.dart index 933162a1a47c..875661244a74 100644 --- a/packages/quick_actions/lib/quick_actions.dart +++ b/packages/quick_actions/lib/quick_actions.dart @@ -22,8 +22,8 @@ class ShortcutItem { /// /// Only [icon] should be nullable. It will remain `null` if unset. const ShortcutItem({ - @required this.type, - @required this.localizedTitle, + required this.type, + required this.localizedTitle, this.icon, }); @@ -35,7 +35,7 @@ class ShortcutItem { /// Name of native resource (xcassets etc; NOT a Flutter asset) to be /// displayed as the icon for this item. - final String icon; + final String? icon; } /// Quick actions plugin. @@ -65,7 +65,8 @@ class QuickActions { assert(call.method == 'launch'); handler(call.arguments); }); - final String action = await channel.invokeMethod('getLaunchAction'); + final String? action = + await channel.invokeMethod('getLaunchAction'); if (action != null) { handler(action); } @@ -73,7 +74,7 @@ class QuickActions { /// Sets the [ShortcutItem]s to become the app's quick actions. Future setShortcutItems(List items) async { - final List> itemsList = + final List> itemsList = items.map(_serializeItem).toList(); await channel.invokeMethod('setShortcutItems', itemsList); } @@ -82,8 +83,8 @@ class QuickActions { Future clearShortcutItems() => channel.invokeMethod('clearShortcutItems'); - Map _serializeItem(ShortcutItem item) { - return { + Map _serializeItem(ShortcutItem item) { + return { 'type': item.type, 'localizedTitle': item.localizedTitle, 'icon': item.icon, diff --git a/packages/quick_actions/pubspec.yaml b/packages/quick_actions/pubspec.yaml index e76cd9ce8bd2..46bc53e63ce6 100644 --- a/packages/quick_actions/pubspec.yaml +++ b/packages/quick_actions/pubspec.yaml @@ -2,7 +2,7 @@ name: quick_actions description: Flutter plugin for creating shortcuts on home screen, also known as Quick Actions on iOS and App Shortcuts on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/quick_actions -version: 0.4.0+12 +version: 0.5.0-nullsafety flutter: plugin: @@ -16,17 +16,17 @@ flutter: dependencies: flutter: sdk: flutter - meta: ^1.0.5 + meta: ^1.3.0-nullsafety dev_dependencies: - test: ^1.3.0 - mockito: ^3.0.0 + test: ^1.16.0-nullsafety + mockito: ^5.0.0-nullsafety.0 flutter_test: sdk: flutter integration_test: path: ../integration_test - pedantic: ^1.8.0 + pedantic: ^1.10.0-nullsafety environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/quick_actions/test/quick_actions_test.dart b/packages/quick_actions/test/quick_actions_test.dart index ffb6de1024fd..8066719e5113 100644 --- a/packages/quick_actions/test/quick_actions_test.dart +++ b/packages/quick_actions/test/quick_actions_test.dart @@ -10,7 +10,7 @@ import 'package:quick_actions/quick_actions.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); - QuickActions quickActions; + late QuickActions quickActions; final List log = []; setUp(() { diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index 0e1d3c4bfac5..447e8742cc8b 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -20,6 +20,7 @@ readonly NNBD_PLUGINS_LIST=( "path_provider" "package_info" "plugin_platform_interface" + "quick_actions" "sensors" "share" "shared_preferences" From 46207ea6d62639c0881b4adf20ec2caa9d252b3c Mon Sep 17 00:00:00 2001 From: shihchanghsiungsonos <44383755+shihchanghsiungsonos@users.noreply.github.com> Date: Tue, 9 Feb 2021 08:11:39 -0800 Subject: [PATCH 0112/1565] [video_player]: Fix texture unregistration callback signature Flutter's video plugin can cause crashes after a closing a flutter view on simulator model iPhone X or higher Co-authored-by: Mike Diarmid --- packages/video_player/video_player/CHANGELOG.md | 4 ++++ .../video_player/ios/Classes/FLTVideoPlayerPlugin.m | 2 +- packages/video_player/video_player/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index 3e8047ced6bc..2e8f7396c618 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.9 + +* Fixed an issue where a crash can occur after a closing a video player view on iOS. + ## 2.0.0-nullsafety.8 * Migrated from deprecated `defaultBinaryMessenger`. diff --git a/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m b/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m index e6a4f6ccb0b7..c2a1a40aa4fe 100644 --- a/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m +++ b/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m @@ -392,7 +392,7 @@ - (CVPixelBufferRef)copyPixelBuffer { } } -- (void)onTextureUnregistered { +- (void)onTextureUnregistered:(NSObject*)texture { dispatch_async(dispatch_get_main_queue(), ^{ [self dispose]; }); diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index 72fb54b125ea..be005280609c 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -4,7 +4,7 @@ description: Flutter plugin for displaying inline video with other Flutter # 0.10.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 2.0.0-nullsafety.8 +version: 2.0.0-nullsafety.9 homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player flutter: From 847749a19e77ca96b9029bc51d040d65ca65cfd0 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Tue, 9 Feb 2021 08:13:23 -0800 Subject: [PATCH 0113/1565] [wifi_info_flutter] Migrate the platform interface to null safety (#3424) --- .../wifi_info_flutter_platform_interface/CHANGELOG.md | 4 ++++ .../lib/src/method_channel_wifi_info_flutter.dart | 8 ++++---- .../lib/wifi_info_flutter_platform_interface.dart | 6 +++--- .../wifi_info_flutter_platform_interface/pubspec.yaml | 8 ++++---- .../test/method_channel_wifi_info_flutter_test.dart | 8 ++++---- script/nnbd_plugins.sh | 3 ++- 6 files changed, 21 insertions(+), 16 deletions(-) diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/CHANGELOG.md b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/CHANGELOG.md index 951f8f5f5ae0..043a3d31b68d 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/CHANGELOG.md +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Migrate to null safety. + ## 1.0.1 * Update Flutter SDK constraint. diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/method_channel_wifi_info_flutter.dart b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/method_channel_wifi_info_flutter.dart index ef390c3cde1e..ba422ecd7565 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/method_channel_wifi_info_flutter.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/method_channel_wifi_info_flutter.dart @@ -17,17 +17,17 @@ class MethodChannelWifiInfoFlutter extends WifiInfoFlutterPlatform { MethodChannel('plugins.flutter.io/wifi_info_flutter'); @override - Future getWifiName() async { + Future getWifiName() async { return methodChannel.invokeMethod('wifiName'); } @override - Future getWifiBSSID() { + Future getWifiBSSID() { return methodChannel.invokeMethod('wifiBSSID'); } @override - Future getWifiIP() { + Future getWifiIP() { return methodChannel.invokeMethod('wifiIPAddress'); } @@ -50,7 +50,7 @@ class MethodChannelWifiInfoFlutter extends WifiInfoFlutterPlatform { } /// Convert a String to a LocationAuthorizationStatus value. -LocationAuthorizationStatus _parseLocationAuthorizationStatus(String result) { +LocationAuthorizationStatus _parseLocationAuthorizationStatus(String? result) { return LocationAuthorizationStatus.values.firstWhere( (LocationAuthorizationStatus status) => result == describeEnum(status), orElse: () => LocationAuthorizationStatus.unknown, diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/wifi_info_flutter_platform_interface.dart b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/wifi_info_flutter_platform_interface.dart index 85034b2cbbff..5115af7e56eb 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/wifi_info_flutter_platform_interface.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/wifi_info_flutter_platform_interface.dart @@ -43,17 +43,17 @@ abstract class WifiInfoFlutterPlatform extends PlatformInterface { } /// Obtains the wifi name (SSID) of the connected network - Future getWifiName() { + Future getWifiName() { throw UnimplementedError('getWifiName() has not been implemented.'); } /// Obtains the wifi BSSID of the connected network. - Future getWifiBSSID() { + Future getWifiBSSID() { throw UnimplementedError('getWifiBSSID() has not been implemented.'); } /// Obtains the IP address of the connected wifi network - Future getWifiIP() { + Future getWifiIP() { throw UnimplementedError('getWifiIP() has not been implemented.'); } diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/pubspec.yaml b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/pubspec.yaml index 62bffd0eeeb3..1d830f0af5f6 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/pubspec.yaml +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/pubspec.yaml @@ -1,20 +1,20 @@ name: wifi_info_flutter_platform_interface description: A common platform interface for the wifi_info_flutter plugin. -version: 1.0.1 +version: 2.0.0-nullsafety # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes homepage: https://github.com/flutter/plugins/tree/master/packages/wifi_info_flutter/wifi_info_flutter_platform_interface environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.17.0" dependencies: - plugin_platform_interface: ^1.0.3 + plugin_platform_interface: ^1.1.0-nullsafety flutter: sdk: flutter dev_dependencies: - pedantic: ^1.9.2 + pedantic: ^1.10.0-nullsafety flutter_test: sdk: flutter diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/test/method_channel_wifi_info_flutter_test.dart b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/test/method_channel_wifi_info_flutter_test.dart index b48b2c4110bb..33733170c9fb 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/test/method_channel_wifi_info_flutter_test.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/test/method_channel_wifi_info_flutter_test.dart @@ -12,7 +12,7 @@ void main() { group('$MethodChannelWifiInfoFlutter', () { final List log = []; - MethodChannelWifiInfoFlutter methodChannelWifiInfoFlutter; + late MethodChannelWifiInfoFlutter methodChannelWifiInfoFlutter; setUp(() async { methodChannelWifiInfoFlutter = MethodChannelWifiInfoFlutter(); @@ -39,7 +39,7 @@ void main() { }); test('getWifiName', () async { - final String result = await methodChannelWifiInfoFlutter.getWifiName(); + final String? result = await methodChannelWifiInfoFlutter.getWifiName(); expect(result, '1337wifi'); expect( log, @@ -53,7 +53,7 @@ void main() { }); test('getWifiBSSID', () async { - final String result = await methodChannelWifiInfoFlutter.getWifiBSSID(); + final String? result = await methodChannelWifiInfoFlutter.getWifiBSSID(); expect(result, 'c0:ff:33:c0:d3:55'); expect( log, @@ -67,7 +67,7 @@ void main() { }); test('getWifiIP', () async { - final String result = await methodChannelWifiInfoFlutter.getWifiIP(); + final String? result = await methodChannelWifiInfoFlutter.getWifiIP(); expect(result, '127.0.0.1'); expect( log, diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index 447e8742cc8b..492c8adf3ad5 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -15,6 +15,7 @@ readonly NNBD_PLUGINS_LIST=( "flutter_plugin_android_lifecycle" "flutter_webview" "google_sign_in" + "image_picker" "ios_platform_images" "local_auth" "path_provider" @@ -27,7 +28,7 @@ readonly NNBD_PLUGINS_LIST=( "url_launcher" "video_player" "webview_flutter" - "image_picker" + "wifi_info_flutter" ) # This list contains the list of plugins that have *not* been From f217be7d7091dd71ef777d6a3016a00216aa23f1 Mon Sep 17 00:00:00 2001 From: nohli <43643339+nohli@users.noreply.github.com> Date: Tue, 9 Feb 2021 19:32:02 +0100 Subject: [PATCH 0114/1565] [url_launcher] Fix PlatformException introduced in nnbd release (#3333) --- .../url_launcher/test/url_launcher_test.dart | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/packages/url_launcher/url_launcher/test/url_launcher_test.dart b/packages/url_launcher/url_launcher/test/url_launcher_test.dart index 89a7801e1ca8..bb3fd2ad92b5 100644 --- a/packages/url_launcher/url_launcher/test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher/test/url_launcher_test.dart @@ -191,6 +191,38 @@ void main() { throwsA(isA())); }); + test('send e-mail', () async { + await launch('mailto:gmail-noreply@google.com?subject=Hello'); + expect( + verify(await mock.launch( + any, + useSafariVC: anyNamed('useSafariVC'), + useWebView: anyNamed('useWebView'), + enableJavaScript: anyNamed('enableJavaScript'), + enableDomStorage: anyNamed('enableDomStorage'), + universalLinksOnly: anyNamed('universalLinksOnly'), + headers: anyNamed('headers'), + )), + isInstanceOf(), + ); + }); + + test('cannot send e-mail with forceSafariVC: true', () async { + expect( + () async => await launch( + 'mailto:gmail-noreply@google.com?subject=Hello', + forceSafariVC: true), + throwsA(isA())); + }); + + test('cannot send e-mail with forceWebView: true', () async { + expect( + () async => await launch( + 'mailto:gmail-noreply@google.com?subject=Hello', + forceWebView: true), + throwsA(isA())); + }); + test('controls system UI when changing statusBarBrightness', () async { final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized(); From 5e87faf3db815ec38efd4c9f268a78d43a881622 Mon Sep 17 00:00:00 2001 From: Emmanuel Garcia Date: Tue, 9 Feb 2021 10:44:32 -0800 Subject: [PATCH 0115/1565] Add section about how to use Material components in an app using WebView (#3521) --- packages/webview_flutter/CHANGELOG.md | 4 ++++ packages/webview_flutter/README.md | 9 ++++++--- packages/webview_flutter/pubspec.yaml | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index 9c54b4cc207d..b3218e296d98 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.5 + +* Add section to the wiki explaining how to use Material components. + ## 2.0.0-nullsafety.4 * Update integration test to workaround an iOS 14 issue with `evaluateJavascript`. diff --git a/packages/webview_flutter/README.md b/packages/webview_flutter/README.md index df554eb5123c..94000772ca71 100644 --- a/packages/webview_flutter/README.md +++ b/packages/webview_flutter/README.md @@ -14,8 +14,6 @@ You can now include a WebView widget in your widget tree. See the [WebView](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebView-class.html) widget's Dartdoc for more details on how to use the widget. - - ## Android Platform Views The WebView is relying on [Platform Views](https://flutter.dev/docs/development/platform-integration/platform-views) to embed @@ -66,5 +64,10 @@ android { // Required by the Flutter WebView plugin. minSdkVersion 19 } - } +} ``` + +#### Enable Material Components for Android + +To use Material Components when the user interacts with input elements in the WebView, +follow the steps described in the [Enabling Material Components instructions](https://flutter.dev/docs/deployment/android#enabling-material-components). diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml index 11769acce2ba..5d8e512b5aa5 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.4 +version: 2.0.0-nullsafety.5 homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter environment: From 44b4b541f890caa0c5e846f09f4b8d64d3abfb0d Mon Sep 17 00:00:00 2001 From: Emmanuel Garcia Date: Tue, 9 Feb 2021 10:50:40 -0800 Subject: [PATCH 0116/1565] Add plugin tools as a git submodule and depend on it directly (#3527) --- .cirrus.yml | 15 +++++++++++++++ .gitmodules | 3 +++ script/check_publish.sh | 3 +-- script/common.sh | 16 +++------------- script/plugin_tools | 1 + 5 files changed, 23 insertions(+), 15 deletions(-) create mode 100644 .gitmodules create mode 160000 script/plugin_tools diff --git a/.cirrus.yml b/.cirrus.yml index a4815ec2489e..a49a8b14ca83 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -14,6 +14,9 @@ task: - flutter channel master - flutter upgrade - git fetch origin master + submodules_script: + - git submodule init + - git submodule update matrix: - name: publishable script: @@ -121,6 +124,9 @@ task: - flutter channel master - flutter upgrade - git fetch origin master + submodules_script: + - git submodule init + - git submodule update matrix: - name: build-linux+drive-examples install_script: @@ -145,6 +151,9 @@ task: - flutter channel master - flutter upgrade - git fetch origin master + submodules_script: + - git submodule init + - git submodule update create_simulator_script: - xcrun simctl list - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-11 com.apple.CoreSimulator.SimRuntime.iOS-14-3 | xargs xcrun simctl boot @@ -198,6 +207,9 @@ task: - flutter channel master - flutter upgrade - git fetch origin master + submodules_script: + - git submodule init + - git submodule update create_simulator_script: - xcrun simctl list - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-X com.apple.CoreSimulator.SimRuntime.iOS-13-3 | xargs xcrun simctl boot @@ -227,6 +239,9 @@ task: - flutter channel master - flutter upgrade - git fetch origin master + submodules_script: + - git submodule init + - git submodule update matrix: - name: build_all_plugins_app script: diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000000..d83ab14b23a0 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "script/plugin_tools"] + path = script/plugin_tools + url = https://github.com/flutter/plugin_tools.git diff --git a/script/check_publish.sh b/script/check_publish.sh index 9f435e9ba42c..5584fc601916 100755 --- a/script/check_publish.sh +++ b/script/check_publish.sh @@ -12,8 +12,7 @@ source "$SCRIPT_DIR/common.sh" function check_publish() { local failures=() - pub_command global activate flutter_plugin_tools - for dir in $(pub_command global run flutter_plugin_tools list --plugins="$1"); do + for dir in $(plugin_tools list --plugins="$1"); do local package_name=$(basename "$dir") echo "Checking that $package_name can be published." diff --git a/script/common.sh b/script/common.sh index cd2c1ca3fd83..4c8aff9822f6 100644 --- a/script/common.sh +++ b/script/common.sh @@ -46,18 +46,8 @@ function check_changed_packages() { return 0 } -# Normalizes the call to the pub command. -function pub_command() { - if [ "$(expr substr $(uname -s) 1 5)" == "MINGW" ]; then - pub.bat "$@" - else - pub "$@" - fi -} - -# Activates the Flutter plugin tool to ensures that the plugin tools dependencies -# are resolved using the current Dart SDK. -# Finally, runs the tool with the parameters. +# Runs the plugin tools from the plugin_tools git submodule. function plugin_tools() { - pub_command global activate flutter_plugin_tools && pub_command global run flutter_plugin_tools "$@" + (pushd "$REPO_DIR/script/plugin_tools" && dart pub get && popd) >/dev/null + dart run "$REPO_DIR/script/plugin_tools/lib/src/main.dart" "$@" } diff --git a/script/plugin_tools b/script/plugin_tools new file mode 160000 index 000000000000..432c56da3588 --- /dev/null +++ b/script/plugin_tools @@ -0,0 +1 @@ +Subproject commit 432c56da35880e95f6cbb02c40e9da0361771f48 From ea19ea8750691cffa0c376ff065f16ea47b5c00d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan?= Date: Tue, 9 Feb 2021 20:22:10 +0100 Subject: [PATCH 0117/1565] [shared_preferences] Migrate main package to null-safety (#3526) Migrates shared_preferences to nnbd. Fixes flutter/flutter#74876. Note: also recreated the android and macos example applications because the macOS app was apparently a copy of the connectivity app and had connectivity_example as its name, the Android app was using the embedding v1. --- .../shared_preferences/CHANGELOG.md | 8 ++ .../shared_preferences/README.md | 8 -- .../shared_preferences/example/.gitignore | 46 +++++++++ .../shared_preferences/example/.metadata | 10 ++ .../example/android/.gitignore | 11 ++ .../example/android/app/build.gradle | 17 ++-- .../gradle/wrapper/gradle-wrapper.properties | 5 - .../android/app/src/debug/AndroidManifest.xml | 7 ++ .../android/app/src/main/AndroidManifest.xml | 47 ++++++--- .../EmbeddingV1Activity.java | 22 ---- .../EmbeddingV1ActivityTest.java | 15 --- .../FlutterActivityTest.java | 17 ---- .../flutter/plugins/example/MainActivity.kt | 6 ++ .../res/drawable-v21/launch_background.xml | 12 +++ .../main/res/drawable/launch_background.xml | 12 +++ .../app/src/main/res/values-night/styles.xml | 18 ++++ .../app/src/main/res/values/styles.xml | 18 ++++ .../app/src/profile/AndroidManifest.xml | 7 ++ .../example/android/build.gradle | 4 +- .../example/android/gradle.properties | 1 - .../gradle/wrapper/gradle-wrapper.properties | 3 +- .../example/android/settings.gradle | 18 ++-- .../shared_preferences/example/ios/.gitignore | 32 ++++++ .../example/ios/Flutter/Debug.xcconfig | 1 + .../example/ios/Flutter/Release.xcconfig | 1 + .../contents.xcworkspacedata | 7 ++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++ .../xcshareddata/WorkspaceSettings.xcsettings | 8 ++ .../contents.xcworkspacedata | 7 ++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++ .../xcshareddata/WorkspaceSettings.xcsettings | 8 ++ .../example/ios/Runner/AppDelegate.swift | 13 +++ .../Icon-App-1024x1024@1x.png | Bin 0 -> 10932 bytes .../LaunchImage.imageset/Contents.json | 23 +++++ .../LaunchImage.imageset/LaunchImage.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/README.md | 5 + .../ios/Runner/Runner-Bridging-Header.h | 1 + .../example/macos/.gitignore | 6 ++ .../macos/Flutter/Flutter-Debug.xcconfig | 2 +- .../macos/Flutter/Flutter-Release.xcconfig | 2 +- .../macos/Runner.xcodeproj/project.pbxproj | 96 ++---------------- .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++ .../xcshareddata/xcschemes/Runner.xcscheme | 22 +--- .../macos/Runner/Configs/AppInfo.xcconfig | 6 +- .../example/web/favicon.png | Bin 0 -> 917 bytes .../example/web/icons/Icon-192.png | Bin 0 -> 5292 bytes .../example/web/icons/Icon-512.png | Bin 0 -> 8252 bytes .../example/web/manifest.json | 23 +++++ .../lib/shared_preferences.dart | 74 ++++++-------- .../shared_preferences/pubspec.yaml | 14 +-- .../test/shared_preferences_test.dart | 35 +++---- 53 files changed, 436 insertions(+), 286 deletions(-) create mode 100644 packages/shared_preferences/shared_preferences/example/.gitignore create mode 100644 packages/shared_preferences/shared_preferences/example/.metadata create mode 100644 packages/shared_preferences/shared_preferences/example/android/.gitignore delete mode 100644 packages/shared_preferences/shared_preferences/example/android/app/gradle/wrapper/gradle-wrapper.properties create mode 100644 packages/shared_preferences/shared_preferences/example/android/app/src/debug/AndroidManifest.xml delete mode 100644 packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1Activity.java delete mode 100644 packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1ActivityTest.java delete mode 100644 packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/FlutterActivityTest.java create mode 100644 packages/shared_preferences/shared_preferences/example/android/app/src/main/kotlin/io/flutter/plugins/example/MainActivity.kt create mode 100644 packages/shared_preferences/shared_preferences/example/android/app/src/main/res/drawable-v21/launch_background.xml create mode 100644 packages/shared_preferences/shared_preferences/example/android/app/src/main/res/drawable/launch_background.xml create mode 100644 packages/shared_preferences/shared_preferences/example/android/app/src/main/res/values-night/styles.xml create mode 100644 packages/shared_preferences/shared_preferences/example/android/app/src/main/res/values/styles.xml create mode 100644 packages/shared_preferences/shared_preferences/example/android/app/src/profile/AndroidManifest.xml create mode 100644 packages/shared_preferences/shared_preferences/example/ios/.gitignore create mode 100644 packages/shared_preferences/shared_preferences/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 packages/shared_preferences/shared_preferences/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 packages/shared_preferences/shared_preferences/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 packages/shared_preferences/shared_preferences/example/ios/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 packages/shared_preferences/shared_preferences/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 packages/shared_preferences/shared_preferences/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.swift create mode 100644 packages/shared_preferences/shared_preferences/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png create mode 100644 packages/shared_preferences/shared_preferences/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json create mode 100644 packages/shared_preferences/shared_preferences/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png create mode 100644 packages/shared_preferences/shared_preferences/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png create mode 100644 packages/shared_preferences/shared_preferences/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png create mode 100644 packages/shared_preferences/shared_preferences/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md create mode 100644 packages/shared_preferences/shared_preferences/example/ios/Runner/Runner-Bridging-Header.h create mode 100644 packages/shared_preferences/shared_preferences/example/macos/.gitignore create mode 100644 packages/shared_preferences/shared_preferences/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 packages/shared_preferences/shared_preferences/example/web/favicon.png create mode 100644 packages/shared_preferences/shared_preferences/example/web/icons/Icon-192.png create mode 100644 packages/shared_preferences/shared_preferences/example/web/icons/Icon-512.png create mode 100644 packages/shared_preferences/shared_preferences/example/web/manifest.json diff --git a/packages/shared_preferences/shared_preferences/CHANGELOG.md b/packages/shared_preferences/shared_preferences/CHANGELOG.md index 5e09b3f87fb0..1f003ef5b133 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,3 +1,11 @@ +## 2.0.0-nullsafety + +* Migrate to null-safety. + +**Breaking changes**: + +* Setters no longer accept null to mean removing values. If you were previously using `set*(key, null)` for removing, use `remove(key)` instead. + ## 0.5.13+2 * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) diff --git a/packages/shared_preferences/shared_preferences/README.md b/packages/shared_preferences/shared_preferences/README.md index 516d7a91b848..e51ddea1c890 100644 --- a/packages/shared_preferences/shared_preferences/README.md +++ b/packages/shared_preferences/shared_preferences/README.md @@ -7,14 +7,6 @@ Wraps platform-specific persistent storage for simple data and there is no guarantee that writes will be persisted to disk after returning, so this plugin must not be used for storing critical data. - -**Please set your constraint to `shared_preferences: '>=0.5.y+x <2.0.0'`** - -## Backward compatible 1.0.0 version is coming -The plugin has reached a stable API, we guarantee that version `1.0.0` will be backward compatible with `0.5.y+z`. -Please use `shared_preferences: '>=0.5.y+x <2.0.0'` as your dependency constraint to allow a smoother ecosystem migration. -For more details see: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 - ## Usage To use this plugin, add `shared_preferences` as a [dependency in your pubspec.yaml file](https://flutter.dev/docs/development/platform-integration/platform-channels). diff --git a/packages/shared_preferences/shared_preferences/example/.gitignore b/packages/shared_preferences/shared_preferences/example/.gitignore new file mode 100644 index 000000000000..0fa6b675c0a5 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/.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/shared_preferences/shared_preferences/example/.metadata b/packages/shared_preferences/shared_preferences/example/.metadata new file mode 100644 index 000000000000..e0e9530fccc9 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/.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: 79b49b9e1057f90ebf797725233c6b311722de69 + channel: dev + +project_type: app diff --git a/packages/shared_preferences/shared_preferences/example/android/.gitignore b/packages/shared_preferences/shared_preferences/example/android/.gitignore new file mode 100644 index 000000000000..0a741cb43d66 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/android/.gitignore @@ -0,0 +1,11 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties diff --git a/packages/shared_preferences/shared_preferences/example/android/app/build.gradle b/packages/shared_preferences/shared_preferences/example/android/app/build.gradle index 58a6567a161c..3b7ee369beee 100644 --- a/packages/shared_preferences/shared_preferences/example/android/app/build.gradle +++ b/packages/shared_preferences/shared_preferences/example/android/app/build.gradle @@ -22,22 +22,23 @@ if (flutterVersionName == null) { } apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 29 + compileSdkVersion 30 - lintOptions { - disable 'InvalidPackage' + sourceSets { + main.java.srcDirs += 'src/main/kotlin' } defaultConfig { - applicationId "io.flutter.plugins.sharedpreferencesexample" + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "io.flutter.plugins.example" minSdkVersion 16 - targetSdkVersion 28 + targetSdkVersion 30 versionCode flutterVersionCode.toInteger() versionName flutterVersionName - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { @@ -54,7 +55,5 @@ flutter { } dependencies { - testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test:runner:1.1.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } diff --git a/packages/shared_preferences/shared_preferences/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/shared_preferences/shared_preferences/example/android/app/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index ee69dd68d1a6..000000000000 --- a/packages/shared_preferences/shared_preferences/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/packages/shared_preferences/shared_preferences/example/android/app/src/debug/AndroidManifest.xml b/packages/shared_preferences/shared_preferences/example/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 000000000000..2d5b32857609 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/packages/shared_preferences/shared_preferences/example/android/app/src/main/AndroidManifest.xml b/packages/shared_preferences/shared_preferences/example/android/app/src/main/AndroidManifest.xml index 04a642a4c748..2a12ff8e0009 100644 --- a/packages/shared_preferences/shared_preferences/example/android/app/src/main/AndroidManifest.xml +++ b/packages/shared_preferences/shared_preferences/example/android/app/src/main/AndroidManifest.xml @@ -1,26 +1,41 @@ - - - - - - - + + + + + + - + + diff --git a/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1Activity.java b/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1Activity.java deleted file mode 100644 index 3857aea6ce6b..000000000000 --- a/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1Activity.java +++ /dev/null @@ -1,22 +0,0 @@ -// 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. - -package io.flutter.plugins.sharedpreferencesexample; - -import android.os.Bundle; -import dev.flutter.plugins.integration_test.IntegrationTestPlugin; -import io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin; - -@SuppressWarnings("deprecation") -public class EmbeddingV1Activity extends io.flutter.app.FlutterActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - IntegrationTestPlugin.registerWith( - registrarFor("dev.flutter.plugins.integration_test.IntegrationTestPlugin")); - SharedPreferencesPlugin.registerWith( - registrarFor("io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin")); - } -} diff --git a/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1ActivityTest.java b/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1ActivityTest.java deleted file mode 100644 index 5b090d0f52c2..000000000000 --- a/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1ActivityTest.java +++ /dev/null @@ -1,15 +0,0 @@ - -package io.flutter.plugins.sharedpreferencesexample; - -import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.integration_test.FlutterTestRunner; -import org.junit.Rule; -import org.junit.runner.RunWith; - -@RunWith(FlutterTestRunner.class) -@SuppressWarnings("deprecation") -public class EmbeddingV1ActivityTest { - @Rule - public ActivityTestRule rule = - new ActivityTestRule<>(EmbeddingV1Activity.class); -} diff --git a/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/FlutterActivityTest.java b/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/FlutterActivityTest.java deleted file mode 100644 index 7a63d6d90c91..000000000000 --- a/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/FlutterActivityTest.java +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2019 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. - -package io.flutter.plugins.sharedpreferencesexample; - -import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.integration_test.FlutterTestRunner; -import io.flutter.embedding.android.FlutterActivity; -import org.junit.Rule; -import org.junit.runner.RunWith; - -@RunWith(FlutterTestRunner.class) -public class FlutterActivityTest { - @Rule - public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); -} diff --git a/packages/shared_preferences/shared_preferences/example/android/app/src/main/kotlin/io/flutter/plugins/example/MainActivity.kt b/packages/shared_preferences/shared_preferences/example/android/app/src/main/kotlin/io/flutter/plugins/example/MainActivity.kt new file mode 100644 index 000000000000..9059dae9e4c4 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/android/app/src/main/kotlin/io/flutter/plugins/example/MainActivity.kt @@ -0,0 +1,6 @@ +package io.flutter.plugins.example + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/packages/shared_preferences/shared_preferences/example/android/app/src/main/res/drawable-v21/launch_background.xml b/packages/shared_preferences/shared_preferences/example/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 000000000000..f74085f3f6a2 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/packages/shared_preferences/shared_preferences/example/android/app/src/main/res/drawable/launch_background.xml b/packages/shared_preferences/shared_preferences/example/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 000000000000..304732f88420 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/packages/shared_preferences/shared_preferences/example/android/app/src/main/res/values-night/styles.xml b/packages/shared_preferences/shared_preferences/example/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 000000000000..449a9f930826 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/packages/shared_preferences/shared_preferences/example/android/app/src/main/res/values/styles.xml b/packages/shared_preferences/shared_preferences/example/android/app/src/main/res/values/styles.xml new file mode 100644 index 000000000000..d74aa35c2826 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/packages/shared_preferences/shared_preferences/example/android/app/src/profile/AndroidManifest.xml b/packages/shared_preferences/shared_preferences/example/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 000000000000..2d5b32857609 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/packages/shared_preferences/shared_preferences/example/android/build.gradle b/packages/shared_preferences/shared_preferences/example/android/build.gradle index 54cc96612793..c505a8635265 100644 --- a/packages/shared_preferences/shared_preferences/example/android/build.gradle +++ b/packages/shared_preferences/shared_preferences/example/android/build.gradle @@ -1,11 +1,13 @@ buildscript { + ext.kotlin_version = '1.3.50' repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.4.0' + classpath 'com.android.tools.build:gradle:4.1.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/packages/shared_preferences/shared_preferences/example/android/gradle.properties b/packages/shared_preferences/shared_preferences/example/android/gradle.properties index a6738207fd15..94adc3a3f97a 100644 --- a/packages/shared_preferences/shared_preferences/example/android/gradle.properties +++ b/packages/shared_preferences/shared_preferences/example/android/gradle.properties @@ -1,4 +1,3 @@ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true -android.enableR8=true diff --git a/packages/shared_preferences/shared_preferences/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/shared_preferences/shared_preferences/example/android/gradle/wrapper/gradle-wrapper.properties index d757f3d33fcc..bc6a58afdda2 100644 --- a/packages/shared_preferences/shared_preferences/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/shared_preferences/shared_preferences/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip diff --git a/packages/shared_preferences/shared_preferences/example/android/settings.gradle b/packages/shared_preferences/shared_preferences/example/android/settings.gradle index 115da6cb4f4d..44e62bcf06ae 100644 --- a/packages/shared_preferences/shared_preferences/example/android/settings.gradle +++ b/packages/shared_preferences/shared_preferences/example/android/settings.gradle @@ -1,15 +1,11 @@ include ':app' -def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() -def plugins = new Properties() -def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') -if (pluginsFile.exists()) { - pluginsFile.withInputStream { stream -> plugins.load(stream) } -} +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } -plugins.each { name, path -> - def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() - include ":$name" - project(":$name").projectDir = pluginDirectory -} +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/packages/shared_preferences/shared_preferences/example/ios/.gitignore b/packages/shared_preferences/shared_preferences/example/ios/.gitignore new file mode 100644 index 000000000000..e96ef602b8d1 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/ios/.gitignore @@ -0,0 +1,32 @@ +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/packages/shared_preferences/shared_preferences/example/ios/Flutter/Debug.xcconfig b/packages/shared_preferences/shared_preferences/example/ios/Flutter/Debug.xcconfig index 9803018ca79d..d0eccdcaf401 100644 --- a/packages/shared_preferences/shared_preferences/example/ios/Flutter/Debug.xcconfig +++ b/packages/shared_preferences/shared_preferences/example/ios/Flutter/Debug.xcconfig @@ -1,2 +1,3 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" diff --git a/packages/shared_preferences/shared_preferences/example/ios/Flutter/Release.xcconfig b/packages/shared_preferences/shared_preferences/example/ios/Flutter/Release.xcconfig index a4a8c604e13d..c751c1d022fa 100644 --- a/packages/shared_preferences/shared_preferences/example/ios/Flutter/Release.xcconfig +++ b/packages/shared_preferences/shared_preferences/example/ios/Flutter/Release.xcconfig @@ -1,2 +1,3 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/shared_preferences/shared_preferences/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..919434a6254f --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/shared_preferences/shared_preferences/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/shared_preferences/shared_preferences/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000000..f9b0d7c5ea15 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/shared_preferences/shared_preferences/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..1d526a16ed0f --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/shared_preferences/shared_preferences/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/shared_preferences/shared_preferences/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000000..f9b0d7c5ea15 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.swift b/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.swift new file mode 100644 index 000000000000..70693e4a8c12 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/packages/shared_preferences/shared_preferences/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..dc9ada4725e9b0ddb1deab583e5b5102493aa332 GIT binary patch literal 10932 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 Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/packages/shared_preferences/shared_preferences/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/packages/shared_preferences/shared_preferences/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/packages/shared_preferences/shared_preferences/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 000000000000..89c2725b70f1 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner/Runner-Bridging-Header.h b/packages/shared_preferences/shared_preferences/example/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 000000000000..308a2a560b42 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/packages/shared_preferences/shared_preferences/example/macos/.gitignore b/packages/shared_preferences/shared_preferences/example/macos/.gitignore new file mode 100644 index 000000000000..d2fd3772308c --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/macos/.gitignore @@ -0,0 +1,6 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/xcuserdata/ diff --git a/packages/shared_preferences/shared_preferences/example/macos/Flutter/Flutter-Debug.xcconfig b/packages/shared_preferences/shared_preferences/example/macos/Flutter/Flutter-Debug.xcconfig index 785633d3a86b..4b81f9b2d200 100644 --- a/packages/shared_preferences/shared_preferences/example/macos/Flutter/Flutter-Debug.xcconfig +++ b/packages/shared_preferences/shared_preferences/example/macos/Flutter/Flutter-Debug.xcconfig @@ -1,2 +1,2 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/shared_preferences/shared_preferences/example/macos/Flutter/Flutter-Release.xcconfig b/packages/shared_preferences/shared_preferences/example/macos/Flutter/Flutter-Release.xcconfig index 5fba960c3af2..5caa9d1579e4 100644 --- a/packages/shared_preferences/shared_preferences/example/macos/Flutter/Flutter-Release.xcconfig +++ b/packages/shared_preferences/shared_preferences/example/macos/Flutter/Flutter-Release.xcconfig @@ -1,2 +1,2 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/shared_preferences/shared_preferences/example/macos/Runner.xcodeproj/project.pbxproj b/packages/shared_preferences/shared_preferences/example/macos/Runner.xcodeproj/project.pbxproj index 0e2413493f6e..cc89c8782812 100644 --- a/packages/shared_preferences/shared_preferences/example/macos/Runner.xcodeproj/project.pbxproj +++ b/packages/shared_preferences/shared_preferences/example/macos/Runner.xcodeproj/project.pbxproj @@ -26,11 +26,6 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; - 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; }; - 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; }; - D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - EA473EC5F2038B17A2FE4D78 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 748ADDF1719804343BB18004 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -50,8 +45,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */, - 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */, ); name = "Bundle Framework"; runOnlyForDeploymentPostprocessing = 0; @@ -61,7 +54,7 @@ /* Begin PBXFileReference section */ 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* connectivity_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = connectivity_example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; @@ -70,17 +63,11 @@ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; - 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; }; 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; - 748ADDF1719804343BB18004 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; - 80418F0A2F74D683C63A4D0A /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; - AA19B00394637215A825CF5E /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; }; - E960ED3977AF6DF197F74FFA /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -88,9 +75,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D73912F022F37F9E000D13A0 /* App.framework in Frameworks */, - 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */, - EA473EC5F2038B17A2FE4D78 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -115,14 +99,13 @@ 33CEB47122A05771004F2AC0 /* Flutter */, 33CC10EE2044A3C60003C045 /* Products */, D73912EC22F37F3D000D13A0 /* Frameworks */, - D42EAEE5849744148CC78D83 /* Pods */, ); sourceTree = ""; }; 33CC10EE2044A3C60003C045 /* Products */ = { isa = PBXGroup; children = ( - 33CC10ED2044A3C60003C045 /* connectivity_example.app */, + 33CC10ED2044A3C60003C045 /* example.app */, ); name = Products; sourceTree = ""; @@ -145,8 +128,6 @@ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, - D73912EF22F37F9E000D13A0 /* App.framework */, - 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */, ); path = Flutter; sourceTree = ""; @@ -164,21 +145,9 @@ path = Runner; sourceTree = ""; }; - D42EAEE5849744148CC78D83 /* Pods */ = { - isa = PBXGroup; - children = ( - 80418F0A2F74D683C63A4D0A /* Pods-Runner.debug.xcconfig */, - E960ED3977AF6DF197F74FFA /* Pods-Runner.release.xcconfig */, - AA19B00394637215A825CF5E /* Pods-Runner.profile.xcconfig */, - ); - name = Pods; - path = Pods; - sourceTree = ""; - }; D73912EC22F37F3D000D13A0 /* Frameworks */ = { isa = PBXGroup; children = ( - 748ADDF1719804343BB18004 /* Pods_Runner.framework */, ); name = Frameworks; sourceTree = ""; @@ -190,13 +159,11 @@ isa = PBXNativeTarget; buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - B24477CAB9D5BDFC8F3553DA /* [CP] Check Pods Manifest.lock */, 33CC10E92044A3C60003C045 /* Sources */, 33CC10EA2044A3C60003C045 /* Frameworks */, 33CC10EB2044A3C60003C045 /* Resources */, 33CC110E2044A8840003C045 /* Bundle Framework */, 3399D490228B24CF009A79C7 /* ShellScript */, - 84A8D21305B2F01D093A8F9C /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -205,7 +172,7 @@ ); name = Runner; productName = Runner; - productReference = 33CC10ED2044A3C60003C045 /* connectivity_example.app */; + productReference = 33CC10ED2044A3C60003C045 /* example.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -216,7 +183,7 @@ attributes = { LastSwiftUpdateCheck = 0920; LastUpgradeCheck = 0930; - ORGANIZATIONNAME = "Google LLC"; + ORGANIZATIONNAME = ""; TargetAttributes = { 33CC10EC2044A3C60003C045 = { CreatedOnToolsVersion = 9.2; @@ -235,7 +202,7 @@ }; }; buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 8.0"; + compatibilityVersion = "Xcode 9.3"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -281,7 +248,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n"; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; }; 33CC111E2044C6BF0003C045 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; @@ -301,44 +268,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh\ntouch Flutter/ephemeral/tripwire\n"; - }; - 84A8D21305B2F01D093A8F9C /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - B24477CAB9D5BDFC8F3553DA /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; }; /* End PBXShellScriptBuildPhase section */ @@ -431,10 +361,6 @@ CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter/ephemeral", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -561,10 +487,6 @@ CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter/ephemeral", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -585,10 +507,6 @@ CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter/ephemeral", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", diff --git a/packages/shared_preferences/shared_preferences/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/shared_preferences/shared_preferences/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/shared_preferences/shared_preferences/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/shared_preferences/shared_preferences/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 2a7d3e7f34ac..ae8ff59d97b3 100644 --- a/packages/shared_preferences/shared_preferences/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/shared_preferences/shared_preferences/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -15,7 +15,7 @@ @@ -27,23 +27,11 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> - - - - - - @@ -66,7 +54,7 @@ @@ -75,7 +63,7 @@ diff --git a/packages/shared_preferences/shared_preferences/example/macos/Runner/Configs/AppInfo.xcconfig b/packages/shared_preferences/shared_preferences/example/macos/Runner/Configs/AppInfo.xcconfig index a95148814518..cccda2e8a262 100644 --- a/packages/shared_preferences/shared_preferences/example/macos/Runner/Configs/AppInfo.xcconfig +++ b/packages/shared_preferences/shared_preferences/example/macos/Runner/Configs/AppInfo.xcconfig @@ -5,10 +5,10 @@ // 'flutter create' template. // The application's name. By default this is also the title of the Flutter window. -PRODUCT_NAME = connectivity_example +PRODUCT_NAME = example // The application's bundle identifier -PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.connectivityExample +PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.example // The copyright displayed in application information -PRODUCT_COPYRIGHT = Copyright © 2019 io.flutter.plugins. All rights reserved. +PRODUCT_COPYRIGHT = Copyright © 2021 io.flutter.plugins. All rights reserved. diff --git a/packages/shared_preferences/shared_preferences/example/web/favicon.png b/packages/shared_preferences/shared_preferences/example/web/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..8aaa46ac1ae21512746f852a42ba87e4165dfdd1 GIT binary patch literal 917 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0X7 zltGxWVyS%@P(fs7NJL45ua8x7ey(0(N`6wRUPW#JP&EUCO@$SZnVVXYs8ErclUHn2 zVXFjIVFhG^g!Ppaz)DK8ZIvQ?0~DO|i&7O#^-S~(l1AfjnEK zjFOT9D}DX)@^Za$W4-*MbbUihOG|wNBYh(yU7!lx;>x^|#0uTKVr7USFmqf|i<65o z3raHc^AtelCMM;Vme?vOfh>Xph&xL%(-1c06+^uR^q@XSM&D4+Kp$>4P^%3{)XKjo zGZknv$b36P8?Z_gF{nK@`XI}Z90TzwSQO}0J1!f2c(B=V`5aP@1P1a|PZ!4!3&Gl8 zTYqUsf!gYFyJnXpu0!n&N*SYAX-%d(5gVjrHJWqXQshj@!Zm{!01WsQrH~9=kTxW#6SvuapgMqt>$=j#%eyGrQzr zP{L-3gsMA^$I1&gsBAEL+vxi1*Igl=8#8`5?A-T5=z-sk46WA1IUT)AIZHx1rdUrf zVJrJn<74DDw`j)Ki#gt}mIT-Q`XRa2-jQXQoI%w`nb|XblvzK${ZzlV)m-XcwC(od z71_OEC5Bt9GEXosOXaPTYOia#R4ID2TiU~`zVMl08TV_C%DnU4^+HE>9(CE4D6?Fz oujB08i7adh9xk7*FX66dWH6F5TM;?E2b5PlUHx3vIVCg!0Dx9vYXATM literal 0 HcmV?d00001 diff --git a/packages/shared_preferences/shared_preferences/example/web/icons/Icon-192.png b/packages/shared_preferences/shared_preferences/example/web/icons/Icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..b749bfef07473333cf1dd31e9eed89862a5d52aa GIT binary patch literal 5292 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 literal 0 HcmV?d00001 diff --git a/packages/shared_preferences/shared_preferences/example/web/icons/Icon-512.png b/packages/shared_preferences/shared_preferences/example/web/icons/Icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..88cfd48dff1169879ba46840804b412fe02fefd6 GIT binary patch literal 8252 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 literal 0 HcmV?d00001 diff --git a/packages/shared_preferences/shared_preferences/example/web/manifest.json b/packages/shared_preferences/shared_preferences/example/web/manifest.json new file mode 100644 index 000000000000..8c012917dab7 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/web/manifest.json @@ -0,0 +1,23 @@ +{ + "name": "example", + "short_name": "example", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +} diff --git a/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart b/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart index c4c8710769df..03619fd14b4f 100644 --- a/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart +++ b/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart @@ -7,10 +7,9 @@ import 'dart:io' show Platform; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:meta/meta.dart'; - import 'package:shared_preferences_linux/shared_preferences_linux.dart'; -import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; import 'package:shared_preferences_platform_interface/method_channel_shared_preferences.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; import 'package:shared_preferences_windows/shared_preferences_windows.dart'; /// Wraps NSUserDefaults (on iOS) and SharedPreferences (on Android), providing @@ -21,7 +20,7 @@ class SharedPreferences { SharedPreferences._(this._preferenceCache); static const String _prefix = 'flutter.'; - static Completer _completer; + static Completer? _completer; static bool _manualDartRegistrationNeeded = true; static SharedPreferencesStorePlatform get _store { @@ -52,21 +51,22 @@ class SharedPreferences { /// performance-sensitive blocks. static Future getInstance() async { if (_completer == null) { - _completer = Completer(); + final completer = Completer(); try { final Map preferencesMap = await _getSharedPreferencesMap(); - _completer.complete(SharedPreferences._(preferencesMap)); + completer.complete(SharedPreferences._(preferencesMap)); } on Exception catch (e) { // If there's an error, explicitly return the future with an error. // then set the completer to null so we can retry. - _completer.completeError(e); - final Future sharedPrefsFuture = _completer.future; + completer.completeError(e); + final Future sharedPrefsFuture = completer.future; _completer = null; return sharedPrefsFuture; } + _completer = completer; } - return _completer.future; + return _completer!.future; } /// The cache that holds all preferences. @@ -83,86 +83,76 @@ class SharedPreferences { Set getKeys() => Set.from(_preferenceCache.keys); /// Reads a value of any type from persistent storage. - dynamic get(String key) => _preferenceCache[key]; + Object? get(String key) => _preferenceCache[key]; /// Reads a value from persistent storage, throwing an exception if it's not a /// bool. - bool getBool(String key) => _preferenceCache[key]; + bool? getBool(String key) => _preferenceCache[key] as bool?; /// Reads a value from persistent storage, throwing an exception if it's not /// an int. - int getInt(String key) => _preferenceCache[key]; + int? getInt(String key) => _preferenceCache[key] as int?; /// Reads a value from persistent storage, throwing an exception if it's not a /// double. - double getDouble(String key) => _preferenceCache[key]; + double? getDouble(String key) => _preferenceCache[key] as double?; /// Reads a value from persistent storage, throwing an exception if it's not a /// String. - String getString(String key) => _preferenceCache[key]; + String? getString(String key) => _preferenceCache[key] as String?; /// Returns true if persistent storage the contains the given [key]. bool containsKey(String key) => _preferenceCache.containsKey(key); /// Reads a set of string values from persistent storage, throwing an /// exception if it's not a string set. - List getStringList(String key) { - List list = _preferenceCache[key]; + List? getStringList(String key) { + List? list = _preferenceCache[key] as List?; if (list != null && list is! List) { list = list.cast().toList(); _preferenceCache[key] = list; } // Make a copy of the list so that later mutations won't propagate - return list?.toList(); + return list?.toList() as List?; } /// Saves a boolean [value] to persistent storage in the background. - /// - /// If [value] is null, this is equivalent to calling [remove()] on the [key]. Future setBool(String key, bool value) => _setValue('Bool', key, value); /// Saves an integer [value] to persistent storage in the background. - /// - /// If [value] is null, this is equivalent to calling [remove()] on the [key]. Future setInt(String key, int value) => _setValue('Int', key, value); /// Saves a double [value] to persistent storage in the background. /// /// Android doesn't support storing doubles, so it will be stored as a float. - /// - /// If [value] is null, this is equivalent to calling [remove()] on the [key]. Future setDouble(String key, double value) => _setValue('Double', key, value); /// Saves a string [value] to persistent storage in the background. - /// - /// If [value] is null, this is equivalent to calling [remove()] on the [key]. Future setString(String key, String value) => _setValue('String', key, value); /// Saves a list of strings [value] to persistent storage in the background. - /// - /// If [value] is null, this is equivalent to calling [remove()] on the [key]. Future setStringList(String key, List value) => _setValue('StringList', key, value); /// Removes an entry from persistent storage. - Future remove(String key) => _setValue(null, key, null); + Future remove(String key) { + final String prefixedKey = '$_prefix$key'; + _preferenceCache.remove(key); + return _store.remove(prefixedKey); + } Future _setValue(String valueType, String key, Object value) { + ArgumentError.checkNotNull(value, 'value'); final String prefixedKey = '$_prefix$key'; - if (value == null) { - _preferenceCache.remove(key); - return _store.remove(prefixedKey); + if (value is List) { + // Make a copy of the list so that later mutations won't propagate + _preferenceCache[key] = value.toList(); } else { - if (value is List) { - // Make a copy of the list so that later mutations won't propagate - _preferenceCache[key] = value.toList(); - } else { - _preferenceCache[key] = value; - } - return _store.setValue(valueType, prefixedKey, value); + _preferenceCache[key] = value; } + return _store.setValue(valueType, prefixedKey, value); } /// Always returns true. @@ -194,7 +184,7 @@ class SharedPreferences { final Map preferencesMap = {}; for (String key in fromSystem.keys) { assert(key.startsWith(_prefix)); - preferencesMap[key.substring(_prefix.length)] = fromSystem[key]; + preferencesMap[key.substring(_prefix.length)] = fromSystem[key]!; } return preferencesMap; } @@ -203,14 +193,14 @@ class SharedPreferences { /// /// If the singleton instance has been initialized already, it is nullified. @visibleForTesting - static void setMockInitialValues(Map values) { - final Map newValues = - values.map((String key, dynamic value) { + static void setMockInitialValues(Map values) { + final Map newValues = + values.map((String key, Object value) { String newKey = key; if (!key.startsWith(_prefix)) { newKey = '$_prefix$key'; } - return MapEntry(newKey, value); + return MapEntry(newKey, value); }); SharedPreferencesStorePlatform.instance = InMemorySharedPreferencesStore.withData(newValues); diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index 69689c738b8e..434c9c6bd4c2 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/shared_prefere # 0.5.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.5.13+2 +version: 2.0.0-nullsafety flutter: plugin: @@ -26,16 +26,16 @@ dependencies: meta: ^1.0.4 flutter: sdk: flutter - shared_preferences_platform_interface: ^1.0.0 + shared_preferences_platform_interface: ^2.0.0-nullsafety # The design on https://flutter.dev/go/federated-plugins was to leave # this constraint as "any". We cannot do it right now as it fails pub publish # validation, so we set a ^ constraint. # TODO(franciscojma): Revisit this (either update this part in the design or the pub tool). # https://github.com/flutter/flutter/issues/46264 - shared_preferences_linux: ^0.0.2 - shared_preferences_macos: ^0.0.1 - shared_preferences_web: ^0.1.2 - shared_preferences_windows: ^0.0.1 + shared_preferences_linux: ^0.0.4-nullsafety + shared_preferences_macos: ^0.0.2-nullsafety + shared_preferences_web: ^0.2.0-nullsafety + shared_preferences_windows: ^0.0.3-nullsafety dev_dependencies: flutter_test: @@ -47,5 +47,5 @@ dev_dependencies: pedantic: ^1.8.0 environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart index 80faba404154..9f6e7203fa85 100755 --- a/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart @@ -2,8 +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 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -13,7 +11,7 @@ void main() { TestWidgetsFlutterBinding.ensureInitialized(); group('SharedPreferences', () { - const Map kTestValues = { + const Map kTestValues = { 'flutter.String': 'hello world', 'flutter.bool': true, 'flutter.int': 42, @@ -29,8 +27,8 @@ void main() { 'flutter.List': ['baz', 'quox'], }; - FakeSharedPreferencesStore store; - SharedPreferences preferences; + late FakeSharedPreferencesStore store; + late SharedPreferences preferences; setUp(() async { store = FakeSharedPreferencesStore(kTestValues); @@ -107,16 +105,11 @@ void main() { test('removing', () async { const String key = 'testKey'; - await preferences.setString(key, null); - await preferences.setBool(key, null); - await preferences.setInt(key, null); - await preferences.setDouble(key, null); - await preferences.setStringList(key, null); await preferences.remove(key); expect( store.log, List.filled( - 6, + 1, isMethodCall( 'remove', arguments: 'flutter.$key', @@ -145,10 +138,12 @@ void main() { }); test('reloading', () async { - await preferences.setString('String', kTestValues['flutter.String']); + await preferences.setString( + 'String', kTestValues['flutter.String'] as String); expect(preferences.getString('String'), kTestValues['flutter.String']); - SharedPreferences.setMockInitialValues(kTestValues2); + SharedPreferences.setMockInitialValues( + kTestValues2.cast()); expect(preferences.getString('String'), kTestValues['flutter.String']); await preferences.reload(); @@ -167,17 +162,17 @@ void main() { test('test 1', () async { SharedPreferences.setMockInitialValues( - {_prefixedKey: 'my string'}); + {_prefixedKey: 'my string'}); final SharedPreferences prefs = await SharedPreferences.getInstance(); - final String value = prefs.getString(_key); + final String? value = prefs.getString(_key); expect(value, 'my string'); }); test('test 2', () async { SharedPreferences.setMockInitialValues( - {_prefixedKey: 'my other string'}); + {_prefixedKey: 'my other string'}); final SharedPreferences prefs = await SharedPreferences.getInstance(); - final String value = prefs.getString(_key); + final String? value = prefs.getString(_key); expect(value, 'my other string'); }); }); @@ -187,7 +182,7 @@ void main() { await preferences.setStringList("myList", myList); myList.add("foobar"); - final List cachedList = preferences.getStringList('myList'); + final List cachedList = preferences.getStringList('myList')!; expect(cachedList, []); cachedList.add("foobar2"); @@ -197,11 +192,11 @@ void main() { }); test('calling mock initial values with non-prefixed keys succeeds', () async { - SharedPreferences.setMockInitialValues({ + SharedPreferences.setMockInitialValues({ 'test': 'foo', }); final SharedPreferences prefs = await SharedPreferences.getInstance(); - final String value = prefs.getString('test'); + final String? value = prefs.getString('test'); expect(value, 'foo'); }); } From e50f17991d90366cc82c42d38259a35a98785d81 Mon Sep 17 00:00:00 2001 From: Ian Hickson Date: Tue, 9 Feb 2021 12:16:46 -0800 Subject: [PATCH 0118/1565] Update video_player_platform_interface to latest pigeon (#3507) See https://github.com/flutter/plugins/pull/3281 for context. --- .../CHANGELOG.md | 5 + .../lib/messages.dart | 585 +++++++----------- .../lib/test.dart | 196 ++++++ .../pubspec.yaml | 6 +- .../method_channel_video_player_test.dart | 1 + 5 files changed, 418 insertions(+), 375 deletions(-) create mode 100644 packages/video_player/video_player_platform_interface/lib/test.dart diff --git a/packages/video_player/video_player_platform_interface/CHANGELOG.md b/packages/video_player/video_player_platform_interface/CHANGELOG.md index 446fffd9a60e..34df33664c68 100644 --- a/packages/video_player/video_player_platform_interface/CHANGELOG.md +++ b/packages/video_player/video_player_platform_interface/CHANGELOG.md @@ -1,3 +1,8 @@ +## 4.0.0-nullsafety.0 + +* Update to latest Pigeon. + This includes a breaking change to how the test logic is exposed. + ## 3.0.0-nullsafety.3 * `messages.dart` sets Dart `2.12`. diff --git a/packages/video_player/video_player_platform_interface/lib/messages.dart b/packages/video_player/video_player_platform_interface/lib/messages.dart index 252cad6993ca..3f2d78ef9ed5 100644 --- a/packages/video_player/video_player_platform_interface/lib/messages.dart +++ b/packages/video_player/video_player_platform_interface/lib/messages.dart @@ -1,25 +1,24 @@ -// Autogenerated from Pigeon (v0.1.12), do not edit directly. +// Autogenerated from Pigeon (v0.1.19), 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 'package:flutter/services.dart'; import 'dart:typed_data' show Uint8List, Int32List, Int64List, Float64List; +import 'package:flutter/services.dart'; + class TextureMessage { int? textureId; - // ignore: unused_element - Map _toMap() { - final Map pigeonMap = {}; + + Object encode() { + final Map pigeonMap = {}; pigeonMap['textureId'] = textureId; return pigeonMap; } - // ignore: unused_element - static TextureMessage _fromMap(Map pigeonMap) { - final TextureMessage result = TextureMessage(); - result.textureId = pigeonMap['textureId']; - return result; + static TextureMessage decode(Object message) { + final Map pigeonMap = message as Map; + return TextureMessage()..textureId = pigeonMap['textureId'] as int; } } @@ -28,9 +27,9 @@ class CreateMessage { String? uri; String? packageName; String? formatHint; - // ignore: unused_element - Map _toMap() { - final Map pigeonMap = {}; + + Object encode() { + final Map pigeonMap = {}; pigeonMap['asset'] = asset; pigeonMap['uri'] = uri; pigeonMap['packageName'] = packageName; @@ -38,540 +37,382 @@ class CreateMessage { return pigeonMap; } - // ignore: unused_element - static CreateMessage _fromMap(Map pigeonMap) { - final CreateMessage result = CreateMessage(); - result.asset = pigeonMap['asset']; - result.uri = pigeonMap['uri']; - result.packageName = pigeonMap['packageName']; - result.formatHint = pigeonMap['formatHint']; - return result; + static CreateMessage decode(Object message) { + final Map pigeonMap = message as Map; + return CreateMessage() + ..asset = pigeonMap['asset'] as String + ..uri = pigeonMap['uri'] as String + ..packageName = pigeonMap['packageName'] as String + ..formatHint = pigeonMap['formatHint'] as String; } } class LoopingMessage { int? textureId; bool? isLooping; - // ignore: unused_element - Map _toMap() { - final Map pigeonMap = {}; + + Object encode() { + final Map pigeonMap = {}; pigeonMap['textureId'] = textureId; pigeonMap['isLooping'] = isLooping; return pigeonMap; } - // ignore: unused_element - static LoopingMessage _fromMap(Map pigeonMap) { - final LoopingMessage result = LoopingMessage(); - result.textureId = pigeonMap['textureId']; - result.isLooping = pigeonMap['isLooping']; - return result; + static LoopingMessage decode(Object message) { + final Map pigeonMap = message as Map; + return LoopingMessage() + ..textureId = pigeonMap['textureId'] as int + ..isLooping = pigeonMap['isLooping'] as bool; } } class VolumeMessage { int? textureId; double? volume; - // ignore: unused_element - Map _toMap() { - final Map pigeonMap = {}; + + Object encode() { + final Map pigeonMap = {}; pigeonMap['textureId'] = textureId; pigeonMap['volume'] = volume; return pigeonMap; } - // ignore: unused_element - static VolumeMessage _fromMap(Map pigeonMap) { - final VolumeMessage result = VolumeMessage(); - result.textureId = pigeonMap['textureId']; - result.volume = pigeonMap['volume']; - return result; + static VolumeMessage decode(Object message) { + final Map pigeonMap = message as Map; + return VolumeMessage() + ..textureId = pigeonMap['textureId'] as int + ..volume = pigeonMap['volume'] as double; } } class PlaybackSpeedMessage { int? textureId; double? speed; - // ignore: unused_element - Map _toMap() { - final Map pigeonMap = {}; + + Object encode() { + final Map pigeonMap = {}; pigeonMap['textureId'] = textureId; pigeonMap['speed'] = speed; return pigeonMap; } - // ignore: unused_element - static PlaybackSpeedMessage _fromMap(Map pigeonMap) { - final PlaybackSpeedMessage result = PlaybackSpeedMessage(); - result.textureId = pigeonMap['textureId']; - result.speed = pigeonMap['speed']; - return result; + static PlaybackSpeedMessage decode(Object message) { + final Map pigeonMap = message as Map; + return PlaybackSpeedMessage() + ..textureId = pigeonMap['textureId'] as int + ..speed = pigeonMap['speed'] as double; } } class PositionMessage { int? textureId; int? position; - // ignore: unused_element - Map _toMap() { - final Map pigeonMap = {}; + + Object encode() { + final Map pigeonMap = {}; pigeonMap['textureId'] = textureId; pigeonMap['position'] = position; return pigeonMap; } - // ignore: unused_element - static PositionMessage _fromMap(Map pigeonMap) { - final PositionMessage result = PositionMessage(); - result.textureId = pigeonMap['textureId']; - result.position = pigeonMap['position']; - return result; + static PositionMessage decode(Object message) { + final Map pigeonMap = message as Map; + return PositionMessage() + ..textureId = pigeonMap['textureId'] as int + ..position = pigeonMap['position'] as int; } } class MixWithOthersMessage { bool? mixWithOthers; - // ignore: unused_element - Map _toMap() { - final Map pigeonMap = {}; + + Object encode() { + final Map pigeonMap = {}; pigeonMap['mixWithOthers'] = mixWithOthers; return pigeonMap; } - // ignore: unused_element - static MixWithOthersMessage _fromMap(Map pigeonMap) { - final MixWithOthersMessage result = MixWithOthersMessage(); - result.mixWithOthers = pigeonMap['mixWithOthers']; - return result; + static MixWithOthersMessage decode(Object message) { + final Map pigeonMap = message as Map; + return MixWithOthersMessage() + ..mixWithOthers = pigeonMap['mixWithOthers'] as bool; } } class VideoPlayerApi { Future initialize() async { - const BasicMessageChannel channel = BasicMessageChannel( + const BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.VideoPlayerApi.initialize', StandardMessageCodec()); - - final Map? replyMap = await channel.send(null); + final Map? replyMap = + await channel.send(null) as Map?; if (replyMap == null) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null); + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); } else if (replyMap['error'] != null) { - final Map error = replyMap['error']; + final Map error = + replyMap['error'] as Map; throw PlatformException( - code: error['code'], - message: error['message'], - details: error['details']); + code: error['code'] as String, + message: error['message'] as String?, + details: error['details'], + ); } else { // noop } } Future create(CreateMessage arg) async { - final Map requestMap = arg._toMap(); - const BasicMessageChannel channel = BasicMessageChannel( + final Object encoded = arg.encode(); + const BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.VideoPlayerApi.create', StandardMessageCodec()); - - final Map? replyMap = await channel.send(requestMap); + final Map? replyMap = + await channel.send(encoded) as Map?; if (replyMap == null) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null); + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); } else if (replyMap['error'] != null) { - final Map error = replyMap['error']; + final Map error = + replyMap['error'] as Map; throw PlatformException( - code: error['code'], - message: error['message'], - details: error['details']); + code: error['code'] as String, + message: error['message'] as String?, + details: error['details'], + ); } else { - return TextureMessage._fromMap(replyMap['result']); + return TextureMessage.decode(replyMap['result']!); } } Future dispose(TextureMessage arg) async { - final Map requestMap = arg._toMap(); - const BasicMessageChannel channel = BasicMessageChannel( + final Object encoded = arg.encode(); + const BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.VideoPlayerApi.dispose', StandardMessageCodec()); - - final Map? replyMap = await channel.send(requestMap); + final Map? replyMap = + await channel.send(encoded) as Map?; if (replyMap == null) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null); + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); } else if (replyMap['error'] != null) { - final Map error = replyMap['error']; + final Map error = + replyMap['error'] as Map; throw PlatformException( - code: error['code'], - message: error['message'], - details: error['details']); + code: error['code'] as String, + message: error['message'] as String?, + details: error['details'], + ); } else { // noop } } Future setLooping(LoopingMessage arg) async { - final Map requestMap = arg._toMap(); - const BasicMessageChannel channel = BasicMessageChannel( + final Object encoded = arg.encode(); + const BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.VideoPlayerApi.setLooping', StandardMessageCodec()); - - final Map? replyMap = await channel.send(requestMap); + final Map? replyMap = + await channel.send(encoded) as Map?; if (replyMap == null) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null); + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); } else if (replyMap['error'] != null) { - final Map error = replyMap['error']; + final Map error = + replyMap['error'] as Map; throw PlatformException( - code: error['code'], - message: error['message'], - details: error['details']); + code: error['code'] as String, + message: error['message'] as String?, + details: error['details'], + ); } else { // noop } } Future setVolume(VolumeMessage arg) async { - final Map requestMap = arg._toMap(); - const BasicMessageChannel channel = BasicMessageChannel( + final Object encoded = arg.encode(); + const BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.VideoPlayerApi.setVolume', StandardMessageCodec()); - - final Map? replyMap = await channel.send(requestMap); + final Map? replyMap = + await channel.send(encoded) as Map?; if (replyMap == null) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null); + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); } else if (replyMap['error'] != null) { - final Map error = replyMap['error']; + final Map error = + replyMap['error'] as Map; throw PlatformException( - code: error['code'], - message: error['message'], - details: error['details']); + code: error['code'] as String, + message: error['message'] as String?, + details: error['details'], + ); } else { // noop } } Future setPlaybackSpeed(PlaybackSpeedMessage arg) async { - final Map requestMap = arg._toMap(); - const BasicMessageChannel channel = BasicMessageChannel( + final Object encoded = arg.encode(); + const BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.VideoPlayerApi.setPlaybackSpeed', StandardMessageCodec()); - - final Map? replyMap = await channel.send(requestMap); + final Map? replyMap = + await channel.send(encoded) as Map?; if (replyMap == null) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null); + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); } else if (replyMap['error'] != null) { - final Map error = replyMap['error']; + final Map error = + replyMap['error'] as Map; throw PlatformException( - code: error['code'], - message: error['message'], - details: error['details']); + code: error['code'] as String, + message: error['message'] as String?, + details: error['details'], + ); } else { // noop } } Future play(TextureMessage arg) async { - final Map requestMap = arg._toMap(); - const BasicMessageChannel channel = BasicMessageChannel( + final Object encoded = arg.encode(); + const BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.VideoPlayerApi.play', StandardMessageCodec()); - - final Map? replyMap = await channel.send(requestMap); + final Map? replyMap = + await channel.send(encoded) as Map?; if (replyMap == null) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null); + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); } else if (replyMap['error'] != null) { - final Map error = replyMap['error']; + final Map error = + replyMap['error'] as Map; throw PlatformException( - code: error['code'], - message: error['message'], - details: error['details']); + code: error['code'] as String, + message: error['message'] as String?, + details: error['details'], + ); } else { // noop } } Future position(TextureMessage arg) async { - final Map requestMap = arg._toMap(); - const BasicMessageChannel channel = BasicMessageChannel( + final Object encoded = arg.encode(); + const BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.VideoPlayerApi.position', StandardMessageCodec()); - - final Map? replyMap = await channel.send(requestMap); + final Map? replyMap = + await channel.send(encoded) as Map?; if (replyMap == null) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null); + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); } else if (replyMap['error'] != null) { - final Map error = replyMap['error']; + final Map error = + replyMap['error'] as Map; throw PlatformException( - code: error['code'], - message: error['message'], - details: error['details']); + code: error['code'] as String, + message: error['message'] as String?, + details: error['details'], + ); } else { - return PositionMessage._fromMap(replyMap['result']); + return PositionMessage.decode(replyMap['result']!); } } Future seekTo(PositionMessage arg) async { - final Map requestMap = arg._toMap(); - const BasicMessageChannel channel = BasicMessageChannel( + final Object encoded = arg.encode(); + const BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.VideoPlayerApi.seekTo', StandardMessageCodec()); - - final Map? replyMap = await channel.send(requestMap); + final Map? replyMap = + await channel.send(encoded) as Map?; if (replyMap == null) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null); + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); } else if (replyMap['error'] != null) { - final Map error = replyMap['error']; + final Map error = + replyMap['error'] as Map; throw PlatformException( - code: error['code'], - message: error['message'], - details: error['details']); + code: error['code'] as String, + message: error['message'] as String?, + details: error['details'], + ); } else { // noop } } Future pause(TextureMessage arg) async { - final Map requestMap = arg._toMap(); - const BasicMessageChannel channel = BasicMessageChannel( + final Object encoded = arg.encode(); + const BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.VideoPlayerApi.pause', StandardMessageCodec()); - - final Map? replyMap = await channel.send(requestMap); + final Map? replyMap = + await channel.send(encoded) as Map?; if (replyMap == null) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null); + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); } else if (replyMap['error'] != null) { - final Map error = replyMap['error']; + final Map error = + replyMap['error'] as Map; throw PlatformException( - code: error['code'], - message: error['message'], - details: error['details']); + code: error['code'] as String, + message: error['message'] as String?, + details: error['details'], + ); } else { // noop } } Future setMixWithOthers(MixWithOthersMessage arg) async { - final Map requestMap = arg._toMap(); - const BasicMessageChannel channel = BasicMessageChannel( + final Object encoded = arg.encode(); + const BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.VideoPlayerApi.setMixWithOthers', StandardMessageCodec()); - - final Map? replyMap = await channel.send(requestMap); + final Map? replyMap = + await channel.send(encoded) as Map?; if (replyMap == null) { throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - details: null); + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); } else if (replyMap['error'] != null) { - final Map error = replyMap['error']; + final Map error = + replyMap['error'] as Map; throw PlatformException( - code: error['code'], - message: error['message'], - details: error['details']); + code: error['code'] as String, + message: error['message'] as String?, + details: error['details'], + ); } else { // noop } } } - -abstract class TestHostVideoPlayerApi { - void initialize(); - TextureMessage create(CreateMessage arg); - void dispose(TextureMessage arg); - void setLooping(LoopingMessage arg); - void setVolume(VolumeMessage arg); - void setPlaybackSpeed(PlaybackSpeedMessage arg); - void play(TextureMessage arg); - PositionMessage position(TextureMessage arg); - void seekTo(PositionMessage arg); - void pause(TextureMessage arg); - void setMixWithOthers(MixWithOthersMessage arg); - static void setup(TestHostVideoPlayerApi? api) { - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.initialize', - StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((dynamic message) async { - api.initialize(); - return {}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.create', StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = - message as Map; - final CreateMessage input = CreateMessage._fromMap(mapMessage); - final TextureMessage output = api.create(input); - return {'result': output._toMap()}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.dispose', StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = - message as Map; - final TextureMessage input = TextureMessage._fromMap(mapMessage); - api.dispose(input); - return {}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.setLooping', - StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = - message as Map; - final LoopingMessage input = LoopingMessage._fromMap(mapMessage); - api.setLooping(input); - return {}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.setVolume', - StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = - message as Map; - final VolumeMessage input = VolumeMessage._fromMap(mapMessage); - api.setVolume(input); - return {}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.setPlaybackSpeed', - StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = - message as Map; - final PlaybackSpeedMessage input = - PlaybackSpeedMessage._fromMap(mapMessage); - api.setPlaybackSpeed(input); - return {}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.play', StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = - message as Map; - final TextureMessage input = TextureMessage._fromMap(mapMessage); - api.play(input); - return {}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.position', StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = - message as Map; - final TextureMessage input = TextureMessage._fromMap(mapMessage); - final PositionMessage output = api.position(input); - return {'result': output._toMap()}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.seekTo', StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = - message as Map; - final PositionMessage input = PositionMessage._fromMap(mapMessage); - api.seekTo(input); - return {}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.pause', StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = - message as Map; - final TextureMessage input = TextureMessage._fromMap(mapMessage); - api.pause(input); - return {}; - }); - } - } - { - const BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.VideoPlayerApi.setMixWithOthers', - StandardMessageCodec()); - if (api == null) { - channel.setMockMessageHandler(null); - } else { - channel.setMockMessageHandler((dynamic message) async { - final Map mapMessage = - message as Map; - final MixWithOthersMessage input = - MixWithOthersMessage._fromMap(mapMessage); - api.setMixWithOthers(input); - return {}; - }); - } - } - } -} diff --git a/packages/video_player/video_player_platform_interface/lib/test.dart b/packages/video_player/video_player_platform_interface/lib/test.dart new file mode 100644 index 000000000000..538e9526b111 --- /dev/null +++ b/packages/video_player/video_player_platform_interface/lib/test.dart @@ -0,0 +1,196 @@ +// Autogenerated from Pigeon (v0.1.19), 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'; +import 'package:flutter_test/flutter_test.dart'; + +import 'messages.dart'; + +abstract class TestHostVideoPlayerApi { + void initialize(); + TextureMessage create(CreateMessage arg); + void dispose(TextureMessage arg); + void setLooping(LoopingMessage arg); + void setVolume(VolumeMessage arg); + void setPlaybackSpeed(PlaybackSpeedMessage arg); + void play(TextureMessage arg); + PositionMessage position(TextureMessage arg); + void seekTo(PositionMessage arg); + void pause(TextureMessage arg); + void setMixWithOthers(MixWithOthersMessage arg); + static void setup(TestHostVideoPlayerApi? api) { + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.initialize', + StandardMessageCodec()); + if (api == null) { + channel.setMockMessageHandler(null); + } else { + channel.setMockMessageHandler((Object? message) async { + // ignore message + api.initialize(); + return {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.create', StandardMessageCodec()); + if (api == null) { + channel.setMockMessageHandler(null); + } else { + channel.setMockMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.VideoPlayerApi.create was null. Expected CreateMessage.'); + final CreateMessage input = CreateMessage.decode(message!); + final TextureMessage output = api.create(input); + return {'result': output.encode()}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.dispose', StandardMessageCodec()); + if (api == null) { + channel.setMockMessageHandler(null); + } else { + channel.setMockMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.VideoPlayerApi.dispose was null. Expected TextureMessage.'); + final TextureMessage input = TextureMessage.decode(message!); + api.dispose(input); + return {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.setLooping', + StandardMessageCodec()); + if (api == null) { + channel.setMockMessageHandler(null); + } else { + channel.setMockMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.VideoPlayerApi.setLooping was null. Expected LoopingMessage.'); + final LoopingMessage input = LoopingMessage.decode(message!); + api.setLooping(input); + return {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.setVolume', + StandardMessageCodec()); + if (api == null) { + channel.setMockMessageHandler(null); + } else { + channel.setMockMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.VideoPlayerApi.setVolume was null. Expected VolumeMessage.'); + final VolumeMessage input = VolumeMessage.decode(message!); + api.setVolume(input); + return {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.setPlaybackSpeed', + StandardMessageCodec()); + if (api == null) { + channel.setMockMessageHandler(null); + } else { + channel.setMockMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.VideoPlayerApi.setPlaybackSpeed was null. Expected PlaybackSpeedMessage.'); + final PlaybackSpeedMessage input = + PlaybackSpeedMessage.decode(message!); + api.setPlaybackSpeed(input); + return {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.play', StandardMessageCodec()); + if (api == null) { + channel.setMockMessageHandler(null); + } else { + channel.setMockMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.VideoPlayerApi.play was null. Expected TextureMessage.'); + final TextureMessage input = TextureMessage.decode(message!); + api.play(input); + return {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.position', StandardMessageCodec()); + if (api == null) { + channel.setMockMessageHandler(null); + } else { + channel.setMockMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.VideoPlayerApi.position was null. Expected TextureMessage.'); + final TextureMessage input = TextureMessage.decode(message!); + final PositionMessage output = api.position(input); + return {'result': output.encode()}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.seekTo', StandardMessageCodec()); + if (api == null) { + channel.setMockMessageHandler(null); + } else { + channel.setMockMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.VideoPlayerApi.seekTo was null. Expected PositionMessage.'); + final PositionMessage input = PositionMessage.decode(message!); + api.seekTo(input); + return {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.pause', StandardMessageCodec()); + if (api == null) { + channel.setMockMessageHandler(null); + } else { + channel.setMockMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.VideoPlayerApi.pause was null. Expected TextureMessage.'); + final TextureMessage input = TextureMessage.decode(message!); + api.pause(input); + return {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.VideoPlayerApi.setMixWithOthers', + StandardMessageCodec()); + if (api == null) { + channel.setMockMessageHandler(null); + } else { + channel.setMockMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.VideoPlayerApi.setMixWithOthers was null. Expected MixWithOthersMessage.'); + final MixWithOthersMessage input = + MixWithOthersMessage.decode(message!); + api.setMixWithOthers(input); + return {}; + }); + } + } + } +} diff --git a/packages/video_player/video_player_platform_interface/pubspec.yaml b/packages/video_player/video_player_platform_interface/pubspec.yaml index ea8d3179cf1d..e493eebd800e 100644 --- a/packages/video_player/video_player_platform_interface/pubspec.yaml +++ b/packages/video_player/video_player_platform_interface/pubspec.yaml @@ -3,16 +3,16 @@ description: A common platform interface for the video_player plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 3.0.0-nullsafety.3 +version: 4.0.0-nullsafety.0 dependencies: flutter: sdk: flutter meta: ^1.3.0-nullsafety.3 - -dev_dependencies: flutter_test: sdk: flutter + +dev_dependencies: mockito: ^4.1.1 pedantic: ^1.10.0-nullsafety.1 diff --git a/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart b/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart index 7f54c4f24f2c..669fd2839897 100644 --- a/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart +++ b/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart @@ -12,6 +12,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:video_player_platform_interface/messages.dart'; import 'package:video_player_platform_interface/method_channel_video_player.dart'; +import 'package:video_player_platform_interface/test.dart'; import 'package:video_player_platform_interface/video_player_platform_interface.dart'; class _ApiLogger implements TestHostVideoPlayerApi { From b4378ce9e748cb470807a9dc6482b340dfb56f6f Mon Sep 17 00:00:00 2001 From: Kabirou Agouda <64534846+kagouda@users.noreply.github.com> Date: Tue, 9 Feb 2021 21:24:43 +0000 Subject: [PATCH 0119/1565] [share] Update README.md (#3300) * Update README.md I just tried to update the links. The old links worked too but redirected to the current links. I just had the idea to put the current links directly. https://pub.dartlang.org/packages/share to https://pub.dev/packages/share/ and https://flutter.io/platform-plugins/ to https://flutter.dev/docs/development/packages-and-plugins/using-packages * Update pubspec.yaml * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md Co-authored-by: stuartmorgan --- packages/share/CHANGELOG.md | 4 ++++ packages/share/README.md | 4 ++-- packages/share/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/share/CHANGELOG.md b/packages/share/CHANGELOG.md index 855e737a1cd4..ba44db433d17 100644 --- a/packages/share/CHANGELOG.md +++ b/packages/share/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.3 + +* Update README with the new documentation urls. + ## 2.0.0-nullsafety.2 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. diff --git a/packages/share/README.md b/packages/share/README.md index 6ca38b416f03..a6e572258a2b 100644 --- a/packages/share/README.md +++ b/packages/share/README.md @@ -17,7 +17,7 @@ For more details see: https://github.com/flutter/flutter/wiki/Package-migration- ## Usage -To use this plugin, add `share` as a [dependency in your pubspec.yaml file](https://flutter.dev/docs/development/platform-integration/platform-channels). +To use this plugin, add `share` as a [dependency in your pubspec.yaml file](https://flutter.dev/docs/development/packages-and-plugins/using-packages/). ## Example @@ -44,4 +44,4 @@ To share one or multiple files invoke the static `shareFiles` method anywhere in ``` dart Share.shareFiles(['${directory.path}/image.jpg'], text: 'Great picture'); Share.shareFiles(['${directory.path}/image1.jpg', '${directory.path}/image2.jpg']); -``` \ No newline at end of file +``` diff --git a/packages/share/pubspec.yaml b/packages/share/pubspec.yaml index ca9b506bf35c..4d2b231bbdfb 100644 --- a/packages/share/pubspec.yaml +++ b/packages/share/pubspec.yaml @@ -2,7 +2,7 @@ name: share description: Flutter plugin for sharing content via the platform share UI, using the ACTION_SEND intent on Android and UIActivityViewController on iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/share -version: 2.0.0-nullsafety.2 +version: 2.0.0-nullsafety.3 flutter: plugin: From ca25038288fa6c777e96aa6406d7263393daf833 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Tue, 9 Feb 2021 22:53:22 +0100 Subject: [PATCH 0120/1565] Removed obsolete example folder from camera root (#3503) --- .../example/android/gradle/wrapper/gradle-wrapper.properties | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 packages/camera/example/android/gradle/wrapper/gradle-wrapper.properties diff --git a/packages/camera/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/camera/example/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index be52383ef49c..000000000000 --- a/packages/camera/example/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists From 291966048f6627e9a39516b7a7047f21f369e27f Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Tue, 9 Feb 2021 23:39:50 +0100 Subject: [PATCH 0121/1565] [camera_platform_interface] Migrate to null safety (#3530) * Migrate camera_platform_interface to null safety * Added camera to the NNBD plugin list * Correct version number * Convert optional parameters to required for CameraInitializationEvent * Convert CameraId in test to non-nullable * Test for null instead of enforcing non-null * Attempt to fix dependency problem building all plugins * Mark google_maps_flutter as NNBD * Depend on correct Dart SDK version * Attempt to fix dependency problem building all plugins * Attempt to fix dependency problem building all plugins * Attempt to fix dependency problem building all plugins * Attempt to fix dependency problem building all plugins * Add camera_platform_interface to exclude list * Exclude camera from nnbd and non-nnbd * Remove mockito dependency * Make sure enableAudio is default false * Include left-hand type definition * Removed unused import statement --- .../src/method_channel/method_channel_camera.dart | 4 ++-- .../src/platform_interface/camera_platform.dart | 4 +++- .../camera/camera_platform_interface/pubspec.yaml | 1 - .../test/camera_platform_interface_test.dart | 14 -------------- .../method_channel/method_channel_camera_test.dart | 2 +- 5 files changed, 6 insertions(+), 19 deletions(-) diff --git a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart index 3537a5ca40a9..9f7f723bcd79 100644 --- a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart +++ b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart @@ -59,7 +59,7 @@ class MethodChannelCamera extends CameraPlatform { @override Future> availableCameras() async { try { - final cameras = await _channel + final List>? cameras = await _channel .invokeListMethod>('availableCameras'); if (cameras == null) { @@ -82,7 +82,7 @@ class MethodChannelCamera extends CameraPlatform { Future createCamera( CameraDescription cameraDescription, ResolutionPreset? resolutionPreset, { - bool enableAudio = true, + bool enableAudio = false, }) async { try { final reply = await _channel diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart index 916922ff29fa..39a17e43dc0f 100644 --- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart +++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart @@ -44,6 +44,8 @@ abstract class CameraPlatform extends PlatformInterface { } /// Completes with a list of available cameras. + /// + /// This method returns an empty list when no cameras are available. Future> availableCameras() { throw UnimplementedError('availableCameras() is not implemented.'); } @@ -52,7 +54,7 @@ abstract class CameraPlatform extends PlatformInterface { Future createCamera( CameraDescription cameraDescription, ResolutionPreset? resolutionPreset, { - bool enableAudio = true, + bool enableAudio = false, }) { throw UnimplementedError('createCamera() is not implemented.'); } diff --git a/packages/camera/camera_platform_interface/pubspec.yaml b/packages/camera/camera_platform_interface/pubspec.yaml index a063765af63b..5817ce5c3fb0 100644 --- a/packages/camera/camera_platform_interface/pubspec.yaml +++ b/packages/camera/camera_platform_interface/pubspec.yaml @@ -17,7 +17,6 @@ dev_dependencies: flutter_test: sdk: flutter async: ^2.5.0-nullsafety.3 - mockito: ^5.0.0-nullsafety.5 pedantic: ^1.10.0-nullsafety.3 environment: diff --git a/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart b/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart index a96df845844a..f663db9776d1 100644 --- a/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart +++ b/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart @@ -6,8 +6,6 @@ import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:camera_platform_interface/src/method_channel/method_channel_camera.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; -import 'package:plugin_platform_interface/plugin_platform_interface.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); @@ -27,11 +25,6 @@ void main() { CameraPlatform.instance = ExtendsCameraPlatform(); }); - test('Can be mocked with `implements`', () { - final mock = MockCameraPlatform(); - CameraPlatform.instance = mock; - }); - test( 'Default implementation of availableCameras() should throw unimplemented error', () { @@ -423,11 +416,4 @@ class ImplementsCameraPlatform implements CameraPlatform { dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); } -class MockCameraPlatform extends Mock - with - // ignore: prefer_mixin - MockPlatformInterfaceMixin - implements - CameraPlatform {} - class ExtendsCameraPlatform extends CameraPlatform {} diff --git a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart index 7633de8626a6..5248d34c46b9 100644 --- a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart +++ b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart @@ -51,7 +51,7 @@ void main() { arguments: { 'cameraName': 'Test', 'resolutionPreset': 'high', - 'enableAudio': true + 'enableAudio': false }, ), ]); From 09d0f79b4f100d884c90f47ab0221f4e9e8671b2 Mon Sep 17 00:00:00 2001 From: Michael Thomsen Date: Wed, 10 Feb 2021 16:25:00 +0100 Subject: [PATCH 0122/1565] Update pubspecs (#3534) --- packages/android_alarm_manager/example/pubspec.yaml | 2 +- packages/android_intent/example/pubspec.yaml | 2 +- packages/battery/battery/example/pubspec.yaml | 2 +- packages/camera/camera/example/pubspec.yaml | 2 +- packages/connectivity/connectivity/example/pubspec.yaml | 2 +- packages/connectivity/connectivity_macos/example/pubspec.yaml | 2 +- packages/device_info/device_info/example/pubspec.yaml | 2 +- .../google_maps_flutter/example/pubspec.yaml | 2 +- .../example/pubspec.yaml | 2 +- packages/google_sign_in/google_sign_in/example/pubspec.yaml | 2 +- packages/image_picker/image_picker/example/pubspec.yaml | 2 +- packages/in_app_purchase/example/pubspec.yaml | 2 +- packages/integration_test/example/pubspec.yaml | 2 +- packages/local_auth/example/pubspec.yaml | 2 +- packages/package_info/example/pubspec.yaml | 2 +- packages/path_provider/path_provider/example/pubspec.yaml | 2 +- packages/path_provider/path_provider_macos/example/pubspec.yaml | 2 +- .../path_provider/path_provider_windows/example/pubspec.yaml | 2 +- packages/quick_actions/example/pubspec.yaml | 2 +- packages/sensors/example/pubspec.yaml | 2 +- packages/share/example/pubspec.yaml | 2 +- .../shared_preferences/shared_preferences/example/pubspec.yaml | 2 +- .../shared_preferences_linux/example/pubspec.yaml | 2 +- .../shared_preferences_macos/example/pubspec.yaml | 2 +- packages/url_launcher/url_launcher/example/pubspec.yaml | 2 +- packages/url_launcher/url_launcher_linux/example/pubspec.yaml | 2 +- packages/url_launcher/url_launcher_macos/example/pubspec.yaml | 2 +- packages/url_launcher/url_launcher_windows/example/pubspec.yaml | 2 +- packages/video_player/video_player/example/pubspec.yaml | 2 +- 29 files changed, 29 insertions(+), 29 deletions(-) diff --git a/packages/android_alarm_manager/example/pubspec.yaml b/packages/android_alarm_manager/example/pubspec.yaml index e636a246376b..140f90a37e79 100644 --- a/packages/android_alarm_manager/example/pubspec.yaml +++ b/packages/android_alarm_manager/example/pubspec.yaml @@ -24,4 +24,4 @@ flutter: environment: sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" + flutter: ">=1.12.13+hotfix.5" diff --git a/packages/android_intent/example/pubspec.yaml b/packages/android_intent/example/pubspec.yaml index 84455d99e618..34924d7b133e 100644 --- a/packages/android_intent/example/pubspec.yaml +++ b/packages/android_intent/example/pubspec.yaml @@ -20,4 +20,4 @@ flutter: environment: sdk: ">=2.3.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" + flutter: ">=1.12.13+hotfix.5" diff --git a/packages/battery/battery/example/pubspec.yaml b/packages/battery/battery/example/pubspec.yaml index 748660adf284..fae9f48956d1 100644 --- a/packages/battery/battery/example/pubspec.yaml +++ b/packages/battery/battery/example/pubspec.yaml @@ -19,4 +19,4 @@ flutter: environment: sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" + flutter: ">=1.12.13+hotfix.5" diff --git a/packages/camera/camera/example/pubspec.yaml b/packages/camera/camera/example/pubspec.yaml index 5d59ebf75c62..077c7a6568d9 100644 --- a/packages/camera/camera/example/pubspec.yaml +++ b/packages/camera/camera/example/pubspec.yaml @@ -23,4 +23,4 @@ flutter: environment: sdk: ">=2.7.0 <3.0.0" - flutter: ">=1.9.1+hotfix.4 <2.0.0" + flutter: ">=1.9.1+hotfix.4" diff --git a/packages/connectivity/connectivity/example/pubspec.yaml b/packages/connectivity/connectivity/example/pubspec.yaml index 682f0a2dd08a..bd723cb79cec 100644 --- a/packages/connectivity/connectivity/example/pubspec.yaml +++ b/packages/connectivity/connectivity/example/pubspec.yaml @@ -20,4 +20,4 @@ flutter: environment: sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" + flutter: ">=1.12.13+hotfix.5" diff --git a/packages/connectivity/connectivity_macos/example/pubspec.yaml b/packages/connectivity/connectivity_macos/example/pubspec.yaml index 041c3b364370..a6107fcbf103 100644 --- a/packages/connectivity/connectivity_macos/example/pubspec.yaml +++ b/packages/connectivity/connectivity_macos/example/pubspec.yaml @@ -20,4 +20,4 @@ flutter: environment: sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.10.0 <2.0.0" + flutter: ">=1.10.0" diff --git a/packages/device_info/device_info/example/pubspec.yaml b/packages/device_info/device_info/example/pubspec.yaml index 09567fd967b2..aa8019fc1022 100644 --- a/packages/device_info/device_info/example/pubspec.yaml +++ b/packages/device_info/device_info/example/pubspec.yaml @@ -19,4 +19,4 @@ flutter: environment: sdk: ">=2.10.0-56.0.dev <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" + flutter: ">=1.12.13+hotfix.5" diff --git a/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml index e0f79b571cb0..09e4924a03b7 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml @@ -3,7 +3,7 @@ description: Demonstrates how to use the google_maps_flutter plugin. environment: sdk: ">=2.2.0 <3.0.0" - flutter: ">=1.22.0 <2.0.0" + flutter: ">=1.22.0" dependencies: flutter: diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml index 3e64fa2da3f2..e032b14ec7a8 100755 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml +++ b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml @@ -21,4 +21,4 @@ flutter: environment: sdk: ">=2.0.0-dev.28.0 <3.0.0" - flutter: ">=1.12.13+hotfix.4 <2.0.0" + flutter: ">=1.12.13+hotfix.4" diff --git a/packages/google_sign_in/google_sign_in/example/pubspec.yaml b/packages/google_sign_in/google_sign_in/example/pubspec.yaml index ebf8e82719f2..d676add2f1df 100755 --- a/packages/google_sign_in/google_sign_in/example/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/example/pubspec.yaml @@ -20,4 +20,4 @@ flutter: environment: sdk: ">=2.0.0-dev.28.0 <3.0.0" - flutter: ">=1.12.13+hotfix.4 <2.0.0" + flutter: ">=1.12.13+hotfix.4" diff --git a/packages/image_picker/image_picker/example/pubspec.yaml b/packages/image_picker/image_picker/example/pubspec.yaml index 44364a1c19e7..017b2a22a86e 100755 --- a/packages/image_picker/image_picker/example/pubspec.yaml +++ b/packages/image_picker/image_picker/example/pubspec.yaml @@ -22,4 +22,4 @@ flutter: environment: sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.10.0 <2.0.0" + flutter: ">=1.10.0" diff --git a/packages/in_app_purchase/example/pubspec.yaml b/packages/in_app_purchase/example/pubspec.yaml index 48359dbc6a06..8f45e0e8e259 100644 --- a/packages/in_app_purchase/example/pubspec.yaml +++ b/packages/in_app_purchase/example/pubspec.yaml @@ -23,4 +23,4 @@ flutter: environment: sdk: ">=2.3.0 <3.0.0" - flutter: ">=1.9.1+hotfix.2 <2.0.0" + flutter: ">=1.9.1+hotfix.2" diff --git a/packages/integration_test/example/pubspec.yaml b/packages/integration_test/example/pubspec.yaml index 9384e9763935..84875dcb28fb 100644 --- a/packages/integration_test/example/pubspec.yaml +++ b/packages/integration_test/example/pubspec.yaml @@ -4,7 +4,7 @@ publish_to: 'none' environment: sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.6.7 <2.0.0" + flutter: ">=1.6.7" dependencies: flutter: diff --git a/packages/local_auth/example/pubspec.yaml b/packages/local_auth/example/pubspec.yaml index 9c7b91e672e6..653ff085ab5f 100644 --- a/packages/local_auth/example/pubspec.yaml +++ b/packages/local_auth/example/pubspec.yaml @@ -19,4 +19,4 @@ flutter: environment: sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" + flutter: ">=1.12.13+hotfix.5" diff --git a/packages/package_info/example/pubspec.yaml b/packages/package_info/example/pubspec.yaml index 605c375e9a8e..dd0bae12c039 100644 --- a/packages/package_info/example/pubspec.yaml +++ b/packages/package_info/example/pubspec.yaml @@ -19,4 +19,4 @@ flutter: environment: sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" + flutter: ">=1.12.13+hotfix.5" diff --git a/packages/path_provider/path_provider/example/pubspec.yaml b/packages/path_provider/path_provider/example/pubspec.yaml index 8659da753e15..98a0fd3c1bfb 100644 --- a/packages/path_provider/path_provider/example/pubspec.yaml +++ b/packages/path_provider/path_provider/example/pubspec.yaml @@ -19,4 +19,4 @@ flutter: environment: sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" + flutter: ">=1.12.13+hotfix.5" diff --git a/packages/path_provider/path_provider_macos/example/pubspec.yaml b/packages/path_provider/path_provider_macos/example/pubspec.yaml index 01ab42bbe71b..f1363cb4dfc7 100644 --- a/packages/path_provider/path_provider_macos/example/pubspec.yaml +++ b/packages/path_provider/path_provider_macos/example/pubspec.yaml @@ -24,4 +24,4 @@ flutter: environment: sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.10.0 <2.0.0" + flutter: ">=1.10.0" diff --git a/packages/path_provider/path_provider_windows/example/pubspec.yaml b/packages/path_provider/path_provider_windows/example/pubspec.yaml index 0e723f502581..1d2b9a7e98da 100644 --- a/packages/path_provider/path_provider_windows/example/pubspec.yaml +++ b/packages/path_provider/path_provider_windows/example/pubspec.yaml @@ -21,4 +21,4 @@ flutter: environment: sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.12.13+hotfix.4 <2.0.0" + flutter: ">=1.12.13+hotfix.4" diff --git a/packages/quick_actions/example/pubspec.yaml b/packages/quick_actions/example/pubspec.yaml index 6f9c0efd01af..03fc294f7361 100644 --- a/packages/quick_actions/example/pubspec.yaml +++ b/packages/quick_actions/example/pubspec.yaml @@ -19,4 +19,4 @@ flutter: environment: sdk: ">=2.0.0-dev.28.0 <3.0.0" - flutter: ">=1.9.1+hotfix.2 <2.0.0" + flutter: ">=1.9.1+hotfix.2" diff --git a/packages/sensors/example/pubspec.yaml b/packages/sensors/example/pubspec.yaml index eb46c611a43a..2cd1397c3527 100644 --- a/packages/sensors/example/pubspec.yaml +++ b/packages/sensors/example/pubspec.yaml @@ -19,5 +19,5 @@ flutter: environment: sdk: ">=2.0.0-dev.28.0 <3.0.0" - flutter: ">=1.9.1+hotfix.2 <2.0.0" + flutter: ">=1.9.1+hotfix.2" diff --git a/packages/share/example/pubspec.yaml b/packages/share/example/pubspec.yaml index 8b8623910b7a..b96141d40946 100644 --- a/packages/share/example/pubspec.yaml +++ b/packages/share/example/pubspec.yaml @@ -20,4 +20,4 @@ flutter: environment: sdk: ">=2.0.0-dev.28.0 <3.0.0" - flutter: ">=1.9.1+hotfix.2 <2.0.0" + flutter: ">=1.9.1+hotfix.2" diff --git a/packages/shared_preferences/shared_preferences/example/pubspec.yaml b/packages/shared_preferences/shared_preferences/example/pubspec.yaml index cf0fa64fea46..203300140250 100644 --- a/packages/shared_preferences/shared_preferences/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/example/pubspec.yaml @@ -19,5 +19,5 @@ flutter: environment: sdk: ">=2.0.0-dev.28.0 <3.0.0" - flutter: ">=1.9.1+hotfix.2 <2.0.0" + flutter: ">=1.9.1+hotfix.2" diff --git a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml index 591aad4c2c57..5728a918f76f 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml @@ -19,4 +19,4 @@ flutter: environment: sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.12.8 <2.0.0" + flutter: ">=1.12.8" diff --git a/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml index 93d5d42597cd..446dc8e07160 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml @@ -20,4 +20,4 @@ flutter: environment: sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.12.8 <2.0.0" + flutter: ">=1.12.8" diff --git a/packages/url_launcher/url_launcher/example/pubspec.yaml b/packages/url_launcher/url_launcher/example/pubspec.yaml index 7caea27744db..27e09749bc2c 100644 --- a/packages/url_launcher/url_launcher/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher/example/pubspec.yaml @@ -21,4 +21,4 @@ flutter: environment: sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" + flutter: ">=1.12.13+hotfix.5" diff --git a/packages/url_launcher/url_launcher_linux/example/pubspec.yaml b/packages/url_launcher/url_launcher_linux/example/pubspec.yaml index 9604637c336c..a0bb317bd417 100644 --- a/packages/url_launcher/url_launcher_linux/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_linux/example/pubspec.yaml @@ -20,4 +20,4 @@ flutter: environment: sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.12.8 <2.0.0" + flutter: ">=1.12.8" diff --git a/packages/url_launcher/url_launcher_macos/example/pubspec.yaml b/packages/url_launcher/url_launcher_macos/example/pubspec.yaml index dbf8951ff408..19952ff910de 100644 --- a/packages/url_launcher/url_launcher_macos/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_macos/example/pubspec.yaml @@ -20,4 +20,4 @@ flutter: environment: sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.12.8 <2.0.0" + flutter: ">=1.12.8" diff --git a/packages/url_launcher/url_launcher_windows/example/pubspec.yaml b/packages/url_launcher/url_launcher_windows/example/pubspec.yaml index 44a5424168c9..3ffbe4b35766 100644 --- a/packages/url_launcher/url_launcher_windows/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_windows/example/pubspec.yaml @@ -20,4 +20,4 @@ flutter: environment: sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.12.8 <2.0.0" + flutter: ">=1.12.8" diff --git a/packages/video_player/video_player/example/pubspec.yaml b/packages/video_player/video_player/example/pubspec.yaml index fb18d8b75efa..6a3d218e5529 100644 --- a/packages/video_player/video_player/example/pubspec.yaml +++ b/packages/video_player/video_player/example/pubspec.yaml @@ -28,4 +28,4 @@ flutter: environment: sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" + flutter: ">=1.12.13+hotfix.5" From 7624d9eb7776ce5f670ebc0d749ce8ac4405f950 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Wed, 10 Feb 2021 10:01:49 -0800 Subject: [PATCH 0123/1565] add post merge labeler (#3532) --- .github/post_merge_labeler.yml | 2 ++ .github/workflows/pull_request_label.yml | 23 +++++++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 .github/post_merge_labeler.yml diff --git a/.github/post_merge_labeler.yml b/.github/post_merge_labeler.yml new file mode 100644 index 000000000000..c02eb411773e --- /dev/null +++ b/.github/post_merge_labeler.yml @@ -0,0 +1,2 @@ +'needs-publishing': + - packages/*/** diff --git a/.github/workflows/pull_request_label.yml b/.github/workflows/pull_request_label.yml index 5016184d6d11..7b048d33e669 100644 --- a/.github/workflows/pull_request_label.yml +++ b/.github/workflows/pull_request_label.yml @@ -1,20 +1,31 @@ # This workflow applies labels to pull requests based on the # paths that are modified in the pull request. # -# Edit `.github/labeler.yml` to configure labels. +# Edit `.github/labeler.yml` and `.github/post_merge_labeler.yml` +# to configure labels. # # For more information, see: https://github.com/actions/labeler name: Pull Request Labeler on: - - pull_request_target + pull_request_target: + types: [opened, synchronize, reopened, closed] jobs: label: runs-on: ubuntu-latest steps: - - uses: actions/labeler@main - with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" - sync-labels: true + - uses: actions/labeler@v3 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + sync-labels: true + + post_merge_label: + if: github.event.action == 'closed' && github.event.pull_request.merged == true + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v3 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + configuration-path: .github/post_merge_labeler.yml From 31a631cb037f9ed0ac12c8de04bd6430820f3d6d Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Thu, 11 Feb 2021 16:49:35 -0800 Subject: [PATCH 0124/1565] [wifi_info_flutter] Migrate to null safety (#3425) --- .../wifi_info_flutter/CHANGELOG.md | 4 +++ .../integration_test/wifi_info_test.dart | 2 ++ .../lib/wifi_info_flutter.dart | 19 +++++-------- .../wifi_info_flutter/pubspec.yaml | 8 +++--- .../test/wifi_info_flutter_test.dart | 27 +++++++++---------- 5 files changed, 29 insertions(+), 31 deletions(-) diff --git a/packages/wifi_info_flutter/wifi_info_flutter/CHANGELOG.md b/packages/wifi_info_flutter/wifi_info_flutter/CHANGELOG.md index fa68eed175b7..c98140eedcf0 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/CHANGELOG.md +++ b/packages/wifi_info_flutter/wifi_info_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Migrate to null safety. + ## 1.0.4 * Android: Add Log warning for unsatisfied requirement(s) in Android P or higher. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/integration_test/wifi_info_test.dart b/packages/wifi_info_flutter/wifi_info_flutter/integration_test/wifi_info_test.dart index 103dc54a1eaa..4760b88d9019 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/integration_test/wifi_info_test.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/integration_test/wifi_info_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 'package:integration_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/wifi_info_flutter/wifi_info_flutter/lib/wifi_info_flutter.dart b/packages/wifi_info_flutter/wifi_info_flutter/lib/wifi_info_flutter.dart index 1183bf6c74bf..a2a69d161f5a 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/lib/wifi_info_flutter.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/lib/wifi_info_flutter.dart @@ -13,19 +13,14 @@ export 'package:wifi_info_flutter_platform_interface/wifi_info_flutter_platform_ /// Checks WI-FI status and more. class WifiInfo { + WifiInfo._(); + /// Constructs a singleton instance of [WifiInfo]. /// /// [WifiInfo] is designed to work as a singleton. - factory WifiInfo() { - if (_singleton == null) { - _singleton = WifiInfo._(); - } - return _singleton; - } - - WifiInfo._(); + factory WifiInfo() => _singleton; - static WifiInfo _singleton; + static final WifiInfo _singleton = WifiInfo._(); static WifiInfoFlutterPlatform get _platform => WifiInfoFlutterPlatform.instance; @@ -36,7 +31,7 @@ class WifiInfo { /// /// From android 8.0 onwards the GPS must be ON (high accuracy) /// in order to be able to obtain the SSID. - Future getWifiName() { + Future getWifiName() { return _platform.getWifiName(); } @@ -46,12 +41,12 @@ class WifiInfo { /// /// From Android 8.0 onwards the GPS must be ON (high accuracy) /// in order to be able to obtain the BSSID. - Future getWifiBSSID() { + Future getWifiBSSID() { return _platform.getWifiBSSID(); } /// Obtains the IP address of the connected wifi network - Future getWifiIP() { + Future getWifiIP() { return _platform.getWifiIP(); } diff --git a/packages/wifi_info_flutter/wifi_info_flutter/pubspec.yaml b/packages/wifi_info_flutter/wifi_info_flutter/pubspec.yaml index b8306a0696d2..0fbc27866201 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/pubspec.yaml +++ b/packages/wifi_info_flutter/wifi_info_flutter/pubspec.yaml @@ -1,20 +1,18 @@ name: wifi_info_flutter description: A new flutter plugin project. -version: 1.0.4 +version: 2.0.0-nullsafety homepage: https://github.com/flutter/plugins/tree/master/packages/wifi_info_flutter/wifi_info_flutter environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.20.0" dependencies: flutter: sdk: flutter - wifi_info_flutter_platform_interface: ^1.0.0 + wifi_info_flutter_platform_interface: ^2.0.0-nullsafety dev_dependencies: - mockito: ^4.1.1 - plugin_platform_interface: ^1.0.0 integration_test: path: ../../integration_test flutter_test: diff --git a/packages/wifi_info_flutter/wifi_info_flutter/test/wifi_info_flutter_test.dart b/packages/wifi_info_flutter/wifi_info_flutter/test/wifi_info_flutter_test.dart index a3a55170bce5..19e84f696f7f 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/test/wifi_info_flutter_test.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/test/wifi_info_flutter_test.dart @@ -2,13 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:wifi_info_flutter/wifi_info_flutter.dart'; import 'package:wifi_info_flutter_platform_interface/wifi_info_flutter_platform_interface.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:plugin_platform_interface/plugin_platform_interface.dart'; -import 'package:mockito/mockito.dart'; const String kWifiNameResult = '1337wifi'; const String kWifiBSSIDResult = 'c0:ff:33:c0:d3:55'; @@ -20,7 +16,7 @@ const LocationAuthorizationStatus kGetLocationResult = void main() { group('$WifiInfo', () { - WifiInfo wifiInfo; + late WifiInfo wifiInfo; MockWifiInfoFlutterPlatform fakePlatform; setUp(() async { @@ -30,17 +26,17 @@ void main() { }); test('getWifiName', () async { - String result = await wifiInfo.getWifiName(); + String? result = await wifiInfo.getWifiName(); expect(result, kWifiNameResult); }); test('getWifiBSSID', () async { - String result = await wifiInfo.getWifiBSSID(); + String? result = await wifiInfo.getWifiBSSID(); expect(result, kWifiBSSIDResult); }); test('getWifiIP', () async { - String result = await wifiInfo.getWifiIP(); + String? result = await wifiInfo.getWifiIP(); expect(result, kWifiIpAddressResult); }); @@ -58,27 +54,30 @@ void main() { }); } -class MockWifiInfoFlutterPlatform extends Mock - with MockPlatformInterfaceMixin - implements WifiInfoFlutterPlatform { - Future getWifiName() async { +class MockWifiInfoFlutterPlatform extends WifiInfoFlutterPlatform { + @override + Future getWifiName() async { return kWifiNameResult; } - Future getWifiBSSID() async { + @override + Future getWifiBSSID() async { return kWifiBSSIDResult; } - Future getWifiIP() async { + @override + Future getWifiIP() async { return kWifiIpAddressResult; } + @override Future requestLocationServiceAuthorization({ bool requestAlwaysLocationUsage = false, }) async { return kRequestLocationResult; } + @override Future getLocationServiceAuthorization() async { return kGetLocationResult; } From acabfe66607ae4e9a5c7ae1d39420fc3dff5ac44 Mon Sep 17 00:00:00 2001 From: Tim Sneath Date: Thu, 11 Feb 2021 17:40:44 -0800 Subject: [PATCH 0125/1565] Bump ffi dependencies (#3540) * Update to FFI 1.0 * Bump CHANGELOG --- .../path_provider/path_provider_windows/CHANGELOG.md | 5 +++++ .../lib/src/path_provider_windows_real.dart | 10 +++++----- .../path_provider/path_provider_windows/pubspec.yaml | 6 +++--- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/path_provider/path_provider_windows/CHANGELOG.md b/packages/path_provider/path_provider_windows/CHANGELOG.md index 6190c39457da..8d365319c32a 100644 --- a/packages/path_provider/path_provider_windows/CHANGELOG.md +++ b/packages/path_provider/path_provider_windows/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.1.0-nullsafety.3 + +* Bump ffi dependency to 1.0.0 +* Bump win32 dependency to 2.0.0-nullsafety.12 + ## 0.1.0-nullsafety.2 * Bump ffi dependency to 0.3.0-nullsafety.1 diff --git a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart index c88e10a0f9b3..db2ad9da207c 100644 --- a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart +++ b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart @@ -34,7 +34,7 @@ class VersionInfoQuerier { if (VerQueryValue(versionInfo, keyPath, valueAddress, length) == 0) { return null; } - return valueAddress.value.unpackString(length.value); + return valueAddress.value.toDartString(); } finally { calloc.free(keyPath); calloc.free(length); @@ -64,7 +64,7 @@ class PathProviderWindows extends PathProviderPlatform { final error = GetLastError(); throw WindowsException(error); } else { - path = buffer.unpackString(length); + path = buffer.toDartString(); // GetTempPath adds a trailing backslash, but SHGetKnownFolderPath does // not. Strip off trailing backslash for consistency with other methods @@ -132,7 +132,7 @@ class PathProviderWindows extends PathProviderPlatform { } } - final path = pathPtrPtr.value.unpackString(MAX_PATH); + final path = pathPtrPtr.value.toDartString(); return Future.value(path); } finally { calloc.free(pathPtrPtr); @@ -183,8 +183,8 @@ class PathProviderWindows extends PathProviderPlatform { // If there was no product name, use the executable name. if (productName == null) { - productName = path.basenameWithoutExtension( - moduleNameBuffer.unpackString(moduleNameLength)); + productName = + path.basenameWithoutExtension(moduleNameBuffer.toDartString()); } return companyName != null diff --git a/packages/path_provider/path_provider_windows/pubspec.yaml b/packages/path_provider/path_provider_windows/pubspec.yaml index 922594a9bd2d..d672ff90cdb9 100644 --- a/packages/path_provider/path_provider_windows/pubspec.yaml +++ b/packages/path_provider/path_provider_windows/pubspec.yaml @@ -1,7 +1,7 @@ name: path_provider_windows description: Windows implementation of the path_provider plugin homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_windows -version: 0.1.0-nullsafety.2 +version: 0.1.0-nullsafety.3 flutter: plugin: @@ -16,8 +16,8 @@ dependencies: path: ^1.8.0-nullsafety.3 flutter: sdk: flutter - ffi: '>=0.3.0-nullsafety.1 <2.0.0' - win32: ^2.0.0-nullsafety.10 + ffi: ^1.0.0 + win32: ^2.0.0-nullsafety.12 dev_dependencies: flutter_test: From 99d599c052801c9d3bdf892433be746e58af4bfb Mon Sep 17 00:00:00 2001 From: Jonas Finnemann Jensen Date: Fri, 12 Feb 2021 18:16:04 +0100 Subject: [PATCH 0126/1565] Added comment about path depenendencies (#3542) --- packages/android_alarm_manager/example/pubspec.yaml | 5 +++++ packages/android_intent/example/pubspec.yaml | 5 +++++ packages/battery/battery/example/pubspec.yaml | 5 +++++ packages/camera/camera/example/pubspec.yaml | 5 +++++ packages/connectivity/connectivity/example/pubspec.yaml | 5 +++++ .../connectivity/connectivity_macos/example/pubspec.yaml | 5 +++++ packages/device_info/device_info/example/pubspec.yaml | 5 +++++ packages/espresso/example/pubspec.yaml | 5 +++++ packages/file_selector/file_selector/example/pubspec.yaml | 5 +++++ .../flutter_plugin_android_lifecycle/example/pubspec.yaml | 5 +++++ .../google_maps_flutter/example/pubspec.yaml | 5 +++++ .../example/pubspec.yaml | 5 +++++ packages/google_sign_in/google_sign_in/example/pubspec.yaml | 5 +++++ packages/image_picker/image_picker/example/pubspec.yaml | 5 +++++ packages/in_app_purchase/example/pubspec.yaml | 5 +++++ packages/integration_test/example/pubspec.yaml | 5 +++++ packages/ios_platform_images/example/pubspec.yaml | 5 +++++ packages/local_auth/example/pubspec.yaml | 5 +++++ packages/package_info/example/pubspec.yaml | 5 +++++ packages/path_provider/path_provider/example/pubspec.yaml | 5 +++++ .../path_provider/path_provider_linux/example/pubspec.yaml | 5 +++++ .../path_provider/path_provider_macos/example/pubspec.yaml | 5 +++++ .../path_provider/path_provider_windows/example/pubspec.yaml | 5 +++++ packages/quick_actions/example/pubspec.yaml | 5 +++++ packages/sensors/example/pubspec.yaml | 5 +++++ packages/share/example/pubspec.yaml | 5 +++++ .../shared_preferences/example/pubspec.yaml | 5 +++++ .../shared_preferences_linux/example/pubspec.yaml | 5 +++++ .../shared_preferences_macos/example/pubspec.yaml | 5 +++++ .../shared_preferences_windows/example/pubspec.yaml | 5 +++++ packages/url_launcher/url_launcher/example/pubspec.yaml | 5 +++++ .../url_launcher/url_launcher_linux/example/pubspec.yaml | 5 +++++ .../url_launcher/url_launcher_macos/example/pubspec.yaml | 5 +++++ .../url_launcher/url_launcher_windows/example/pubspec.yaml | 5 +++++ packages/video_player/video_player/example/pubspec.yaml | 5 +++++ packages/webview_flutter/example/pubspec.yaml | 5 +++++ .../wifi_info_flutter/wifi_info_flutter/example/pubspec.yaml | 5 +++++ 37 files changed, 185 insertions(+) diff --git a/packages/android_alarm_manager/example/pubspec.yaml b/packages/android_alarm_manager/example/pubspec.yaml index 140f90a37e79..6fce3464b92a 100644 --- a/packages/android_alarm_manager/example/pubspec.yaml +++ b/packages/android_alarm_manager/example/pubspec.yaml @@ -5,6 +5,11 @@ dependencies: flutter: sdk: flutter android_alarm_manager: + # When depending on this package from a real application you should use: + # android_alarm_manager: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ shared_preferences: ^0.5.6 integration_test: diff --git a/packages/android_intent/example/pubspec.yaml b/packages/android_intent/example/pubspec.yaml index 34924d7b133e..7a0814d4acc0 100644 --- a/packages/android_intent/example/pubspec.yaml +++ b/packages/android_intent/example/pubspec.yaml @@ -5,6 +5,11 @@ dependencies: flutter: sdk: flutter android_intent: + # When depending on this package from a real application you should use: + # android_intent: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/battery/battery/example/pubspec.yaml b/packages/battery/battery/example/pubspec.yaml index fae9f48956d1..e118a7c21540 100644 --- a/packages/battery/battery/example/pubspec.yaml +++ b/packages/battery/battery/example/pubspec.yaml @@ -5,6 +5,11 @@ dependencies: flutter: sdk: flutter battery: + # When depending on this package from a real application you should use: + # battery: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/camera/camera/example/pubspec.yaml b/packages/camera/camera/example/pubspec.yaml index 077c7a6568d9..2a45fd69194c 100644 --- a/packages/camera/camera/example/pubspec.yaml +++ b/packages/camera/camera/example/pubspec.yaml @@ -3,6 +3,11 @@ description: Demonstrates how to use the camera plugin. dependencies: camera: + # When depending on this package from a real application you should use: + # camera: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ path_provider: ^0.5.0 flutter: diff --git a/packages/connectivity/connectivity/example/pubspec.yaml b/packages/connectivity/connectivity/example/pubspec.yaml index bd723cb79cec..b50214619c13 100644 --- a/packages/connectivity/connectivity/example/pubspec.yaml +++ b/packages/connectivity/connectivity/example/pubspec.yaml @@ -5,6 +5,11 @@ dependencies: flutter: sdk: flutter connectivity: + # When depending on this package from a real application you should use: + # connectivity: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/connectivity/connectivity_macos/example/pubspec.yaml b/packages/connectivity/connectivity_macos/example/pubspec.yaml index a6107fcbf103..49d24e76b717 100644 --- a/packages/connectivity/connectivity_macos/example/pubspec.yaml +++ b/packages/connectivity/connectivity_macos/example/pubspec.yaml @@ -6,6 +6,11 @@ dependencies: sdk: flutter connectivity: any connectivity_macos: + # When depending on this package from a real application you should use: + # connectivity_macos: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/device_info/device_info/example/pubspec.yaml b/packages/device_info/device_info/example/pubspec.yaml index aa8019fc1022..1f636977c2a9 100644 --- a/packages/device_info/device_info/example/pubspec.yaml +++ b/packages/device_info/device_info/example/pubspec.yaml @@ -5,6 +5,11 @@ dependencies: flutter: sdk: flutter device_info: + # When depending on this package from a real application you should use: + # device_info: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/espresso/example/pubspec.yaml b/packages/espresso/example/pubspec.yaml index d2d73da3c0ae..4854d85cb281 100644 --- a/packages/espresso/example/pubspec.yaml +++ b/packages/espresso/example/pubspec.yaml @@ -21,6 +21,11 @@ dev_dependencies: pedantic: ^1.8.0 espresso: + # When depending on this package from a real application you should use: + # espresso: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ # For information on the generic Dart part of this file, see the diff --git a/packages/file_selector/file_selector/example/pubspec.yaml b/packages/file_selector/file_selector/example/pubspec.yaml index 58f0abbf2658..3af2a67e9e93 100644 --- a/packages/file_selector/file_selector/example/pubspec.yaml +++ b/packages/file_selector/file_selector/example/pubspec.yaml @@ -25,6 +25,11 @@ dependencies: sdk: flutter file_selector: + # When depending on this package from a real application you should use: + # file_selector: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ # The following adds the Cupertino Icons font to your application. diff --git a/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml b/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml index 4643317c1951..833c2eba4319 100644 --- a/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml +++ b/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml @@ -5,6 +5,11 @@ dependencies: flutter: sdk: flutter flutter_plugin_android_lifecycle: + # When depending on this package from a real application you should use: + # flutter_plugin_android_lifecycle: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml index 09e4924a03b7..b3a0ae75daad 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml @@ -13,6 +13,11 @@ dependencies: # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.0 google_maps_flutter: + # When depending on this package from a real application you should use: + # google_maps_flutter: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ flutter_plugin_android_lifecycle: ^1.0.0 diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml index e032b14ec7a8..48dfef644a5c 100755 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml +++ b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml @@ -6,6 +6,11 @@ dependencies: sdk: flutter google_sign_in: ^4.4.1 extension_google_sign_in_as_googleapis_auth: + # When depending on this package from a real application you should use: + # extension_google_sign_in_as_googleapis_auth: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ googleapis: ^0.55.0 diff --git a/packages/google_sign_in/google_sign_in/example/pubspec.yaml b/packages/google_sign_in/google_sign_in/example/pubspec.yaml index d676add2f1df..e35aa9ace6a3 100755 --- a/packages/google_sign_in/google_sign_in/example/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/example/pubspec.yaml @@ -5,6 +5,11 @@ dependencies: flutter: sdk: flutter google_sign_in: + # When depending on this package from a real application you should use: + # google_sign_in: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ http: ^0.12.0 diff --git a/packages/image_picker/image_picker/example/pubspec.yaml b/packages/image_picker/image_picker/example/pubspec.yaml index 017b2a22a86e..eed223c1ade7 100755 --- a/packages/image_picker/image_picker/example/pubspec.yaml +++ b/packages/image_picker/image_picker/example/pubspec.yaml @@ -8,6 +8,11 @@ dependencies: sdk: flutter flutter_plugin_android_lifecycle: ^2.0.0-nullsafety.2 image_picker: + # When depending on this package from a real application you should use: + # image_picker: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/in_app_purchase/example/pubspec.yaml b/packages/in_app_purchase/example/pubspec.yaml index 8f45e0e8e259..9b623a15795a 100644 --- a/packages/in_app_purchase/example/pubspec.yaml +++ b/packages/in_app_purchase/example/pubspec.yaml @@ -13,6 +13,11 @@ dev_dependencies: flutter_driver: sdk: flutter in_app_purchase: + # When depending on this package from a real application you should use: + # in_app_purchase: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ integration_test: path: ../../integration_test diff --git a/packages/integration_test/example/pubspec.yaml b/packages/integration_test/example/pubspec.yaml index 84875dcb28fb..5ad8be4a818e 100644 --- a/packages/integration_test/example/pubspec.yaml +++ b/packages/integration_test/example/pubspec.yaml @@ -18,6 +18,11 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: + # When depending on this package from a real application you should use: + # integration_test: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ integration_test_macos: path: ../integration_test_macos diff --git a/packages/ios_platform_images/example/pubspec.yaml b/packages/ios_platform_images/example/pubspec.yaml index fa0f9eb3aac6..7802a2b0fe0a 100644 --- a/packages/ios_platform_images/example/pubspec.yaml +++ b/packages/ios_platform_images/example/pubspec.yaml @@ -18,6 +18,11 @@ dev_dependencies: flutter_test: sdk: flutter ios_platform_images: + # When depending on this package from a real application you should use: + # ios_platform_images: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ pedantic: ^1.8.0 diff --git a/packages/local_auth/example/pubspec.yaml b/packages/local_auth/example/pubspec.yaml index 653ff085ab5f..364f604a31d8 100644 --- a/packages/local_auth/example/pubspec.yaml +++ b/packages/local_auth/example/pubspec.yaml @@ -5,6 +5,11 @@ dependencies: flutter: sdk: flutter local_auth: + # When depending on this package from a real application you should use: + # local_auth: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/package_info/example/pubspec.yaml b/packages/package_info/example/pubspec.yaml index dd0bae12c039..0d0e1bae3c1f 100644 --- a/packages/package_info/example/pubspec.yaml +++ b/packages/package_info/example/pubspec.yaml @@ -5,6 +5,11 @@ dependencies: flutter: sdk: flutter package_info: + # When depending on this package from a real application you should use: + # package_info: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ integration_test: path: ../../integration_test diff --git a/packages/path_provider/path_provider/example/pubspec.yaml b/packages/path_provider/path_provider/example/pubspec.yaml index 98a0fd3c1bfb..bbb140e8f4bf 100644 --- a/packages/path_provider/path_provider/example/pubspec.yaml +++ b/packages/path_provider/path_provider/example/pubspec.yaml @@ -5,6 +5,11 @@ dependencies: flutter: sdk: flutter path_provider: + # When depending on this package from a real application you should use: + # path_provider: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/path_provider/path_provider_linux/example/pubspec.yaml b/packages/path_provider/path_provider_linux/example/pubspec.yaml index d66af910c998..a1a9dde163cf 100644 --- a/packages/path_provider/path_provider_linux/example/pubspec.yaml +++ b/packages/path_provider/path_provider_linux/example/pubspec.yaml @@ -17,6 +17,11 @@ dependencies: dependency_overrides: path_provider_linux: + # When depending on this package from a real application you should use: + # path_provider_linux: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/path_provider/path_provider_macos/example/pubspec.yaml b/packages/path_provider/path_provider_macos/example/pubspec.yaml index f1363cb4dfc7..cb904fa5ea98 100644 --- a/packages/path_provider/path_provider_macos/example/pubspec.yaml +++ b/packages/path_provider/path_provider_macos/example/pubspec.yaml @@ -10,6 +10,11 @@ dependencies: # to depend on it from path: dependency_overrides: path_provider_macos: + # When depending on this package from a real application you should use: + # path_provider_macos: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/path_provider/path_provider_windows/example/pubspec.yaml b/packages/path_provider/path_provider_windows/example/pubspec.yaml index 1d2b9a7e98da..7a34d90c0f6c 100644 --- a/packages/path_provider/path_provider_windows/example/pubspec.yaml +++ b/packages/path_provider/path_provider_windows/example/pubspec.yaml @@ -8,6 +8,11 @@ dependencies: dependency_overrides: path_provider_windows: + # When depending on this package from a real application you should use: + # path_provider_windows: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/quick_actions/example/pubspec.yaml b/packages/quick_actions/example/pubspec.yaml index 03fc294f7361..deba400ccd9f 100644 --- a/packages/quick_actions/example/pubspec.yaml +++ b/packages/quick_actions/example/pubspec.yaml @@ -5,6 +5,11 @@ dependencies: flutter: sdk: flutter quick_actions: + # When depending on this package from a real application you should use: + # quick_actions: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/sensors/example/pubspec.yaml b/packages/sensors/example/pubspec.yaml index 2cd1397c3527..d4702ac3aabe 100644 --- a/packages/sensors/example/pubspec.yaml +++ b/packages/sensors/example/pubspec.yaml @@ -5,6 +5,11 @@ dependencies: flutter: sdk: flutter sensors: + # When depending on this package from a real application you should use: + # sensors: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/share/example/pubspec.yaml b/packages/share/example/pubspec.yaml index b96141d40946..372633ec19ec 100644 --- a/packages/share/example/pubspec.yaml +++ b/packages/share/example/pubspec.yaml @@ -5,6 +5,11 @@ dependencies: flutter: sdk: flutter share: + # When depending on this package from a real application you should use: + # share: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ image_picker: ^0.6.7+4 diff --git a/packages/shared_preferences/shared_preferences/example/pubspec.yaml b/packages/shared_preferences/shared_preferences/example/pubspec.yaml index 203300140250..05f2528af2af 100644 --- a/packages/shared_preferences/shared_preferences/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/example/pubspec.yaml @@ -5,6 +5,11 @@ dependencies: flutter: sdk: flutter shared_preferences: + # When depending on this package from a real application you should use: + # shared_preferences: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml index 5728a918f76f..5fc8ae039812 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml @@ -5,6 +5,11 @@ dependencies: flutter: sdk: flutter shared_preferences_linux: + # When depending on this package from a real application you should use: + # shared_preferences_linux: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml index 446dc8e07160..5543b4a3b8c2 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml @@ -6,6 +6,11 @@ dependencies: sdk: flutter shared_preferences: any shared_preferences_macos: + # When depending on this package from a real application you should use: + # shared_preferences_macos: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml index 8a44e7874cfb..1af679b4ede3 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml @@ -11,6 +11,11 @@ dependencies: dependency_overrides: shared_preferences_windows: + # When depending on this package from a real application you should use: + # shared_preferences_windows: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/url_launcher/url_launcher/example/pubspec.yaml b/packages/url_launcher/url_launcher/example/pubspec.yaml index 27e09749bc2c..520b6863ec2d 100644 --- a/packages/url_launcher/url_launcher/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher/example/pubspec.yaml @@ -5,6 +5,11 @@ dependencies: flutter: sdk: flutter url_launcher: + # When depending on this package from a real application you should use: + # url_launcher: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/url_launcher/url_launcher_linux/example/pubspec.yaml b/packages/url_launcher/url_launcher_linux/example/pubspec.yaml index a0bb317bd417..e95bcd0af478 100644 --- a/packages/url_launcher/url_launcher_linux/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_linux/example/pubspec.yaml @@ -6,6 +6,11 @@ dependencies: sdk: flutter url_launcher: any url_launcher_linux: + # When depending on this package from a real application you should use: + # url_launcher_linux: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/url_launcher/url_launcher_macos/example/pubspec.yaml b/packages/url_launcher/url_launcher_macos/example/pubspec.yaml index 19952ff910de..2e66616101c2 100644 --- a/packages/url_launcher/url_launcher_macos/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_macos/example/pubspec.yaml @@ -6,6 +6,11 @@ dependencies: sdk: flutter url_launcher: any url_launcher_macos: + # When depending on this package from a real application you should use: + # url_launcher_macos: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/url_launcher/url_launcher_windows/example/pubspec.yaml b/packages/url_launcher/url_launcher_windows/example/pubspec.yaml index 3ffbe4b35766..2de2bcf14f44 100644 --- a/packages/url_launcher/url_launcher_windows/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_windows/example/pubspec.yaml @@ -6,6 +6,11 @@ dependencies: sdk: flutter url_launcher_platform_interface: any url_launcher_windows: + # When depending on this package from a real application you should use: + # url_launcher_windows: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/video_player/video_player/example/pubspec.yaml b/packages/video_player/video_player/example/pubspec.yaml index 6a3d218e5529..620186afc880 100644 --- a/packages/video_player/video_player/example/pubspec.yaml +++ b/packages/video_player/video_player/example/pubspec.yaml @@ -7,6 +7,11 @@ dependencies: flutter: sdk: flutter video_player: + # When depending on this package from a real application you should use: + # video_player: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/webview_flutter/example/pubspec.yaml b/packages/webview_flutter/example/pubspec.yaml index 1ace8afe400f..b61b6df590ce 100644 --- a/packages/webview_flutter/example/pubspec.yaml +++ b/packages/webview_flutter/example/pubspec.yaml @@ -8,6 +8,11 @@ dependencies: flutter: sdk: flutter webview_flutter: + # When depending on this package from a real application you should use: + # webview_flutter: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ dev_dependencies: diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/pubspec.yaml b/packages/wifi_info_flutter/wifi_info_flutter/example/pubspec.yaml index 7ebc1573ddcf..0f0adbf7b4a1 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/pubspec.yaml +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/pubspec.yaml @@ -10,6 +10,11 @@ dependencies: flutter: sdk: flutter wifi_info_flutter: + # When depending on this package from a real application you should use: + # wifi_info_flutter: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. path: ../ cupertino_icons: ^1.0.0 From 197d9761d0a301ddd3e3cc119d5e39ae339b4461 Mon Sep 17 00:00:00 2001 From: Aman Kumar Date: Sat, 13 Feb 2021 02:20:42 +0530 Subject: [PATCH 0127/1565] [android_alarm_manager] Migrated android_alarm_manager to support null safety #75233 (#3499) Migrated android_alarm_manager to support null safety. Fixes flutter/flutter#75233 --- packages/android_alarm_manager/CHANGELOG.md | 4 +++ packages/android_alarm_manager/README.md | 14 +--------- .../android_alarm_manager_test.dart | 2 ++ .../example/lib/main.dart | 10 +++---- .../example/pubspec.yaml | 6 ++-- .../example/test_driver/integration_test.dart | 2 ++ .../lib/android_alarm_manager.dart | 28 +++++++++---------- packages/android_alarm_manager/pubspec.yaml | 7 ++--- script/nnbd_plugins.sh | 2 +- 9 files changed, 34 insertions(+), 41 deletions(-) diff --git a/packages/android_alarm_manager/CHANGELOG.md b/packages/android_alarm_manager/CHANGELOG.md index df5b7a2fa752..b06f23c45a30 100644 --- a/packages/android_alarm_manager/CHANGELOG.md +++ b/packages/android_alarm_manager/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Migrate to null safety. + ## 0.4.5+20 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. diff --git a/packages/android_alarm_manager/README.md b/packages/android_alarm_manager/README.md index cf02bf66ff11..5a8a55e43641 100644 --- a/packages/android_alarm_manager/README.md +++ b/packages/android_alarm_manager/README.md @@ -5,13 +5,6 @@ A Flutter plugin for accessing the Android AlarmManager service, and running Dart code in the background when alarms fire. -**Please set your constraint to `android_alarm_manager: '>=0.4.y+x <2.0.0'`** - -## Backward compatible 1.0.0 version is coming -The plugin has reached a stable API, we guarantee that version `1.0.0` will be backward compatible with `0.4.y+z`. -Please use `android_alarm_manager: '>=0.4.y+x <2.0.0'` as your dependency constraint to allow a smoother ecosystem migration. -For more details see: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 - ## Getting Started After importing this plugin to your project as usual, add the following to your @@ -109,17 +102,12 @@ Which must be reflected in the application's `AndroidManifest.xml`. E.g.: **Note:** Not calling `AlarmService.setPluginRegistrant` will result in an exception being thrown when an alarm eventually fires. -### Flutter Android Embedding V2 (Flutter Version >= 1.12) +### Flutter Android Embedding V2 For the Flutter Android Embedding V2, plugins are registered with the background isolate via reflection so `AlarmService.setPluginRegistrant` does not need to be called. -**NOTE: this plugin is not completely compatible with the V2 embedding on -Flutter versions < 1.12 as the background isolate will not automatically -register plugins. This can be resolved by running `flutter upgrade` to upgrade -to the latest Flutter version.** - For help getting started with Flutter, view our online [documentation](https://flutter.dev/). diff --git a/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart b/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart index 4d2e3201eecf..4d53a5a945e6 100644 --- a/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart +++ b/packages/android_alarm_manager/example/integration_test/android_alarm_manager_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:io'; import 'package:android_alarm_manager_example/main.dart' as app; diff --git a/packages/android_alarm_manager/example/lib/main.dart b/packages/android_alarm_manager/example/lib/main.dart index ac27fec2e4c6..dc3779c8cbe2 100644 --- a/packages/android_alarm_manager/example/lib/main.dart +++ b/packages/android_alarm_manager/example/lib/main.dart @@ -22,7 +22,7 @@ const String isolateName = 'isolate'; final ReceivePort port = ReceivePort(); /// Global [SharedPreferences] object. -SharedPreferences prefs; +late SharedPreferences prefs; Future main() async { // TODO(bkonyi): uncomment @@ -54,7 +54,7 @@ class AlarmManagerExampleApp extends StatelessWidget { } class _AlarmHomePage extends StatefulWidget { - _AlarmHomePage({Key key, this.title}) : super(key: key); + _AlarmHomePage({Key? key, required this.title}) : super(key: key); final String title; @override @@ -86,7 +86,7 @@ class _AlarmHomePageState extends State<_AlarmHomePage> { } // The background - static SendPort uiSendPort; + static SendPort? uiSendPort; // The callback for our alarm static Future callback() async { @@ -94,7 +94,7 @@ class _AlarmHomePageState extends State<_AlarmHomePage> { // Get the previous cached count and increment it. final prefs = await SharedPreferences.getInstance(); - int currentCount = prefs.getInt(countKey); + int currentCount = prefs.getInt(countKey) ?? 0; await prefs.setInt(countKey, currentCount + 1); // This will be null if we're running in the background. @@ -140,7 +140,7 @@ class _AlarmHomePageState extends State<_AlarmHomePage> { await AndroidAlarmManager.oneShot( const Duration(seconds: 5), // Ensure we have a unique alarm ID. - Random().nextInt(pow(2, 31)), + Random().nextInt(pow(2, 31).toInt()), callback, exact: true, wakeup: true, diff --git a/packages/android_alarm_manager/example/pubspec.yaml b/packages/android_alarm_manager/example/pubspec.yaml index 6fce3464b92a..029a60493193 100644 --- a/packages/android_alarm_manager/example/pubspec.yaml +++ b/packages/android_alarm_manager/example/pubspec.yaml @@ -11,10 +11,10 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - shared_preferences: ^0.5.6 + shared_preferences: ^2.0.0-nullsafety integration_test: path: ../../integration_test - path_provider: ^1.3.1 + path_provider: ^2.0.0-nullsafety dev_dependencies: espresso: ^0.0.1+3 @@ -28,5 +28,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" diff --git a/packages/android_alarm_manager/example/test_driver/integration_test.dart b/packages/android_alarm_manager/example/test_driver/integration_test.dart index ed54518d7d00..4e78d04fa971 100644 --- a/packages/android_alarm_manager/example/test_driver/integration_test.dart +++ b/packages/android_alarm_manager/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/android_alarm_manager/lib/android_alarm_manager.dart b/packages/android_alarm_manager/lib/android_alarm_manager.dart index b8afa134472c..218959bc4bcc 100644 --- a/packages/android_alarm_manager/lib/android_alarm_manager.dart +++ b/packages/android_alarm_manager/lib/android_alarm_manager.dart @@ -31,7 +31,7 @@ void _alarmManagerCallbackDispatcher() { // PluginUtilities.getCallbackFromHandle performs a lookup based on the // callback handle and returns a tear-off of the original callback. - final Function closure = PluginUtilities.getCallbackFromHandle(handle); + final Function? closure = PluginUtilities.getCallbackFromHandle(handle); if (closure == null) { print('Fatal: could not find callback'); @@ -56,7 +56,7 @@ void _alarmManagerCallbackDispatcher() { // A lambda that returns the current instant in the form of a [DateTime]. typedef DateTime _Now(); // A lambda that gets the handle for the given [callback]. -typedef CallbackHandle _GetCallbackHandle(Function callback); +typedef CallbackHandle? _GetCallbackHandle(Function callback); /// A Flutter plugin for registering Dart callbacks with the Android /// AlarmManager service. @@ -77,7 +77,7 @@ class AndroidAlarmManager { /// the plugin. @visibleForTesting static void setTestOverides( - {_Now now, _GetCallbackHandle getCallbackHandle}) { + {_Now? now, _GetCallbackHandle? getCallbackHandle}) { _now = (now ?? _now); _getCallbackHandle = (getCallbackHandle ?? _getCallbackHandle); } @@ -88,12 +88,12 @@ class AndroidAlarmManager { /// Returns a [Future] that resolves to `true` on success and `false` on /// failure. static Future initialize() async { - final CallbackHandle handle = + final CallbackHandle? handle = _getCallbackHandle(_alarmManagerCallbackDispatcher); if (handle == null) { return false; } - final bool r = await _channel.invokeMethod( + final bool? r = await _channel.invokeMethod( 'AlarmService.start', [handle.toRawHandle()]); return r ?? false; } @@ -207,11 +207,11 @@ class AndroidAlarmManager { assert(callback is Function() || callback is Function(int)); assert(id.bitLength < 32); final int startMillis = time.millisecondsSinceEpoch; - final CallbackHandle handle = _getCallbackHandle(callback); + final CallbackHandle? handle = _getCallbackHandle(callback); if (handle == null) { return false; } - final bool r = + final bool? r = await _channel.invokeMethod('Alarm.oneShotAt', [ id, alarmClock, @@ -222,7 +222,7 @@ class AndroidAlarmManager { rescheduleOnReboot, handle.toRawHandle(), ]); - return (r == null) ? false : r; + return r ?? false; } /// Schedules a repeating timer to run `callback` with period `duration`. @@ -262,7 +262,7 @@ class AndroidAlarmManager { Duration duration, int id, Function callback, { - DateTime startAt, + DateTime? startAt, bool exact = false, bool wakeup = false, bool rescheduleOnReboot = false, @@ -274,11 +274,11 @@ class AndroidAlarmManager { final int period = duration.inMilliseconds; final int first = startAt != null ? startAt.millisecondsSinceEpoch : now + period; - final CallbackHandle handle = _getCallbackHandle(callback); + final CallbackHandle? handle = _getCallbackHandle(callback); if (handle == null) { return false; } - final bool r = await _channel.invokeMethod( + final bool? r = await _channel.invokeMethod( 'Alarm.periodic', [ id, exact, @@ -288,7 +288,7 @@ class AndroidAlarmManager { rescheduleOnReboot, handle.toRawHandle() ]); - return (r == null) ? false : r; + return r ?? false; } /// Cancels a timer. @@ -299,8 +299,8 @@ class AndroidAlarmManager { /// Returns a [Future] that resolves to `true` on success and `false` on /// failure. static Future cancel(int id) async { - final bool r = + final bool? r = await _channel.invokeMethod('Alarm.cancel', [id]); - return (r == null) ? false : r; + return r ?? false; } } diff --git a/packages/android_alarm_manager/pubspec.yaml b/packages/android_alarm_manager/pubspec.yaml index d1771c0f0380..ab1937242859 100644 --- a/packages/android_alarm_manager/pubspec.yaml +++ b/packages/android_alarm_manager/pubspec.yaml @@ -1,10 +1,7 @@ name: android_alarm_manager description: Flutter plugin for accessing the Android AlarmManager service, and running Dart code in the background when alarms fire. -# 0.4.y+z is compatible with 1.0.0, if you land a breaking change bump -# the version to 2.0.0. -# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.4.5+20 +version: 2.0.0-nullsafety homepage: https://github.com/flutter/plugins/tree/master/packages/android_alarm_manager dependencies: @@ -24,5 +21,5 @@ flutter: pluginClass: AndroidAlarmManagerPlugin environment: - sdk: ">=2.1.0 <3.0.0" + sdk: '>=2.12.0-0 <3.0.0' flutter: ">=1.12.13+hotfix.5" diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index 492c8adf3ad5..5a54a7ff30d6 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -5,6 +5,7 @@ # null-safe is available on stable. readonly NNBD_PLUGINS_LIST=( + "android_alarm_manager" "android_intent" "battery" "camera" @@ -36,7 +37,6 @@ readonly NNBD_PLUGINS_LIST=( # building the all plugins app. This list should be kept empty. readonly NON_NNBD_PLUGINS_LIST=( - # "android_alarm_manager" "camera" # "google_maps_flutter" # "image_picker" From e0262421d2c9133438c7f5cb5ceea19452665c27 Mon Sep 17 00:00:00 2001 From: Emmanuel Garcia Date: Fri, 12 Feb 2021 13:46:44 -0800 Subject: [PATCH 0128/1565] Move plugin tools code (#3544) --- .gitmodules | 3 - script/common.sh | 4 +- script/plugin_tools | 1 - script/tool/README.md | 8 + script/tool/lib/src/analyze_command.dart | 94 ++++ .../tool/lib/src/build_examples_command.dart | 188 +++++++ script/tool/lib/src/common.dart | 466 ++++++++++++++++++ .../src/create_all_plugins_app_command.dart | 200 ++++++++ .../tool/lib/src/drive_examples_command.dart | 210 ++++++++ .../lib/src/firebase_test_lab_command.dart | 264 ++++++++++ script/tool/lib/src/format_command.dart | 147 ++++++ script/tool/lib/src/java_test_command.dart | 89 ++++ .../tool/lib/src/lint_podspecs_command.dart | 146 ++++++ script/tool/lib/src/list_command.dart | 60 +++ script/tool/lib/src/main.dart | 63 +++ .../tool/lib/src/publish_plugin_command.dart | 223 +++++++++ script/tool/lib/src/test_command.dart | 101 ++++ .../tool/lib/src/version_check_command.dart | 220 +++++++++ script/tool/lib/src/xctest_command.dart | 216 ++++++++ script/tool/pubspec.yaml | 25 + 20 files changed, 2722 insertions(+), 6 deletions(-) delete mode 100644 .gitmodules delete mode 160000 script/plugin_tools create mode 100644 script/tool/README.md create mode 100644 script/tool/lib/src/analyze_command.dart create mode 100644 script/tool/lib/src/build_examples_command.dart create mode 100644 script/tool/lib/src/common.dart create mode 100644 script/tool/lib/src/create_all_plugins_app_command.dart create mode 100644 script/tool/lib/src/drive_examples_command.dart create mode 100644 script/tool/lib/src/firebase_test_lab_command.dart create mode 100644 script/tool/lib/src/format_command.dart create mode 100644 script/tool/lib/src/java_test_command.dart create mode 100644 script/tool/lib/src/lint_podspecs_command.dart create mode 100644 script/tool/lib/src/list_command.dart create mode 100644 script/tool/lib/src/main.dart create mode 100644 script/tool/lib/src/publish_plugin_command.dart create mode 100644 script/tool/lib/src/test_command.dart create mode 100644 script/tool/lib/src/version_check_command.dart create mode 100644 script/tool/lib/src/xctest_command.dart create mode 100644 script/tool/pubspec.yaml diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index d83ab14b23a0..000000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "script/plugin_tools"] - path = script/plugin_tools - url = https://github.com/flutter/plugin_tools.git diff --git a/script/common.sh b/script/common.sh index 4c8aff9822f6..28c37540af88 100644 --- a/script/common.sh +++ b/script/common.sh @@ -48,6 +48,6 @@ function check_changed_packages() { # Runs the plugin tools from the plugin_tools git submodule. function plugin_tools() { - (pushd "$REPO_DIR/script/plugin_tools" && dart pub get && popd) >/dev/null - dart run "$REPO_DIR/script/plugin_tools/lib/src/main.dart" "$@" + (pushd "$REPO_DIR/script/tool" && dart pub get && popd) >/dev/null + dart run "$REPO_DIR/script/tool/lib/src/main.dart" "$@" } diff --git a/script/plugin_tools b/script/plugin_tools deleted file mode 160000 index 432c56da3588..000000000000 --- a/script/plugin_tools +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 432c56da35880e95f6cbb02c40e9da0361771f48 diff --git a/script/tool/README.md b/script/tool/README.md new file mode 100644 index 000000000000..162ca0d98a74 --- /dev/null +++ b/script/tool/README.md @@ -0,0 +1,8 @@ +# Flutter Plugin Tools + +To run the tool: + +```sh +dart pub get +dart run lib/src/main.dart +``` diff --git a/script/tool/lib/src/analyze_command.dart b/script/tool/lib/src/analyze_command.dart new file mode 100644 index 000000000000..8cd57fa0b338 --- /dev/null +++ b/script/tool/lib/src/analyze_command.dart @@ -0,0 +1,94 @@ +// 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. + +import 'dart:async'; + +import 'package:file/file.dart'; +import 'package:path/path.dart' as p; + +import 'common.dart'; + +class AnalyzeCommand extends PluginCommand { + AnalyzeCommand( + Directory packagesDir, + FileSystem fileSystem, { + ProcessRunner processRunner = const ProcessRunner(), + }) : super(packagesDir, fileSystem, processRunner: processRunner) { + argParser.addMultiOption(_customAnalysisFlag, + help: + 'Directories (comma seperated) that are allowed to have their own analysis options.', + defaultsTo: []); + } + + static const String _customAnalysisFlag = 'custom-analysis'; + + @override + final String name = 'analyze'; + + @override + final String description = 'Analyzes all packages using package:tuneup.\n\n' + 'This command requires "pub" and "flutter" to be in your path.'; + + @override + Future run() async { + checkSharding(); + + print('Verifying analysis settings...'); + final List files = packagesDir.listSync(recursive: true); + for (final FileSystemEntity file in files) { + if (file.basename != 'analysis_options.yaml' && + file.basename != '.analysis_options') { + continue; + } + + final bool whitelisted = argResults[_customAnalysisFlag].any( + (String directory) => + p.isWithin(p.join(packagesDir.path, directory), file.path)); + if (whitelisted) { + continue; + } + + print('Found an extra analysis_options.yaml in ${file.absolute.path}.'); + print( + 'If this was deliberate, pass the package to the analyze command with the --$_customAnalysisFlag flag and try again.'); + throw ToolExit(1); + } + + print('Activating tuneup package...'); + await processRunner.runAndStream( + 'pub', ['global', 'activate', 'tuneup'], + workingDir: packagesDir, exitOnError: true); + + await for (Directory package in getPackages()) { + if (isFlutterPackage(package, fileSystem)) { + await processRunner.runAndStream('flutter', ['packages', 'get'], + workingDir: package, exitOnError: true); + } else { + await processRunner.runAndStream('pub', ['get'], + workingDir: package, exitOnError: true); + } + } + + final List failingPackages = []; + await for (Directory package in getPlugins()) { + final int exitCode = await processRunner.runAndStream( + 'pub', ['global', 'run', 'tuneup', 'check'], + workingDir: package); + if (exitCode != 0) { + failingPackages.add(p.basename(package.path)); + } + } + + print('\n\n'); + if (failingPackages.isNotEmpty) { + print('The following packages have analyzer errors (see above):'); + failingPackages.forEach((String package) { + print(' * $package'); + }); + throw ToolExit(1); + } + + print('No analyzer errors found!'); + } +} diff --git a/script/tool/lib/src/build_examples_command.dart b/script/tool/lib/src/build_examples_command.dart new file mode 100644 index 000000000000..53da9086abaa --- /dev/null +++ b/script/tool/lib/src/build_examples_command.dart @@ -0,0 +1,188 @@ +// 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. + +import 'dart:async'; +import 'dart:io' as io; + +import 'package:file/file.dart'; +import 'package:path/path.dart' as p; +import 'package:platform/platform.dart'; + +import 'common.dart'; + +class BuildExamplesCommand extends PluginCommand { + BuildExamplesCommand( + Directory packagesDir, + FileSystem fileSystem, { + ProcessRunner processRunner = const ProcessRunner(), + }) : super(packagesDir, fileSystem, processRunner: processRunner) { + argParser.addFlag(kLinux, defaultsTo: false); + argParser.addFlag(kMacos, defaultsTo: false); + argParser.addFlag(kWindows, defaultsTo: false); + argParser.addFlag(kIpa, defaultsTo: io.Platform.isMacOS); + argParser.addFlag(kApk); + argParser.addOption( + kEnableExperiment, + defaultsTo: '', + help: 'Enables the given Dart SDK experiments.', + ); + } + + @override + final String name = 'build-examples'; + + @override + final String description = + 'Builds all example apps (IPA for iOS and APK for Android).\n\n' + 'This command requires "flutter" to be in your path.'; + + @override + Future run() async { + if (!argResults[kIpa] && + !argResults[kApk] && + !argResults[kLinux] && + !argResults[kMacos] && + !argResults[kWindows]) { + print( + 'None of --linux, --macos, --windows, --apk nor --ipa were specified, ' + 'so not building anything.'); + return; + } + final String flutterCommand = + LocalPlatform().isWindows ? 'flutter.bat' : 'flutter'; + + final String enableExperiment = argResults[kEnableExperiment]; + + checkSharding(); + final List failingPackages = []; + await for (Directory plugin in getPlugins()) { + for (Directory example in getExamplesForPlugin(plugin)) { + final String packageName = + p.relative(example.path, from: packagesDir.path); + + if (argResults[kLinux]) { + print('\nBUILDING Linux for $packageName'); + if (isLinuxPlugin(plugin, fileSystem)) { + int buildExitCode = await processRunner.runAndStream( + flutterCommand, + [ + 'build', + kLinux, + if (enableExperiment.isNotEmpty) + '--enable-experiment=$enableExperiment', + ], + workingDir: example); + if (buildExitCode != 0) { + failingPackages.add('$packageName (linux)'); + } + } else { + print('Linux is not supported by this plugin'); + } + } + + if (argResults[kMacos]) { + print('\nBUILDING macOS for $packageName'); + if (isMacOsPlugin(plugin, fileSystem)) { + // TODO(https://github.com/flutter/flutter/issues/46236): + // Builing macos without running flutter pub get first results + // in an error. + int exitCode = await processRunner.runAndStream( + flutterCommand, ['pub', 'get'], + workingDir: example); + if (exitCode != 0) { + failingPackages.add('$packageName (macos)'); + } else { + exitCode = await processRunner.runAndStream( + flutterCommand, + [ + 'build', + kMacos, + if (enableExperiment.isNotEmpty) + '--enable-experiment=$enableExperiment', + ], + workingDir: example); + if (exitCode != 0) { + failingPackages.add('$packageName (macos)'); + } + } + } else { + print('macOS is not supported by this plugin'); + } + } + + if (argResults[kWindows]) { + print('\nBUILDING Windows for $packageName'); + if (isWindowsPlugin(plugin, fileSystem)) { + int buildExitCode = await processRunner.runAndStream( + flutterCommand, + [ + 'build', + kWindows, + if (enableExperiment.isNotEmpty) + '--enable-experiment=$enableExperiment', + ], + workingDir: example); + if (buildExitCode != 0) { + failingPackages.add('$packageName (windows)'); + } + } else { + print('Windows is not supported by this plugin'); + } + } + + if (argResults[kIpa]) { + print('\nBUILDING IPA for $packageName'); + if (isIosPlugin(plugin, fileSystem)) { + final int exitCode = await processRunner.runAndStream( + flutterCommand, + [ + 'build', + 'ios', + '--no-codesign', + if (enableExperiment.isNotEmpty) + '--enable-experiment=$enableExperiment', + ], + workingDir: example); + if (exitCode != 0) { + failingPackages.add('$packageName (ipa)'); + } + } else { + print('iOS is not supported by this plugin'); + } + } + + if (argResults[kApk]) { + print('\nBUILDING APK for $packageName'); + if (isAndroidPlugin(plugin, fileSystem)) { + final int exitCode = await processRunner.runAndStream( + flutterCommand, + [ + 'build', + 'apk', + if (enableExperiment.isNotEmpty) + '--enable-experiment=$enableExperiment', + ], + workingDir: example); + if (exitCode != 0) { + failingPackages.add('$packageName (apk)'); + } + } else { + print('Android is not supported by this plugin'); + } + } + } + } + print('\n\n'); + + if (failingPackages.isNotEmpty) { + print('The following build are failing (see above for details):'); + for (String package in failingPackages) { + print(' * $package'); + } + throw ToolExit(1); + } + + print('All builds successful!'); + } +} diff --git a/script/tool/lib/src/common.dart b/script/tool/lib/src/common.dart new file mode 100644 index 000000000000..78b91ee8a75b --- /dev/null +++ b/script/tool/lib/src/common.dart @@ -0,0 +1,466 @@ +// 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. + +import 'dart:async'; +import 'dart:io' as io; +import 'dart:math'; + +import 'package:args/command_runner.dart'; +import 'package:file/file.dart'; +import 'package:path/path.dart' as p; +import 'package:yaml/yaml.dart'; + +typedef void Print(Object object); + +/// Key for windows platform. +const String kWindows = 'windows'; + +/// Key for macos platform. +const String kMacos = 'macos'; + +/// Key for linux platform. +const String kLinux = 'linux'; + +/// Key for IPA (iOS) platform. +const String kIos = 'ios'; + +/// Key for APK (Android) platform. +const String kAndroid = 'android'; + +/// Key for Web platform. +const String kWeb = 'web'; + +/// Key for IPA. +const String kIpa = 'ipa'; + +/// Key for APK. +const String kApk = 'apk'; + +/// Key for enable experiment. +const String kEnableExperiment = 'enable-experiment'; + +/// Returns whether the given directory contains a Flutter package. +bool isFlutterPackage(FileSystemEntity entity, FileSystem fileSystem) { + if (entity == null || entity is! Directory) { + return false; + } + + try { + final File pubspecFile = + fileSystem.file(p.join(entity.path, 'pubspec.yaml')); + final YamlMap pubspecYaml = loadYaml(pubspecFile.readAsStringSync()); + final YamlMap dependencies = pubspecYaml['dependencies']; + if (dependencies == null) { + return false; + } + return dependencies.containsKey('flutter'); + } on FileSystemException { + return false; + } on YamlException { + return false; + } +} + +/// Returns whether the given directory contains a Flutter [platform] plugin. +/// +/// It checks this by looking for the following pattern in the pubspec: +/// +/// flutter: +/// plugin: +/// platforms: +/// [platform]: +bool pluginSupportsPlatform( + String platform, FileSystemEntity entity, FileSystem fileSystem) { + assert(platform == kIos || + platform == kAndroid || + platform == kWeb || + platform == kMacos || + platform == kWindows || + platform == kLinux); + if (entity == null || entity is! Directory) { + return false; + } + + try { + final File pubspecFile = + fileSystem.file(p.join(entity.path, 'pubspec.yaml')); + final YamlMap pubspecYaml = loadYaml(pubspecFile.readAsStringSync()); + final YamlMap flutterSection = pubspecYaml['flutter']; + if (flutterSection == null) { + return false; + } + final YamlMap pluginSection = flutterSection['plugin']; + if (pluginSection == null) { + return false; + } + final YamlMap platforms = pluginSection['platforms']; + if (platforms == null) { + // Legacy plugin specs are assumed to support iOS and Android. + if (!pluginSection.containsKey('platforms')) { + return platform == kIos || platform == kAndroid; + } + return false; + } + return platforms.containsKey(platform); + } on FileSystemException { + return false; + } on YamlException { + return false; + } +} + +/// Returns whether the given directory contains a Flutter Android plugin. +bool isAndroidPlugin(FileSystemEntity entity, FileSystem fileSystem) { + return pluginSupportsPlatform(kAndroid, entity, fileSystem); +} + +/// Returns whether the given directory contains a Flutter iOS plugin. +bool isIosPlugin(FileSystemEntity entity, FileSystem fileSystem) { + return pluginSupportsPlatform(kIos, entity, fileSystem); +} + +/// Returns whether the given directory contains a Flutter web plugin. +bool isWebPlugin(FileSystemEntity entity, FileSystem fileSystem) { + return pluginSupportsPlatform(kWeb, entity, fileSystem); +} + +/// Returns whether the given directory contains a Flutter Windows plugin. +bool isWindowsPlugin(FileSystemEntity entity, FileSystem fileSystem) { + return pluginSupportsPlatform(kWindows, entity, fileSystem); +} + +/// Returns whether the given directory contains a Flutter macOS plugin. +bool isMacOsPlugin(FileSystemEntity entity, FileSystem fileSystem) { + return pluginSupportsPlatform(kMacos, entity, fileSystem); +} + +/// Returns whether the given directory contains a Flutter linux plugin. +bool isLinuxPlugin(FileSystemEntity entity, FileSystem fileSystem) { + return pluginSupportsPlatform(kLinux, entity, fileSystem); +} + +/// Error thrown when a command needs to exit with a non-zero exit code. +class ToolExit extends Error { + ToolExit(this.exitCode); + + final int exitCode; +} + +abstract class PluginCommand extends Command { + PluginCommand( + this.packagesDir, + this.fileSystem, { + this.processRunner = const ProcessRunner(), + }) { + argParser.addMultiOption( + _pluginsArg, + splitCommas: true, + help: + 'Specifies which plugins the command should run on (before sharding).', + valueHelp: 'plugin1,plugin2,...', + ); + argParser.addOption( + _shardIndexArg, + help: 'Specifies the zero-based index of the shard to ' + 'which the command applies.', + valueHelp: 'i', + defaultsTo: '0', + ); + argParser.addOption( + _shardCountArg, + help: 'Specifies the number of shards into which plugins are divided.', + valueHelp: 'n', + defaultsTo: '1', + ); + argParser.addMultiOption( + _excludeArg, + abbr: 'e', + help: 'Exclude packages from this command.', + defaultsTo: [], + ); + } + + static const String _pluginsArg = 'plugins'; + static const String _shardIndexArg = 'shardIndex'; + static const String _shardCountArg = 'shardCount'; + static const String _excludeArg = 'exclude'; + + /// The directory containing the plugin packages. + final Directory packagesDir; + + /// The file system. + /// + /// This can be overridden for testing. + final FileSystem fileSystem; + + /// The process runner. + /// + /// This can be overridden for testing. + final ProcessRunner processRunner; + + int _shardIndex; + int _shardCount; + + int get shardIndex { + if (_shardIndex == null) { + checkSharding(); + } + return _shardIndex; + } + + int get shardCount { + if (_shardCount == null) { + checkSharding(); + } + return _shardCount; + } + + void checkSharding() { + final int shardIndex = int.tryParse(argResults[_shardIndexArg]); + final int shardCount = int.tryParse(argResults[_shardCountArg]); + if (shardIndex == null) { + usageException('$_shardIndexArg must be an integer'); + } + if (shardCount == null) { + usageException('$_shardCountArg must be an integer'); + } + if (shardCount < 1) { + usageException('$_shardCountArg must be positive'); + } + if (shardIndex < 0 || shardCount <= shardIndex) { + usageException( + '$_shardIndexArg must be in the half-open range [0..$shardCount['); + } + _shardIndex = shardIndex; + _shardCount = shardCount; + } + + /// Returns the root Dart package folders of the plugins involved in this + /// command execution. + Stream getPlugins() async* { + // To avoid assuming consistency of `Directory.list` across command + // invocations, we collect and sort the plugin folders before sharding. + // This is considered an implementation detail which is why the API still + // uses streams. + final List allPlugins = await _getAllPlugins().toList(); + allPlugins.sort((Directory d1, Directory d2) => d1.path.compareTo(d2.path)); + // Sharding 10 elements into 3 shards should yield shard sizes 4, 4, 2. + // Sharding 9 elements into 3 shards should yield shard sizes 3, 3, 3. + // Sharding 2 elements into 3 shards should yield shard sizes 1, 1, 0. + final int shardSize = allPlugins.length ~/ shardCount + + (allPlugins.length % shardCount == 0 ? 0 : 1); + final int start = min(shardIndex * shardSize, allPlugins.length); + final int end = min(start + shardSize, allPlugins.length); + + for (Directory plugin in allPlugins.sublist(start, end)) { + yield plugin; + } + } + + /// Returns the root Dart package folders of the plugins involved in this + /// command execution, assuming there is only one shard. + /// + /// Plugin packages can exist in one of two places relative to the packages + /// directory. + /// + /// 1. As a Dart package in a directory which is a direct child of the + /// packages directory. This is a plugin where all of the implementations + /// exist in a single Dart package. + /// 2. Several plugin packages may live in a directory which is a direct + /// child of the packages directory. This directory groups several Dart + /// packages which implement a single plugin. This directory contains a + /// "client library" package, which declares the API for the plugin, as + /// well as one or more platform-specific implementations. + Stream _getAllPlugins() async* { + final Set plugins = Set.from(argResults[_pluginsArg]); + final Set excludedPlugins = + Set.from(argResults[_excludeArg]); + + await for (FileSystemEntity entity + in packagesDir.list(followLinks: false)) { + // A top-level Dart package is a plugin package. + if (_isDartPackage(entity)) { + if (!excludedPlugins.contains(entity.basename) && + (plugins.isEmpty || plugins.contains(p.basename(entity.path)))) { + yield entity; + } + } else if (entity is Directory) { + // Look for Dart packages under this top-level directory. + await for (FileSystemEntity subdir in entity.list(followLinks: false)) { + if (_isDartPackage(subdir)) { + // If --plugin=my_plugin is passed, then match all federated + // plugins under 'my_plugin'. Also match if the exact plugin is + // passed. + final String relativePath = + p.relative(subdir.path, from: packagesDir.path); + final String basenamePath = p.basename(entity.path); + if (!excludedPlugins.contains(basenamePath) && + !excludedPlugins.contains(relativePath) && + (plugins.isEmpty || + plugins.contains(relativePath) || + plugins.contains(basenamePath))) { + yield subdir; + } + } + } + } + } + } + + /// Returns the example Dart package folders of the plugins involved in this + /// command execution. + Stream getExamples() => + getPlugins().expand(getExamplesForPlugin); + + /// Returns all Dart package folders (typically, plugin + example) of the + /// plugins involved in this command execution. + Stream getPackages() async* { + await for (Directory plugin in getPlugins()) { + yield plugin; + yield* plugin + .list(recursive: true, followLinks: false) + .where(_isDartPackage) + .cast(); + } + } + + /// Returns the files contained, recursively, within the plugins + /// involved in this command execution. + Stream getFiles() { + return getPlugins().asyncExpand((Directory folder) => folder + .list(recursive: true, followLinks: false) + .where((FileSystemEntity entity) => entity is File) + .cast()); + } + + /// Returns whether the specified entity is a directory containing a + /// `pubspec.yaml` file. + bool _isDartPackage(FileSystemEntity entity) { + return entity is Directory && + fileSystem.file(p.join(entity.path, 'pubspec.yaml')).existsSync(); + } + + /// Returns the example Dart packages contained in the specified plugin, or + /// an empty List, if the plugin has no examples. + Iterable getExamplesForPlugin(Directory plugin) { + final Directory exampleFolder = + fileSystem.directory(p.join(plugin.path, 'example')); + if (!exampleFolder.existsSync()) { + return []; + } + if (isFlutterPackage(exampleFolder, fileSystem)) { + return [exampleFolder]; + } + // Only look at the subdirectories of the example directory if the example + // directory itself is not a Dart package, and only look one level below the + // example directory for other dart packages. + return exampleFolder + .listSync() + .where( + (FileSystemEntity entity) => isFlutterPackage(entity, fileSystem)) + .cast(); + } +} + +/// A class used to run processes. +/// +/// We use this instead of directly running the process so it can be overridden +/// in tests. +class ProcessRunner { + const ProcessRunner(); + + /// Run the [executable] with [args] and stream output to stderr and stdout. + /// + /// The current working directory of [executable] can be overridden by + /// passing [workingDir]. + /// + /// If [exitOnError] is set to `true`, then this will throw an error if + /// the [executable] terminates with a non-zero exit code. + /// + /// Returns the exit code of the [executable]. + Future runAndStream( + String executable, + List args, { + Directory workingDir, + bool exitOnError = false, + }) async { + print( + 'Running command: "$executable ${args.join(' ')}" in ${workingDir?.path ?? io.Directory.current.path}'); + final io.Process process = await io.Process.start(executable, args, + workingDirectory: workingDir?.path); + await io.stdout.addStream(process.stdout); + await io.stderr.addStream(process.stderr); + if (exitOnError && await process.exitCode != 0) { + final String error = + _getErrorString(executable, args, workingDir: workingDir); + print('$error See above for details.'); + throw ToolExit(await process.exitCode); + } + return process.exitCode; + } + + /// Run the [executable] with [args]. + /// + /// The current working directory of [executable] can be overridden by + /// passing [workingDir]. + /// + /// If [exitOnError] is set to `true`, then this will throw an error if + /// the [executable] terminates with a non-zero exit code. + /// + /// Returns the [io.ProcessResult] of the [executable]. + Future run(String executable, List args, + {Directory workingDir, + bool exitOnError = false, + stdoutEncoding = io.systemEncoding, + stderrEncoding = io.systemEncoding}) async { + return io.Process.run(executable, args, + workingDirectory: workingDir?.path, + stdoutEncoding: stdoutEncoding, + stderrEncoding: stderrEncoding); + } + + /// Starts the [executable] with [args]. + /// + /// The current working directory of [executable] can be overridden by + /// passing [workingDir]. + /// + /// Returns the started [io.Process]. + Future start(String executable, List args, + {Directory workingDirectory}) async { + final io.Process process = await io.Process.start(executable, args, + workingDirectory: workingDirectory?.path); + return process; + } + + /// Run the [executable] with [args], throwing an error on non-zero exit code. + /// + /// Unlike [runAndStream], this does not stream the process output to stdout. + /// It also unconditionally throws an error on a non-zero exit code. + /// + /// The current working directory of [executable] can be overridden by + /// passing [workingDir]. + /// + /// Returns the [io.ProcessResult] of running the [executable]. + Future runAndExitOnError( + String executable, + List args, { + Directory workingDir, + }) async { + final io.ProcessResult result = await io.Process.run(executable, args, + workingDirectory: workingDir?.path); + if (result.exitCode != 0) { + final String error = + _getErrorString(executable, args, workingDir: workingDir); + print('$error Stderr:\n${result.stdout}'); + throw ToolExit(result.exitCode); + } + return result; + } + + String _getErrorString(String executable, List args, + {Directory workingDir}) { + final String workdir = workingDir == null ? '' : ' in ${workingDir.path}'; + return 'ERROR: Unable to execute "$executable ${args.join(' ')}"$workdir.'; + } +} diff --git a/script/tool/lib/src/create_all_plugins_app_command.dart b/script/tool/lib/src/create_all_plugins_app_command.dart new file mode 100644 index 000000000000..0f1431c5aee0 --- /dev/null +++ b/script/tool/lib/src/create_all_plugins_app_command.dart @@ -0,0 +1,200 @@ +// Copyright 2019 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. + +import 'dart:async'; +import 'dart:io' as io; + +import 'package:file/file.dart'; +import 'package:path/path.dart' as p; +import 'package:pub_semver/pub_semver.dart'; +import 'package:pubspec_parse/pubspec_parse.dart'; + +import 'common.dart'; + +// TODO(cyanglaz): Add tests for this command. +// https://github.com/flutter/flutter/issues/61049 +class CreateAllPluginsAppCommand extends PluginCommand { + CreateAllPluginsAppCommand(Directory packagesDir, FileSystem fileSystem) + : super(packagesDir, fileSystem); + + @override + String get description => + 'Generate Flutter app that includes all plugins in packages.'; + + @override + String get name => 'all-plugins-app'; + + @override + Future run() async { + final int exitCode = await _createPlugin(); + if (exitCode != 0) { + throw ToolExit(exitCode); + } + + await Future.wait(>[ + _genPubspecWithAllPlugins(), + _updateAppGradle(), + _updateManifest(), + ]); + } + + Future _createPlugin() async { + final io.ProcessResult result = io.Process.runSync( + 'flutter', + [ + 'create', + '--template=app', + '--project-name=all_plugins', + '--android-language=java', + './all_plugins', + ], + ); + + print(result.stdout); + print(result.stderr); + return result.exitCode; + } + + Future _updateAppGradle() async { + final File gradleFile = fileSystem.file(p.join( + 'all_plugins', + 'android', + 'app', + 'build.gradle', + )); + if (!gradleFile.existsSync()) { + throw ToolExit(64); + } + + final StringBuffer newGradle = StringBuffer(); + for (String line in gradleFile.readAsLinesSync()) { + newGradle.writeln(line); + if (line.contains('defaultConfig {')) { + newGradle.writeln(' multiDexEnabled true'); + } else if (line.contains('dependencies {')) { + newGradle.writeln( + ' implementation \'com.google.guava:guava:27.0.1-android\'\n', + ); + // Tests for https://github.com/flutter/flutter/issues/43383 + newGradle.writeln( + " implementation 'androidx.lifecycle:lifecycle-runtime:2.2.0-rc01'\n", + ); + } + } + gradleFile.writeAsStringSync(newGradle.toString()); + } + + Future _updateManifest() async { + final File manifestFile = fileSystem.file(p.join( + 'all_plugins', + 'android', + 'app', + 'src', + 'main', + 'AndroidManifest.xml', + )); + if (!manifestFile.existsSync()) { + throw ToolExit(64); + } + + final StringBuffer newManifest = StringBuffer(); + for (String line in manifestFile.readAsLinesSync()) { + if (line.contains('package="com.example.all_plugins"')) { + newManifest + ..writeln('package="com.example.all_plugins"') + ..writeln('xmlns:tools="http://schemas.android.com/tools">') + ..writeln() + ..writeln( + '', + ); + } else { + newManifest.writeln(line); + } + } + manifestFile.writeAsStringSync(newManifest.toString()); + } + + Future _genPubspecWithAllPlugins() async { + final Map pluginDeps = + await _getValidPathDependencies(); + final Pubspec pubspec = Pubspec( + 'all_plugins', + description: 'Flutter app containing all 1st party plugins.', + version: Version.parse('1.0.0+1'), + environment: { + 'sdk': VersionConstraint.compatibleWith( + Version.parse('2.0.0'), + ), + }, + dependencies: { + 'flutter': SdkDependency('flutter'), + }..addAll(pluginDeps), + devDependencies: { + 'flutter_test': SdkDependency('flutter'), + }, + dependencyOverrides: pluginDeps, + ); + final File pubspecFile = + fileSystem.file(p.join('all_plugins', 'pubspec.yaml')); + pubspecFile.writeAsStringSync(_pubspecToString(pubspec)); + } + + Future> _getValidPathDependencies() async { + final Map pathDependencies = + {}; + + await for (Directory package in getPlugins()) { + final String pluginName = package.path.split('/').last; + final File pubspecFile = + fileSystem.file(p.join(package.path, 'pubspec.yaml')); + final Pubspec pubspec = Pubspec.parse(pubspecFile.readAsStringSync()); + + if (pubspec.publishTo != 'none') { + pathDependencies[pluginName] = PathDependency(package.path); + } + } + return pathDependencies; + } + + String _pubspecToString(Pubspec pubspec) { + return ''' +### Generated file. Do not edit. Run `pub global run flutter_plugin_tools gen-pubspec` to update. +name: ${pubspec.name} +description: ${pubspec.description} + +version: ${pubspec.version} + +environment:${_pubspecMapString(pubspec.environment)} + +dependencies:${_pubspecMapString(pubspec.dependencies)} + +dependency_overrides:${_pubspecMapString(pubspec.dependencyOverrides)} + +dev_dependencies:${_pubspecMapString(pubspec.devDependencies)} +###'''; + } + + String _pubspecMapString(Map values) { + final StringBuffer buffer = StringBuffer(); + + for (MapEntry entry in values.entries) { + buffer.writeln(); + if (entry.value is VersionConstraint) { + buffer.write(' ${entry.key}: ${entry.value}'); + } else if (entry.value is SdkDependency) { + final SdkDependency dep = entry.value; + buffer.write(' ${entry.key}: \n sdk: ${dep.sdk}'); + } else if (entry.value is PathDependency) { + final PathDependency dep = entry.value; + buffer.write(' ${entry.key}: \n path: ${dep.path}'); + } else { + throw UnimplementedError( + 'Not available for type: ${entry.value.runtimeType}', + ); + } + } + + return buffer.toString(); + } +} diff --git a/script/tool/lib/src/drive_examples_command.dart b/script/tool/lib/src/drive_examples_command.dart new file mode 100644 index 000000000000..59c642265bae --- /dev/null +++ b/script/tool/lib/src/drive_examples_command.dart @@ -0,0 +1,210 @@ +// Copyright 2019 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. + +import 'dart:async'; +import 'package:file/file.dart'; +import 'package:path/path.dart' as p; +import 'package:platform/platform.dart'; +import 'common.dart'; + +class DriveExamplesCommand extends PluginCommand { + DriveExamplesCommand( + Directory packagesDir, + FileSystem fileSystem, { + ProcessRunner processRunner = const ProcessRunner(), + }) : super(packagesDir, fileSystem, processRunner: processRunner) { + argParser.addFlag(kLinux, + help: 'Runs the Linux implementation of the examples'); + argParser.addFlag(kMacos, + help: 'Runs the macOS implementation of the examples'); + argParser.addFlag(kWindows, + help: 'Runs the Windows implementation of the examples'); + argParser.addFlag(kIos, + help: 'Runs the iOS implementation of the examples'); + argParser.addFlag(kAndroid, + help: 'Runs the Android implementation of the examples'); + argParser.addOption( + kEnableExperiment, + defaultsTo: '', + help: + 'Runs the driver tests in Dart VM with the given experiments enabled.', + ); + } + + @override + final String name = 'drive-examples'; + + @override + final String description = 'Runs driver tests for plugin example apps.\n\n' + 'For each *_test.dart in test_driver/ it drives an application with a ' + 'corresponding name in the test/ or test_driver/ directories.\n\n' + 'For example, test_driver/app_test.dart would match test/app.dart.\n\n' + 'This command requires "flutter" to be in your path.\n\n' + 'If a file with a corresponding name cannot be found, this driver file' + 'will be used to drive the tests that match ' + 'integration_test/*_test.dart.'; + + @override + Future run() async { + checkSharding(); + final List failingTests = []; + final bool isLinux = argResults[kLinux]; + final bool isMacos = argResults[kMacos]; + final bool isWindows = argResults[kWindows]; + await for (Directory plugin in getPlugins()) { + final String flutterCommand = + LocalPlatform().isWindows ? 'flutter.bat' : 'flutter'; + for (Directory example in getExamplesForPlugin(plugin)) { + final String packageName = + p.relative(example.path, from: packagesDir.path); + if (!(await pluginSupportedOnCurrentPlatform(plugin, fileSystem))) { + continue; + } + final Directory driverTests = + fileSystem.directory(p.join(example.path, 'test_driver')); + if (!driverTests.existsSync()) { + // No driver tests available for this example + continue; + } + // Look for driver tests ending in _test.dart in test_driver/ + await for (FileSystemEntity test in driverTests.list()) { + final String driverTestName = + p.relative(test.path, from: driverTests.path); + if (!driverTestName.endsWith('_test.dart')) { + continue; + } + // Try to find a matching app to drive without the _test.dart + final String deviceTestName = driverTestName.replaceAll( + RegExp(r'_test.dart$'), + '.dart', + ); + String deviceTestPath = p.join('test', deviceTestName); + if (!fileSystem + .file(p.join(example.path, deviceTestPath)) + .existsSync()) { + // If the app isn't in test/ folder, look in test_driver/ instead. + deviceTestPath = p.join('test_driver', deviceTestName); + } + + final List targetPaths = []; + if (fileSystem + .file(p.join(example.path, deviceTestPath)) + .existsSync()) { + targetPaths.add(deviceTestPath); + } else { + final Directory integrationTests = + fileSystem.directory(p.join(example.path, 'integration_test')); + + if (await integrationTests.exists()) { + await for (FileSystemEntity integration_test + in integrationTests.list()) { + if (!integration_test.basename.endsWith('_test.dart')) { + continue; + } + targetPaths + .add(p.relative(integration_test.path, from: example.path)); + } + } + + if (targetPaths.isEmpty) { + print(''' +Unable to infer a target application for $driverTestName to drive. +Tried searching for the following: +1. test/$deviceTestName +2. test_driver/$deviceTestName +3. test_driver/*_test.dart +'''); + failingTests.add(p.relative(test.path, from: example.path)); + continue; + } + } + + final List driveArgs = ['drive']; + + final String enableExperiment = argResults[kEnableExperiment]; + if (enableExperiment.isNotEmpty) { + driveArgs.add('--enable-experiment=$enableExperiment'); + } + + if (isLinux && isLinuxPlugin(plugin, fileSystem)) { + driveArgs.addAll([ + '-d', + 'linux', + ]); + } + if (isMacos && isMacOsPlugin(plugin, fileSystem)) { + driveArgs.addAll([ + '-d', + 'macos', + ]); + } + if (isWindows && isWindowsPlugin(plugin, fileSystem)) { + driveArgs.addAll([ + '-d', + 'windows', + ]); + } + + for (final targetPath in targetPaths) { + final int exitCode = await processRunner.runAndStream( + flutterCommand, + [ + ...driveArgs, + '--driver', + p.join('test_driver', driverTestName), + '--target', + targetPath, + ], + workingDir: example, + exitOnError: true); + if (exitCode != 0) { + failingTests.add(p.join(packageName, deviceTestPath)); + } + } + } + } + } + print('\n\n'); + + if (failingTests.isNotEmpty) { + print('The following driver tests are failing (see above for details):'); + for (String test in failingTests) { + print(' * $test'); + } + throw ToolExit(1); + } + + print('All driver tests successful!'); + } + + Future pluginSupportedOnCurrentPlatform( + FileSystemEntity plugin, FileSystem fileSystem) async { + final bool isLinux = argResults[kLinux]; + final bool isMacos = argResults[kMacos]; + final bool isWindows = argResults[kWindows]; + final bool isIOS = argResults[kIos]; + final bool isAndroid = argResults[kAndroid]; + if (isLinux) { + return isLinuxPlugin(plugin, fileSystem); + } + if (isMacos) { + return isMacOsPlugin(plugin, fileSystem); + } + if (isWindows) { + return isWindowsPlugin(plugin, fileSystem); + } + if (isIOS) { + return isIosPlugin(plugin, fileSystem); + } + if (isAndroid) { + return (isAndroidPlugin(plugin, fileSystem)); + } + // When we are here, no flags are specified. Only return true if the plugin supports mobile for legacy command support. + // TODO(cyanglaz): Make mobile platforms flags also required like other platforms (breaking change). + // https://github.com/flutter/flutter/issues/58285 + final bool isMobilePlugin = + isIosPlugin(plugin, fileSystem) || isAndroidPlugin(plugin, fileSystem); + return isMobilePlugin; + } +} diff --git a/script/tool/lib/src/firebase_test_lab_command.dart b/script/tool/lib/src/firebase_test_lab_command.dart new file mode 100644 index 000000000000..0b4b2a471dbc --- /dev/null +++ b/script/tool/lib/src/firebase_test_lab_command.dart @@ -0,0 +1,264 @@ +// Copyright 2018 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. + +import 'dart:async'; +import 'dart:io' as io; + +import 'package:file/file.dart'; +import 'package:path/path.dart' as p; +import 'package:uuid/uuid.dart'; + +import 'common.dart'; + +class FirebaseTestLabCommand extends PluginCommand { + FirebaseTestLabCommand( + Directory packagesDir, + FileSystem fileSystem, { + ProcessRunner processRunner = const ProcessRunner(), + Print print = print, + }) : _print = print, + super(packagesDir, fileSystem, processRunner: processRunner) { + argParser.addOption( + 'project', + defaultsTo: 'flutter-infra', + help: 'The Firebase project name.', + ); + argParser.addOption('service-key', + defaultsTo: + p.join(io.Platform.environment['HOME'], 'gcloud-service-key.json')); + argParser.addOption('test-run-id', + defaultsTo: Uuid().v4(), + help: + 'Optional string to append to the results path, to avoid conflicts. ' + 'Randomly chosen on each invocation if none is provided. ' + 'The default shown here is just an example.'); + argParser.addMultiOption('device', + splitCommas: false, + defaultsTo: [ + 'model=walleye,version=26', + 'model=flame,version=29' + ], + help: + 'Device model(s) to test. See https://cloud.google.com/sdk/gcloud/reference/firebase/test/android/run for more info'); + argParser.addOption('results-bucket', + defaultsTo: 'gs://flutter_firebase_testlab'); + argParser.addOption( + kEnableExperiment, + defaultsTo: '', + help: 'Enables the given Dart SDK experiments.', + ); + } + + @override + final String name = 'firebase-test-lab'; + + @override + final String description = 'Runs the instrumentation tests of the example ' + 'apps on Firebase Test Lab.\n\n' + 'Runs tests in test_instrumentation folder using the ' + 'instrumentation_test package.'; + + static const String _gradleWrapper = 'gradlew'; + + final Print _print; + + Completer _firebaseProjectConfigured; + + Future _configureFirebaseProject() async { + if (_firebaseProjectConfigured != null) { + return _firebaseProjectConfigured.future; + } else { + _firebaseProjectConfigured = Completer(); + } + await processRunner.runAndExitOnError('gcloud', [ + 'auth', + 'activate-service-account', + '--key-file=${argResults['service-key']}', + ]); + int exitCode = await processRunner.runAndStream('gcloud', [ + 'config', + 'set', + 'project', + argResults['project'], + ]); + if (exitCode == 0) { + _print('\nFirebase project configured.'); + return; + } else { + _print( + '\nWarning: gcloud config set returned a non-zero exit code. Continuing anyway.'); + } + _firebaseProjectConfigured.complete(null); + } + + @override + Future run() async { + checkSharding(); + final Stream packagesWithTests = getPackages().where( + (Directory d) => + isFlutterPackage(d, fileSystem) && + fileSystem + .directory(p.join( + d.path, 'example', 'android', 'app', 'src', 'androidTest')) + .existsSync()); + + final List failingPackages = []; + final List missingFlutterBuild = []; + int resultsCounter = + 0; // We use a unique GCS bucket for each Firebase Test Lab run + await for (Directory package in packagesWithTests) { + // See https://github.com/flutter/flutter/issues/38983 + + final Directory exampleDirectory = + fileSystem.directory(p.join(package.path, 'example')); + final String packageName = + p.relative(package.path, from: packagesDir.path); + _print('\nRUNNING FIREBASE TEST LAB TESTS for $packageName'); + + final Directory androidDirectory = + fileSystem.directory(p.join(exampleDirectory.path, 'android')); + + final String enableExperiment = argResults[kEnableExperiment]; + final String encodedEnableExperiment = + Uri.encodeComponent('--enable-experiment=$enableExperiment'); + + // Ensures that gradle wrapper exists + if (!fileSystem + .file(p.join(androidDirectory.path, _gradleWrapper)) + .existsSync()) { + final int exitCode = await processRunner.runAndStream( + 'flutter', + [ + 'build', + 'apk', + if (enableExperiment.isNotEmpty) + '--enable-experiment=$enableExperiment', + ], + workingDir: androidDirectory); + + if (exitCode != 0) { + failingPackages.add(packageName); + continue; + } + continue; + } + + await _configureFirebaseProject(); + + int exitCode = await processRunner.runAndStream( + p.join(androidDirectory.path, _gradleWrapper), + [ + 'app:assembleAndroidTest', + '-Pverbose=true', + if (enableExperiment.isNotEmpty) + '-Pextra-front-end-options=$encodedEnableExperiment', + if (enableExperiment.isNotEmpty) + '-Pextra-gen-snapshot-options=$encodedEnableExperiment', + ], + workingDir: androidDirectory); + + if (exitCode != 0) { + failingPackages.add(packageName); + continue; + } + + // Look for tests recursively in folders that start with 'test' and that + // live in the root or example folders. + bool isTestDir(FileSystemEntity dir) { + return p.basename(dir.path).startsWith('test') || + p.basename(dir.path) == 'integration_test'; + } + + final List testDirs = + package.listSync().where(isTestDir).toList(); + final Directory example = + fileSystem.directory(p.join(package.path, 'example')); + testDirs.addAll(example.listSync().where(isTestDir).toList()); + for (Directory testDir in testDirs) { + bool isE2ETest(FileSystemEntity file) { + return file.path.endsWith('_e2e.dart') || + (file.parent.basename == 'integration_test' && + file.path.endsWith('_test.dart')); + } + + final List testFiles = testDir + .listSync(recursive: true, followLinks: true) + .where(isE2ETest) + .toList(); + for (FileSystemEntity test in testFiles) { + exitCode = await processRunner.runAndStream( + p.join(androidDirectory.path, _gradleWrapper), + [ + 'app:assembleDebug', + '-Pverbose=true', + '-Ptarget=${test.path}', + if (enableExperiment.isNotEmpty) + '-Pextra-front-end-options=$encodedEnableExperiment', + if (enableExperiment.isNotEmpty) + '-Pextra-gen-snapshot-options=$encodedEnableExperiment', + ], + workingDir: androidDirectory); + + if (exitCode != 0) { + failingPackages.add(packageName); + continue; + } + final String buildId = io.Platform.environment['CIRRUS_BUILD_ID']; + final String testRunId = argResults['test-run-id']; + final String resultsDir = + 'plugins_android_test/$packageName/$buildId/$testRunId/${resultsCounter++}/'; + final List args = [ + 'firebase', + 'test', + 'android', + 'run', + '--type', + 'instrumentation', + '--app', + 'build/app/outputs/apk/debug/app-debug.apk', + '--test', + 'build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk', + '--timeout', + '5m', + '--results-bucket=${argResults['results-bucket']}', + '--results-dir=${resultsDir}', + ]; + for (String device in argResults['device']) { + args.addAll(['--device', device]); + } + exitCode = await processRunner.runAndStream('gcloud', args, + workingDir: exampleDirectory); + + if (exitCode != 0) { + failingPackages.add(packageName); + continue; + } + } + } + } + + _print('\n\n'); + if (failingPackages.isNotEmpty) { + _print( + 'The instrumentation tests for the following packages are failing (see above for' + 'details):'); + for (String package in failingPackages) { + _print(' * $package'); + } + } + if (missingFlutterBuild.isNotEmpty) { + _print('Run "pub global run flutter_plugin_tools build-examples --apk" on' + 'the following packages before executing tests again:'); + for (String package in missingFlutterBuild) { + _print(' * $package'); + } + } + + if (failingPackages.isNotEmpty || missingFlutterBuild.isNotEmpty) { + throw ToolExit(1); + } + + _print('All Firebase Test Lab tests successful!'); + } +} diff --git a/script/tool/lib/src/format_command.dart b/script/tool/lib/src/format_command.dart new file mode 100644 index 000000000000..ec326b96c1f9 --- /dev/null +++ b/script/tool/lib/src/format_command.dart @@ -0,0 +1,147 @@ +// 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. + +import 'dart:async'; +import 'dart:convert'; +import 'dart:io' as io; + +import 'package:file/file.dart'; +import 'package:http/http.dart' as http; +import 'package:path/path.dart' as p; +import 'package:quiver/iterables.dart'; + +import 'common.dart'; + +const String _googleFormatterUrl = + 'https://github.com/google/google-java-format/releases/download/google-java-format-1.3/google-java-format-1.3-all-deps.jar'; + +class FormatCommand extends PluginCommand { + FormatCommand( + Directory packagesDir, + FileSystem fileSystem, { + ProcessRunner processRunner = const ProcessRunner(), + }) : super(packagesDir, fileSystem, processRunner: processRunner) { + argParser.addFlag('travis', hide: true); + argParser.addOption('clang-format', + defaultsTo: 'clang-format', + help: 'Path to executable of clang-format v5.'); + } + + @override + final String name = 'format'; + + @override + final String description = + 'Formats the code of all packages (Java, Objective-C, C++, and Dart).\n\n' + 'This command requires "git", "flutter" and "clang-format" v5 to be in ' + 'your path.'; + + @override + Future run() async { + checkSharding(); + final String googleFormatterPath = await _getGoogleFormatterPath(); + + await _formatDart(); + await _formatJava(googleFormatterPath); + await _formatCppAndObjectiveC(); + + if (argResults['travis']) { + final bool modified = await _didModifyAnything(); + if (modified) { + throw ToolExit(1); + } + } + } + + Future _didModifyAnything() async { + final io.ProcessResult modifiedFiles = await processRunner + .runAndExitOnError('git', ['ls-files', '--modified'], + workingDir: packagesDir); + + print('\n\n'); + + if (modifiedFiles.stdout.isEmpty) { + print('All files formatted correctly.'); + return false; + } + + print('These files are not formatted correctly (see diff below):'); + LineSplitter.split(modifiedFiles.stdout) + .map((String line) => ' $line') + .forEach(print); + + print('\nTo fix run "pub global activate flutter_plugin_tools && ' + 'pub global run flutter_plugin_tools format" or copy-paste ' + 'this command into your terminal:'); + + print('patch -p1 <['diff'], workingDir: packagesDir); + print(diff.stdout); + print('DONE'); + return true; + } + + Future _formatCppAndObjectiveC() async { + print('Formatting all .cc, .cpp, .mm, .m, and .h files...'); + final Iterable allFiles = [] + ..addAll(await _getFilesWithExtension('.h')) + ..addAll(await _getFilesWithExtension('.m')) + ..addAll(await _getFilesWithExtension('.mm')) + ..addAll(await _getFilesWithExtension('.cc')) + ..addAll(await _getFilesWithExtension('.cpp')); + // Split this into multiple invocations to avoid a + // 'ProcessException: Argument list too long'. + final Iterable> batches = partition(allFiles, 100); + for (List batch in batches) { + await processRunner.runAndStream(argResults['clang-format'], + ['-i', '--style=Google']..addAll(batch), + workingDir: packagesDir, exitOnError: true); + } + } + + Future _formatJava(String googleFormatterPath) async { + print('Formatting all .java files...'); + final Iterable javaFiles = await _getFilesWithExtension('.java'); + await processRunner.runAndStream('java', + ['-jar', googleFormatterPath, '--replace']..addAll(javaFiles), + workingDir: packagesDir, exitOnError: true); + } + + Future _formatDart() async { + // This actually should be fine for non-Flutter Dart projects, no need to + // specifically shell out to dartfmt -w in that case. + print('Formatting all .dart files...'); + final Iterable dartFiles = await _getFilesWithExtension('.dart'); + if (dartFiles.isEmpty) { + print( + 'No .dart files to format. If you set the `--exclude` flag, most likey they were skipped'); + } else { + await processRunner.runAndStream( + 'flutter', ['format']..addAll(dartFiles), + workingDir: packagesDir, exitOnError: true); + } + } + + Future> _getFilesWithExtension(String extension) async => + getFiles() + .where((File file) => p.extension(file.path) == extension) + .map((File file) => file.path) + .toList(); + + Future _getGoogleFormatterPath() async { + final String javaFormatterPath = p.join( + p.dirname(p.fromUri(io.Platform.script)), + 'google-java-format-1.3-all-deps.jar'); + final File javaFormatterFile = fileSystem.file(javaFormatterPath); + + if (!javaFormatterFile.existsSync()) { + print('Downloading Google Java Format...'); + final http.Response response = await http.get(_googleFormatterUrl); + javaFormatterFile.writeAsBytesSync(response.bodyBytes); + } + + return javaFormatterPath; + } +} diff --git a/script/tool/lib/src/java_test_command.dart b/script/tool/lib/src/java_test_command.dart new file mode 100644 index 000000000000..cf605bfc5ce2 --- /dev/null +++ b/script/tool/lib/src/java_test_command.dart @@ -0,0 +1,89 @@ +// Copyright 2018 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. + +import 'dart:async'; + +import 'package:file/file.dart'; +import 'package:path/path.dart' as p; + +import 'common.dart'; + +class JavaTestCommand extends PluginCommand { + JavaTestCommand( + Directory packagesDir, + FileSystem fileSystem, { + ProcessRunner processRunner = const ProcessRunner(), + }) : super(packagesDir, fileSystem, processRunner: processRunner); + + @override + final String name = 'java-test'; + + @override + final String description = 'Runs the Java tests of the example apps.\n\n' + 'Building the apks of the example apps is required before executing this' + 'command.'; + + static const String _gradleWrapper = 'gradlew'; + + @override + Future run() async { + checkSharding(); + final Stream examplesWithTests = getExamples().where( + (Directory d) => + isFlutterPackage(d, fileSystem) && + fileSystem + .directory(p.join(d.path, 'android', 'app', 'src', 'test')) + .existsSync()); + + final List failingPackages = []; + final List missingFlutterBuild = []; + await for (Directory example in examplesWithTests) { + final String packageName = + p.relative(example.path, from: packagesDir.path); + print('\nRUNNING JAVA TESTS for $packageName'); + + final Directory androidDirectory = + fileSystem.directory(p.join(example.path, 'android')); + if (!fileSystem + .file(p.join(androidDirectory.path, _gradleWrapper)) + .existsSync()) { + print('ERROR: Run "flutter build apk" on example app of $packageName' + 'before executing tests.'); + missingFlutterBuild.add(packageName); + continue; + } + + final int exitCode = await processRunner.runAndStream( + p.join(androidDirectory.path, _gradleWrapper), + ['testDebugUnitTest', '--info'], + workingDir: androidDirectory); + if (exitCode != 0) { + failingPackages.add(packageName); + } + } + + print('\n\n'); + if (failingPackages.isNotEmpty) { + print( + 'The Java tests for the following packages are failing (see above for' + 'details):'); + for (String package in failingPackages) { + print(' * $package'); + } + } + if (missingFlutterBuild.isNotEmpty) { + print('Run "pub global run flutter_plugin_tools build-examples --apk" on' + 'the following packages before executing tests again:'); + for (String package in missingFlutterBuild) { + print(' * $package'); + } + } + + if (failingPackages.isNotEmpty || missingFlutterBuild.isNotEmpty) { + throw ToolExit(1); + } + + print('All Java tests successful!'); + } +} diff --git a/script/tool/lib/src/lint_podspecs_command.dart b/script/tool/lib/src/lint_podspecs_command.dart new file mode 100644 index 000000000000..68fd4b61dd66 --- /dev/null +++ b/script/tool/lib/src/lint_podspecs_command.dart @@ -0,0 +1,146 @@ +// 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. + +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:file/file.dart'; +import 'package:path/path.dart' as p; +import 'package:platform/platform.dart'; + +import 'common.dart'; + +typedef void Print(Object object); + +/// Lint the CocoaPod podspecs, run the static analyzer on iOS/macOS plugin +/// platform code, and run unit tests. +/// +/// See https://guides.cocoapods.org/terminal/commands.html#pod_lib_lint. +class LintPodspecsCommand extends PluginCommand { + LintPodspecsCommand( + Directory packagesDir, + FileSystem fileSystem, { + ProcessRunner processRunner = const ProcessRunner(), + this.platform = const LocalPlatform(), + Print print = print, + }) : _print = print, + super(packagesDir, fileSystem, processRunner: processRunner) { + argParser.addMultiOption('skip', + help: + 'Skip all linting for podspecs with this basename (example: federated plugins with placeholder podspecs)', + valueHelp: 'podspec_file_name'); + argParser.addMultiOption('ignore-warnings', + help: + 'Do not pass --allow-warnings flag to "pod lib lint" for podspecs with this basename (example: plugins with known warnings)', + valueHelp: 'podspec_file_name'); + argParser.addMultiOption('no-analyze', + help: + 'Do not pass --analyze flag to "pod lib lint" for podspecs with this basename (example: plugins with known analyzer warnings)', + valueHelp: 'podspec_file_name'); + } + + @override + final String name = 'podspecs'; + + @override + List get aliases => ['podspec']; + + @override + final String description = + 'Runs "pod lib lint" on all iOS and macOS plugin podspecs.\n\n' + 'This command requires "pod" and "flutter" to be in your path. Runs on macOS only.'; + + final Platform platform; + + final Print _print; + + @override + Future run() async { + if (!platform.isMacOS) { + _print('Detected platform is not macOS, skipping podspec lint'); + return; + } + + checkSharding(); + + await processRunner.runAndExitOnError('which', ['pod'], + workingDir: packagesDir); + + _print('Starting podspec lint test'); + + final List failingPlugins = []; + for (File podspec in await _podspecsToLint()) { + if (!await _lintPodspec(podspec)) { + failingPlugins.add(p.basenameWithoutExtension(podspec.path)); + } + } + + _print('\n\n'); + if (failingPlugins.isNotEmpty) { + _print('The following plugins have podspec errors (see above):'); + failingPlugins.forEach((String plugin) { + _print(' * $plugin'); + }); + throw ToolExit(1); + } + } + + Future> _podspecsToLint() async { + final List podspecs = await getFiles().where((File entity) { + final String filePath = entity.path; + return p.extension(filePath) == '.podspec' && + !argResults['skip'].contains(p.basenameWithoutExtension(filePath)); + }).toList(); + + podspecs.sort( + (File a, File b) => p.basename(a.path).compareTo(p.basename(b.path))); + return podspecs; + } + + Future _lintPodspec(File podspec) async { + // Do not run the static analyzer on plugins with known analyzer issues. + final String podspecPath = podspec.path; + final bool runAnalyzer = !argResults['no-analyze'] + .contains(p.basenameWithoutExtension(podspecPath)); + + final String podspecBasename = p.basename(podspecPath); + if (runAnalyzer) { + _print('Linting and analyzing $podspecBasename'); + } else { + _print('Linting $podspecBasename'); + } + + // Lint plugin as framework (use_frameworks!). + final ProcessResult frameworkResult = await _runPodLint(podspecPath, + runAnalyzer: runAnalyzer, libraryLint: true); + _print(frameworkResult.stdout); + _print(frameworkResult.stderr); + + // Lint plugin as library. + final ProcessResult libraryResult = await _runPodLint(podspecPath, + runAnalyzer: runAnalyzer, libraryLint: false); + _print(libraryResult.stdout); + _print(libraryResult.stderr); + + return frameworkResult.exitCode == 0 && libraryResult.exitCode == 0; + } + + Future _runPodLint(String podspecPath, + {bool runAnalyzer, bool libraryLint}) async { + final bool allowWarnings = argResults['ignore-warnings'] + .contains(p.basenameWithoutExtension(podspecPath)); + final List arguments = [ + 'lib', + 'lint', + podspecPath, + if (allowWarnings) '--allow-warnings', + if (runAnalyzer) '--analyze', + if (libraryLint) '--use-libraries' + ]; + + return processRunner.run('pod', arguments, + workingDir: packagesDir, stdoutEncoding: utf8, stderrEncoding: utf8); + } +} diff --git a/script/tool/lib/src/list_command.dart b/script/tool/lib/src/list_command.dart new file mode 100644 index 000000000000..7f94daac7096 --- /dev/null +++ b/script/tool/lib/src/list_command.dart @@ -0,0 +1,60 @@ +// Copyright 2018 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. + +import 'dart:async'; + +import 'package:file/file.dart'; + +import 'common.dart'; + +class ListCommand extends PluginCommand { + ListCommand(Directory packagesDir, FileSystem fileSystem) + : super(packagesDir, fileSystem) { + argParser.addOption( + _type, + defaultsTo: _plugin, + allowed: [_plugin, _example, _package, _file], + help: 'What type of file system content to list.', + ); + } + + static const String _type = 'type'; + static const String _plugin = 'plugin'; + static const String _example = 'example'; + static const String _package = 'package'; + static const String _file = 'file'; + + @override + final String name = 'list'; + + @override + final String description = 'Lists packages or files'; + + @override + Future run() async { + checkSharding(); + switch (argResults[_type]) { + case _plugin: + await for (Directory package in getPlugins()) { + print(package.path); + } + break; + case _example: + await for (Directory package in getExamples()) { + print(package.path); + } + break; + case _package: + await for (Directory package in getPackages()) { + print(package.path); + } + break; + case _file: + await for (File file in getFiles()) { + print(file.path); + } + break; + } + } +} diff --git a/script/tool/lib/src/main.dart b/script/tool/lib/src/main.dart new file mode 100644 index 000000000000..bb3f67c0a9e1 --- /dev/null +++ b/script/tool/lib/src/main.dart @@ -0,0 +1,63 @@ +// 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. + +import 'dart:io' as io; + +import 'package:args/command_runner.dart'; +import 'package:file/file.dart'; +import 'package:file/local.dart'; +import 'package:flutter_plugin_tools/src/publish_plugin_command.dart'; +import 'package:path/path.dart' as p; + +import 'analyze_command.dart'; +import 'build_examples_command.dart'; +import 'common.dart'; +import 'create_all_plugins_app_command.dart'; +import 'drive_examples_command.dart'; +import 'firebase_test_lab_command.dart'; +import 'format_command.dart'; +import 'java_test_command.dart'; +import 'lint_podspecs_command.dart'; +import 'list_command.dart'; +import 'test_command.dart'; +import 'version_check_command.dart'; +import 'xctest_command.dart'; + +void main(List args) { + final FileSystem fileSystem = const LocalFileSystem(); + + Directory packagesDir = fileSystem + .directory(p.join(fileSystem.currentDirectory.path, 'packages')); + + if (!packagesDir.existsSync()) { + if (p.basename(fileSystem.currentDirectory.path) == 'packages') { + packagesDir = fileSystem.currentDirectory; + } else { + print('Error: Cannot find a "packages" sub-directory'); + io.exit(1); + } + } + + final CommandRunner commandRunner = CommandRunner( + 'pub global run flutter_plugin_tools', + 'Productivity utils for hosting multiple plugins within one repository.') + ..addCommand(AnalyzeCommand(packagesDir, fileSystem)) + ..addCommand(BuildExamplesCommand(packagesDir, fileSystem)) + ..addCommand(CreateAllPluginsAppCommand(packagesDir, fileSystem)) + ..addCommand(DriveExamplesCommand(packagesDir, fileSystem)) + ..addCommand(FirebaseTestLabCommand(packagesDir, fileSystem)) + ..addCommand(FormatCommand(packagesDir, fileSystem)) + ..addCommand(JavaTestCommand(packagesDir, fileSystem)) + ..addCommand(LintPodspecsCommand(packagesDir, fileSystem)) + ..addCommand(ListCommand(packagesDir, fileSystem)) + ..addCommand(PublishPluginCommand(packagesDir, fileSystem)) + ..addCommand(TestCommand(packagesDir, fileSystem)) + ..addCommand(VersionCheckCommand(packagesDir, fileSystem)) + ..addCommand(XCTestCommand(packagesDir, fileSystem)); + + commandRunner.run(args).catchError((Object e) { + final ToolExit toolExit = e; + io.exit(toolExit.exitCode); + }, test: (Object e) => e is ToolExit); +} diff --git a/script/tool/lib/src/publish_plugin_command.dart b/script/tool/lib/src/publish_plugin_command.dart new file mode 100644 index 000000000000..f7e3b5deeecf --- /dev/null +++ b/script/tool/lib/src/publish_plugin_command.dart @@ -0,0 +1,223 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:file/file.dart'; +import 'package:git/git.dart'; +import 'package:meta/meta.dart'; +import 'package:path/path.dart' as p; +import 'package:yaml/yaml.dart'; + +import 'common.dart'; + +/// Wraps pub publish with a few niceties used by the flutter/plugin team. +/// +/// 1. Checks for any modified files in git and refuses to publish if there's an +/// issue. +/// 2. Tags the release with the format -v. +/// 3. Pushes the release to a remote. +/// +/// Both 2 and 3 are optional, see `plugin_tools help publish-plugin` for full +/// usage information. +/// +/// [processRunner], [print], and [stdin] can be overriden for easier testing. +class PublishPluginCommand extends PluginCommand { + PublishPluginCommand( + Directory packagesDir, + FileSystem fileSystem, { + ProcessRunner processRunner = const ProcessRunner(), + Print print = print, + Stdin stdinput, + }) : _print = print, + _stdin = stdinput ?? stdin, + super(packagesDir, fileSystem, processRunner: processRunner) { + argParser.addOption( + _packageOption, + help: 'The package to publish.' + 'If the package directory name is different than its pubspec.yaml name, then this should specify the directory.', + ); + argParser.addMultiOption(_pubFlagsOption, + help: + 'A list of options that will be forwarded on to pub. Separate multiple flags with commas.'); + argParser.addFlag( + _tagReleaseOption, + help: 'Whether or not to tag the release.', + defaultsTo: true, + negatable: true, + ); + argParser.addFlag( + _pushTagsOption, + help: + 'Whether or not tags should be pushed to a remote after creation. Ignored if tag-release is false.', + defaultsTo: true, + negatable: true, + ); + argParser.addOption( + _remoteOption, + help: + 'The name of the remote to push the tags to. Ignored if push-tags or tag-release is false.', + // Flutter convention is to use "upstream" for the single source of truth, and "origin" for personal forks. + defaultsTo: 'upstream', + ); + } + + static const String _packageOption = 'package'; + static const String _tagReleaseOption = 'tag-release'; + static const String _pushTagsOption = 'push-tags'; + static const String _pubFlagsOption = 'pub-publish-flags'; + static const String _remoteOption = 'remote'; + + // Version tags should follow -v. For example, + // `flutter_plugin_tools-v0.0.24`. + static const String _tagFormat = '%PACKAGE%-v%VERSION%'; + + @override + final String name = 'publish-plugin'; + + @override + final String description = + 'Attempts to publish the given plugin and tag its release on GitHub.'; + + final Print _print; + final Stdin _stdin; + // The directory of the actual package that we are publishing. + Directory _packageDir; + StreamSubscription _stdinSubscription; + + @override + Future run() async { + checkSharding(); + _print('Checking local repo...'); + _packageDir = _checkPackageDir(); + await _checkGitStatus(); + final bool shouldPushTag = argResults[_pushTagsOption]; + final String remote = argResults[_remoteOption]; + String remoteUrl; + if (shouldPushTag) { + remoteUrl = await _verifyRemote(remote); + } + _print('Local repo is ready!'); + + await _publish(); + _print('Package published!'); + if (!argResults[_tagReleaseOption]) { + return await _finishSuccesfully(); + } + + _print('Tagging release...'); + final String tag = _getTag(); + await processRunner.runAndExitOnError('git', ['tag', tag], + workingDir: _packageDir); + if (!shouldPushTag) { + return await _finishSuccesfully(); + } + + _print('Pushing tag to $remote...'); + await _pushTagToRemote(remote: remote, tag: tag, remoteUrl: remoteUrl); + await _finishSuccesfully(); + } + + Future _finishSuccesfully() async { + await _stdinSubscription.cancel(); + _print('Done!'); + } + + Directory _checkPackageDir() { + final String package = argResults[_packageOption]; + if (package == null) { + _print( + 'Must specify a package to publish. See `plugin_tools help publish-plugin`.'); + throw ToolExit(1); + } + final Directory _packageDir = packagesDir.childDirectory(package); + if (!_packageDir.existsSync()) { + _print('${_packageDir.absolute.path} does not exist.'); + throw ToolExit(1); + } + return _packageDir; + } + + Future _checkGitStatus() async { + if (!await GitDir.isGitDir(packagesDir.path)) { + _print('$packagesDir is not a valid Git repository.'); + throw ToolExit(1); + } + + final ProcessResult statusResult = await processRunner.runAndExitOnError( + 'git', + [ + 'status', + '--porcelain', + '--ignored', + _packageDir.absolute.path + ], + workingDir: _packageDir); + final String statusOutput = statusResult.stdout; + if (statusOutput.isNotEmpty) { + _print( + "There are files in the package directory that haven't been saved in git. Refusing to publish these files:\n\n" + '$statusOutput\n' + 'If the directory should be clean, you can run `git clean -xdf && git reset --hard HEAD` to wipe all local changes.'); + throw ToolExit(1); + } + } + + Future _verifyRemote(String remote) async { + final ProcessResult remoteInfo = await processRunner.runAndExitOnError( + 'git', ['remote', 'get-url', remote], + workingDir: _packageDir); + return remoteInfo.stdout; + } + + Future _publish() async { + final List publishFlags = argResults[_pubFlagsOption]; + _print( + 'Running `pub publish ${publishFlags.join(' ')}` in ${_packageDir.absolute.path}...\n'); + final Process publish = await processRunner.start( + 'flutter', ['pub', 'publish'] + publishFlags, + workingDirectory: _packageDir); + publish.stdout + .transform(utf8.decoder) + .listen((String data) => _print(data)); + publish.stderr + .transform(utf8.decoder) + .listen((String data) => _print(data)); + _stdinSubscription = _stdin + .transform(utf8.decoder) + .listen((String data) => publish.stdin.writeln(data)); + final int result = await publish.exitCode; + if (result != 0) { + _print('Publish failed. Exiting.'); + throw ToolExit(result); + } + } + + String _getTag() { + final File pubspecFile = + fileSystem.file(p.join(_packageDir.path, 'pubspec.yaml')); + final YamlMap pubspecYaml = loadYaml(pubspecFile.readAsStringSync()); + final String name = pubspecYaml['name']; + final String version = pubspecYaml['version']; + // We should have failed to publish if these were unset. + assert(name.isNotEmpty && version.isNotEmpty); + return _tagFormat + .replaceAll('%PACKAGE%', name) + .replaceAll('%VERSION%', version); + } + + Future _pushTagToRemote( + {@required String remote, + @required String tag, + @required String remoteUrl}) async { + assert(remote != null && tag != null && remoteUrl != null); + _print('Ready to push $tag to $remoteUrl (y/n)?'); + final String input = _stdin.readLineSync(); + if (input.toLowerCase() != 'y') { + _print('Tag push canceled.'); + throw ToolExit(1); + } + + await processRunner.runAndExitOnError('git', ['push', remote, tag], + workingDir: packagesDir); + } +} diff --git a/script/tool/lib/src/test_command.dart b/script/tool/lib/src/test_command.dart new file mode 100644 index 000000000000..e938168cfa89 --- /dev/null +++ b/script/tool/lib/src/test_command.dart @@ -0,0 +1,101 @@ +// 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. + +import 'dart:async'; + +import 'package:file/file.dart'; +import 'package:path/path.dart' as p; + +import 'common.dart'; + +class TestCommand extends PluginCommand { + TestCommand( + Directory packagesDir, + FileSystem fileSystem, { + ProcessRunner processRunner = const ProcessRunner(), + }) : super(packagesDir, fileSystem, processRunner: processRunner) { + argParser.addOption( + kEnableExperiment, + defaultsTo: '', + help: 'Runs the tests in Dart VM with the given experiments enabled.', + ); + } + + @override + final String name = 'test'; + + @override + final String description = 'Runs the Dart tests for all packages.\n\n' + 'This command requires "flutter" to be in your path.'; + + @override + Future run() async { + checkSharding(); + final List failingPackages = []; + await for (Directory packageDir in getPackages()) { + final String packageName = + p.relative(packageDir.path, from: packagesDir.path); + if (!fileSystem.directory(p.join(packageDir.path, 'test')).existsSync()) { + print('SKIPPING $packageName - no test subdirectory'); + continue; + } + + print('RUNNING $packageName tests...'); + + final String enableExperiment = argResults[kEnableExperiment]; + + // `flutter test` automatically gets packages. `pub run test` does not. :( + int exitCode = 0; + if (isFlutterPackage(packageDir, fileSystem)) { + final List args = [ + 'test', + '--color', + if (enableExperiment.isNotEmpty) + '--enable-experiment=$enableExperiment', + ]; + + if (isWebPlugin(packageDir, fileSystem)) { + args.add('--platform=chrome'); + } + exitCode = await processRunner.runAndStream( + 'flutter', + args, + workingDir: packageDir, + ); + } else { + exitCode = await processRunner.runAndStream( + 'pub', + ['get'], + workingDir: packageDir, + ); + if (exitCode == 0) { + exitCode = await processRunner.runAndStream( + 'pub', + [ + 'run', + if (enableExperiment.isNotEmpty) + '--enable-experiment=$enableExperiment', + 'test', + ], + workingDir: packageDir, + ); + } + } + if (exitCode != 0) { + failingPackages.add(packageName); + } + } + + print('\n\n'); + if (failingPackages.isNotEmpty) { + print('Tests for the following packages are failing (see above):'); + failingPackages.forEach((String package) { + print(' * $package'); + }); + throw ToolExit(1); + } + + print('All tests are passing!'); + } +} diff --git a/script/tool/lib/src/version_check_command.dart b/script/tool/lib/src/version_check_command.dart new file mode 100644 index 000000000000..2c6b92bbcb7a --- /dev/null +++ b/script/tool/lib/src/version_check_command.dart @@ -0,0 +1,220 @@ +// 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. + +import 'dart:async'; +import 'dart:io' as io; + +import 'package:meta/meta.dart'; +import 'package:colorize/colorize.dart'; +import 'package:file/file.dart'; +import 'package:git/git.dart'; +import 'package:pub_semver/pub_semver.dart'; +import 'package:pubspec_parse/pubspec_parse.dart'; +import 'package:yaml/yaml.dart'; + +import 'common.dart'; + +const String _kBaseSha = 'base_sha'; + +class GitVersionFinder { + GitVersionFinder(this.baseGitDir, this.baseSha); + + final GitDir baseGitDir; + final String baseSha; + + static bool isPubspec(String file) { + return file.trim().endsWith('pubspec.yaml'); + } + + Future> getChangedPubSpecs() async { + final io.ProcessResult changedFilesCommand = await baseGitDir + .runCommand(['diff', '--name-only', '$baseSha', 'HEAD']); + final List changedFiles = + changedFilesCommand.stdout.toString().split('\n'); + return changedFiles.where(isPubspec).toList(); + } + + Future getPackageVersion(String pubspecPath, String gitRef) async { + final io.ProcessResult gitShow = + await baseGitDir.runCommand(['show', '$gitRef:$pubspecPath']); + final String fileContent = gitShow.stdout; + final String versionString = loadYaml(fileContent)['version']; + return versionString == null ? null : Version.parse(versionString); + } +} + +enum NextVersionType { + BREAKING_MAJOR, + MAJOR_NULLSAFETY_PRE_RELEASE, + MINOR_NULLSAFETY_PRE_RELEASE, + MINOR, + PATCH, + RELEASE, +} + +Version getNextNullSafetyPreRelease(Version current, Version next) { + String nextNullsafetyPrerelease = 'nullsafety'; + if (current.isPreRelease && + current.preRelease.first is String && + current.preRelease.first == 'nullsafety') { + if (current.preRelease.length == 1) { + nextNullsafetyPrerelease = 'nullsafety.1'; + } else if (current.preRelease.length == 2 && + current.preRelease.last is int) { + nextNullsafetyPrerelease = 'nullsafety.${current.preRelease.last + 1}'; + } + } + return Version( + next.major, + next.minor, + next.patch, + pre: nextNullsafetyPrerelease, + ); +} + +@visibleForTesting +Map getAllowedNextVersions( + Version masterVersion, Version headVersion) { + final Version nextNullSafetyMajor = + getNextNullSafetyPreRelease(masterVersion, masterVersion.nextMajor); + final Version nextNullSafetyMinor = + getNextNullSafetyPreRelease(masterVersion, masterVersion.nextMinor); + final Map allowedNextVersions = + { + masterVersion.nextMajor: NextVersionType.BREAKING_MAJOR, + nextNullSafetyMajor: NextVersionType.MAJOR_NULLSAFETY_PRE_RELEASE, + nextNullSafetyMinor: NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE, + masterVersion.nextMinor: NextVersionType.MINOR, + masterVersion.nextPatch: NextVersionType.PATCH, + }; + + if (masterVersion.major < 1 && headVersion.major < 1) { + int nextBuildNumber = -1; + if (masterVersion.build.isEmpty) { + nextBuildNumber = 1; + } else { + final int currentBuildNumber = masterVersion.build.first; + nextBuildNumber = currentBuildNumber + 1; + } + final Version preReleaseVersion = Version( + masterVersion.major, + masterVersion.minor, + masterVersion.patch, + build: nextBuildNumber.toString(), + ); + allowedNextVersions.clear(); + allowedNextVersions[masterVersion.nextMajor] = NextVersionType.RELEASE; + allowedNextVersions[masterVersion.nextMinor] = + NextVersionType.BREAKING_MAJOR; + allowedNextVersions[masterVersion.nextPatch] = NextVersionType.MINOR; + allowedNextVersions[preReleaseVersion] = NextVersionType.PATCH; + + final Version nextNullSafetyMajor = + getNextNullSafetyPreRelease(masterVersion, masterVersion.nextMinor); + final Version nextNullSafetyMinor = + getNextNullSafetyPreRelease(masterVersion, masterVersion.nextPatch); + + allowedNextVersions[nextNullSafetyMajor] = + NextVersionType.MAJOR_NULLSAFETY_PRE_RELEASE; + allowedNextVersions[nextNullSafetyMinor] = + NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE; + } + return allowedNextVersions; +} + +class VersionCheckCommand extends PluginCommand { + VersionCheckCommand( + Directory packagesDir, + FileSystem fileSystem, { + ProcessRunner processRunner = const ProcessRunner(), + this.gitDir, + }) : super(packagesDir, fileSystem, processRunner: processRunner) { + argParser.addOption(_kBaseSha); + } + + /// The git directory to use. By default it uses the parent directory. + /// + /// This can be mocked for testing. + final GitDir gitDir; + + @override + final String name = 'version-check'; + + @override + final String description = + 'Checks if the versions of the plugins have been incremented per pub specification.\n\n' + 'This command requires "pub" and "flutter" to be in your path.'; + + @override + Future run() async { + checkSharding(); + + final String rootDir = packagesDir.parent.absolute.path; + final String baseSha = argResults[_kBaseSha]; + + GitDir baseGitDir = gitDir; + if (baseGitDir == null) { + if (!await GitDir.isGitDir(rootDir)) { + print('$rootDir is not a valid Git repository.'); + throw ToolExit(2); + } + baseGitDir = await GitDir.fromExisting(rootDir); + } + + final GitVersionFinder gitVersionFinder = + GitVersionFinder(baseGitDir, baseSha); + + final List changedPubspecs = + await gitVersionFinder.getChangedPubSpecs(); + + for (final String pubspecPath in changedPubspecs) { + try { + final File pubspecFile = fileSystem.file(pubspecPath); + if (!pubspecFile.existsSync()) { + continue; + } + final Pubspec pubspec = Pubspec.parse(pubspecFile.readAsStringSync()); + if (pubspec.publishTo == 'none') { + continue; + } + + final Version masterVersion = + await gitVersionFinder.getPackageVersion(pubspecPath, baseSha); + final Version headVersion = + await gitVersionFinder.getPackageVersion(pubspecPath, 'HEAD'); + if (headVersion == null) { + continue; // Example apps don't have versions + } + + final Map allowedNextVersions = + getAllowedNextVersions(masterVersion, headVersion); + + if (!allowedNextVersions.containsKey(headVersion)) { + final String error = '$pubspecPath incorrectly updated version.\n' + 'HEAD: $headVersion, master: $masterVersion.\n' + 'Allowed versions: $allowedNextVersions'; + final Colorize redError = Colorize(error)..red(); + print(redError); + throw ToolExit(1); + } + + bool isPlatformInterface = pubspec.name.endsWith("_platform_interface"); + if (isPlatformInterface && + allowedNextVersions[headVersion] == + NextVersionType.BREAKING_MAJOR) { + final String error = '$pubspecPath breaking change detected.\n' + 'Breaking changes to platform interfaces are strongly discouraged.\n'; + final Colorize redError = Colorize(error)..red(); + print(redError); + throw ToolExit(1); + } + } on io.ProcessException { + print('Unable to find pubspec in master for $pubspecPath.' + ' Safe to ignore if the project is new.'); + } + } + + print('No version check errors found!'); + } +} diff --git a/script/tool/lib/src/xctest_command.dart b/script/tool/lib/src/xctest_command.dart new file mode 100644 index 000000000000..d90b7a8fbfea --- /dev/null +++ b/script/tool/lib/src/xctest_command.dart @@ -0,0 +1,216 @@ +// 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. + +import 'dart:async'; +import 'dart:convert'; +import 'dart:io' as io; + +import 'package:file/file.dart'; +import 'package:path/path.dart' as p; + +import 'common.dart'; + +const String _kiOSDestination = 'ios-destination'; +const String _kTarget = 'target'; +const String _kSkip = 'skip'; +const String _kXcodeBuildCommand = 'xcodebuild'; +const String _kXCRunCommand = 'xcrun'; +const String _kFoundNoSimulatorsMessage = + 'Cannot find any available simulators, tests failed'; + +/// The command to run iOS' XCTests in plugins, this should work for both XCUnitTest and XCUITest targets. +/// The tests target have to be added to the xcode project of the example app. Usually at "example/ios/Runner.xcodeproj". +/// The command takes a "-target" argument which has to match the target of the test target. +/// For information on how to add test target in an xcode project, see https://developer.apple.com/library/archive/documentation/ToolsLanguages/Conceptual/Xcode_Overview/UnitTesting.html +class XCTestCommand extends PluginCommand { + XCTestCommand( + Directory packagesDir, + FileSystem fileSystem, { + ProcessRunner processRunner = const ProcessRunner(), + }) : super(packagesDir, fileSystem, processRunner: processRunner) { + argParser.addOption( + _kiOSDestination, + help: + 'Specify the destination when running the test, used for -destination flag for xcodebuild command.\n' + 'this is passed to the `-destination` argument in xcodebuild command.\n' + 'See https://developer.apple.com/library/archive/technotes/tn2339/_index.html#//apple_ref/doc/uid/DTS40014588-CH1-UNIT for details on how to specify the destination.', + ); + argParser.addOption(_kTarget, + help: 'The test target.\n' + 'This is the xcode project test target. This is passed to the `-scheme` argument in the xcodebuild command. \n' + 'See https://developer.apple.com/library/archive/technotes/tn2339/_index.html#//apple_ref/doc/uid/DTS40014588-CH1-UNIT for details on how to specify the scheme'); + argParser.addMultiOption(_kSkip, + help: 'Plugins to skip while running this command. \n'); + } + + @override + final String name = 'xctest'; + + @override + final String description = 'Runs the xctests in the iOS example apps.\n\n' + 'This command requires "flutter" to be in your path.'; + + @override + Future run() async { + if (argResults[_kTarget] == null) { + // TODO(cyanglaz): Automatically find all the available testing schemes if this argument is not specified. + // https://github.com/flutter/flutter/issues/68419 + print('--$_kTarget must be specified'); + throw ToolExit(1); + } + + String destination = argResults[_kiOSDestination]; + if (destination == null) { + String simulatorId = await _findAvailableIphoneSimulator(); + if (simulatorId == null) { + print(_kFoundNoSimulatorsMessage); + throw ToolExit(1); + } + destination = 'id=$simulatorId'; + } + + checkSharding(); + + final String target = argResults[_kTarget]; + final List skipped = argResults[_kSkip]; + + List failingPackages = []; + await for (Directory plugin in getPlugins()) { + // Start running for package. + final String packageName = + p.relative(plugin.path, from: packagesDir.path); + print('Start running for $packageName ...'); + if (!isIosPlugin(plugin, fileSystem)) { + print('iOS is not supported by this plugin.'); + print('\n\n'); + continue; + } + if (skipped.contains(packageName)) { + print('$packageName was skipped with the --skip flag.'); + print('\n\n'); + continue; + } + for (Directory example in getExamplesForPlugin(plugin)) { + // Look for the test scheme in the example app. + print('Look for target named: $_kTarget ...'); + final List findSchemeArgs = [ + '-project', + 'ios/Runner.xcodeproj', + '-list', + '-json' + ]; + final String completeFindSchemeCommand = + '$_kXcodeBuildCommand ${findSchemeArgs.join(' ')}'; + print(completeFindSchemeCommand); + final io.ProcessResult xcodeprojListResult = await processRunner + .run(_kXcodeBuildCommand, findSchemeArgs, workingDir: example); + if (xcodeprojListResult.exitCode != 0) { + print('Error occurred while running "$completeFindSchemeCommand":\n' + '${xcodeprojListResult.stderr}'); + failingPackages.add(packageName); + print('\n\n'); + continue; + } + + final String xcodeprojListOutput = xcodeprojListResult.stdout; + Map xcodeprojListOutputJson = + jsonDecode(xcodeprojListOutput); + if (!xcodeprojListOutputJson['project']['targets'].contains(target)) { + failingPackages.add(packageName); + print('$target not configured for $packageName, test failed.'); + print( + 'Please check the scheme for the test target if it matches the name $target.\n' + 'If this plugin does not have an XCTest target, use the $_kSkip flag in the $name command to skip the plugin.'); + print('\n\n'); + continue; + } + // Found the scheme, running tests + print('Running XCTests:$target for $packageName ...'); + final List xctestArgs = [ + 'test', + '-workspace', + 'ios/Runner.xcworkspace', + '-scheme', + target, + '-destination', + destination, + 'CODE_SIGN_IDENTITY=""', + 'CODE_SIGNING_REQUIRED=NO' + ]; + final String completeTestCommand = + '$_kXcodeBuildCommand ${xctestArgs.join(' ')}'; + print(completeTestCommand); + final int exitCode = await processRunner + .runAndStream(_kXcodeBuildCommand, xctestArgs, workingDir: example); + if (exitCode == 0) { + print('Successfully ran xctest for $packageName'); + } else { + failingPackages.add(packageName); + } + } + } + + // Command end, print reports. + if (failingPackages.isEmpty) { + print("All XCTests have passed!"); + } else { + print( + 'The following packages are failing XCTests (see above for details):'); + for (String package in failingPackages) { + print(' * $package'); + } + throw ToolExit(1); + } + } + + Future _findAvailableIphoneSimulator() async { + // Find the first available destination if not specified. + final List findSimulatorsArguments = [ + 'simctl', + 'list', + '--json' + ]; + final String findSimulatorCompleteCommand = + '$_kXCRunCommand ${findSimulatorsArguments.join(' ')}'; + print('Looking for available simulators...'); + print(findSimulatorCompleteCommand); + final io.ProcessResult findSimulatorsResult = + await processRunner.run(_kXCRunCommand, findSimulatorsArguments); + if (findSimulatorsResult.exitCode != 0) { + print('Error occurred while running "$findSimulatorCompleteCommand":\n' + '${findSimulatorsResult.stderr}'); + throw ToolExit(1); + } + final Map simulatorListJson = + jsonDecode(findSimulatorsResult.stdout); + final List runtimes = simulatorListJson['runtimes']; + final Map devices = simulatorListJson['devices']; + if (runtimes.isEmpty || devices.isEmpty) { + return null; + } + String id; + // Looking for runtimes, trying to find one with highest OS version. + for (Map runtimeMap in runtimes.reversed) { + if (!runtimeMap['name'].contains('iOS')) { + continue; + } + final String runtimeID = runtimeMap['identifier']; + final List devicesForRuntime = devices[runtimeID]; + if (devicesForRuntime.isEmpty) { + continue; + } + // Looking for runtimes, trying to find latest version of device. + for (Map device in devicesForRuntime.reversed) { + if (device['availabilityError'] != null || + (device['isAvailable'] as bool == false)) { + continue; + } + id = device['udid']; + print('device selected: $device'); + return id; + } + } + return null; + } +} diff --git a/script/tool/pubspec.yaml b/script/tool/pubspec.yaml new file mode 100644 index 000000000000..d9fce4ad26a7 --- /dev/null +++ b/script/tool/pubspec.yaml @@ -0,0 +1,25 @@ +name: flutter_plugin_tools +description: Productivity utils for hosting multiple plugins within one repository. +publish_to: 'none' + +dependencies: + args: "^1.4.3" + path: "^1.6.1" + http: "^0.12.1" + async: "^2.0.7" + yaml: "^2.1.15" + quiver: "^2.0.2" + pub_semver: ^1.4.2 + colorize: ^2.0.0 + git: ^1.0.0 + platform: ^2.2.0 + pubspec_parse: "^0.1.4" + test: ^1.6.4 + meta: ^1.1.7 + file: ^5.0.10 + uuid: ^2.0.4 + http_multi_server: ^2.2.0 + collection: 1.14.13 + +environment: + sdk: ">=2.3.0 <3.0.0" From c7b9a244a6a5249976ffb986f9f63d92b8608363 Mon Sep 17 00:00:00 2001 From: Sameer Kashyap <40424087+Sameerkash@users.noreply.github.com> Date: Sat, 13 Feb 2021 05:21:03 +0530 Subject: [PATCH 0129/1565] [image_picker_web] Migrate to null-safety (#3535) --- .../image_picker_for_web/CHANGELOG.md | 4 ++ .../lib/image_picker_for_web.dart | 62 ++++++++++--------- .../image_picker_for_web/pubspec.yaml | 16 +++-- .../test/image_picker_for_web_test.dart | 4 +- 4 files changed, 45 insertions(+), 41 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/CHANGELOG.md b/packages/image_picker/image_picker_for_web/CHANGELOG.md index 4c452ee78de9..37b17b3eef26 100644 --- a/packages/image_picker/image_picker_for_web/CHANGELOG.md +++ b/packages/image_picker/image_picker_for_web/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.0.0-nullsafety + +* Migrate to null safety. + # 0.1.0+3 * Update Flutter SDK constraint. diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index e50b4aad3c8d..0c05980172aa 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -13,14 +13,14 @@ final String _kAcceptVideoMimeType = 'video/3gpp,video/x-m4v,video/mp4,video/*'; /// /// This class implements the `package:image_picker` functionality for the web. class ImagePickerPlugin extends ImagePickerPlatform { - final ImagePickerPluginTestOverrides _overrides; + final ImagePickerPluginTestOverrides? _overrides; bool get _hasOverrides => _overrides != null; - html.Element _target; + late html.Element _target; /// A constructor that allows tests to override the function that creates file inputs. ImagePickerPlugin({ - @visibleForTesting ImagePickerPluginTestOverrides overrides, + @visibleForTesting ImagePickerPluginTestOverrides? overrides, }) : _overrides = overrides { _target = _ensureInitialized(_kImagePickerInputsDomId); } @@ -32,23 +32,23 @@ class ImagePickerPlugin extends ImagePickerPlatform { @override Future pickImage({ - @required ImageSource source, - double maxWidth, - double maxHeight, - int imageQuality, + required ImageSource source, + double? maxWidth, + double? maxHeight, + int? imageQuality, CameraDevice preferredCameraDevice = CameraDevice.rear, }) { - String capture = computeCaptureAttribute(source, preferredCameraDevice); + String? capture = computeCaptureAttribute(source, preferredCameraDevice); return pickFile(accept: _kAcceptImageMimeType, capture: capture); } @override Future pickVideo({ - @required ImageSource source, + required ImageSource source, CameraDevice preferredCameraDevice = CameraDevice.rear, - Duration maxDuration, + Duration? maxDuration, }) { - String capture = computeCaptureAttribute(source, preferredCameraDevice); + String? capture = computeCaptureAttribute(source, preferredCameraDevice); return pickFile(accept: _kAcceptVideoMimeType, capture: capture); } @@ -59,10 +59,11 @@ class ImagePickerPlugin extends ImagePickerPlatform { /// See https://caniuse.com/#feat=html-media-capture @visibleForTesting Future pickFile({ - String accept, - String capture, + String? accept, + String? capture, }) { - html.FileUploadInputElement input = createInputElement(accept, capture); + html.FileUploadInputElement input = + createInputElement(accept, capture) as html.FileUploadInputElement; _injectAndActivate(input); return _getSelectedFile(input); } @@ -73,25 +74,26 @@ class ImagePickerPlugin extends ImagePickerPlatform { /// /// See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#capture @visibleForTesting - String computeCaptureAttribute(ImageSource source, CameraDevice device) { + String? computeCaptureAttribute(ImageSource source, CameraDevice device) { if (source == ImageSource.camera) { return (device == CameraDevice.front) ? 'user' : 'environment'; } return null; } - html.File _getFileFromInput(html.FileUploadInputElement input) { + html.File? _getFileFromInput(html.FileUploadInputElement input) { if (_hasOverrides) { - return _overrides.getFileFromInput(input); + return _overrides!.getFileFromInput(input); } - return input?.files?.first; + return input.files?.first; } /// Handles the OnChange event from a FileUploadInputElement object /// Returns the objectURL of the selected file. - String _handleOnChangeEvent(html.Event event) { - final html.FileUploadInputElement input = event?.target; - final html.File file = _getFileFromInput(input); + String? _handleOnChangeEvent(html.Event event) { + final html.FileUploadInputElement input = + event.target as html.FileUploadInputElement; + final html.File? file = _getFileFromInput(input); if (file != null) { return html.Url.createObjectUrl(file); @@ -105,7 +107,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { // Observe the input until we can return something input.onChange.first.then((event) { final objectUrl = _handleOnChangeEvent(event); - if (!_completer.isCompleted) { + if (!_completer.isCompleted && objectUrl != null) { _completer.complete(PickedFile(objectUrl)); } }); @@ -127,7 +129,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { final html.Element targetElement = html.Element.tag('flt-image-picker-inputs')..id = id; - html.querySelector('body').children.add(targetElement); + html.querySelector('body')!.children.add(targetElement); target = targetElement; } return target; @@ -136,9 +138,9 @@ class ImagePickerPlugin extends ImagePickerPlatform { /// Creates an input element that accepts certain file types, and /// allows to `capture` from the device's cameras (where supported) @visibleForTesting - html.Element createInputElement(String accept, String capture) { + html.Element createInputElement(String? accept, String? capture) { if (_hasOverrides) { - return _overrides.createInputElement(accept, capture); + return _overrides!.createInputElement(accept, capture); } html.Element element = html.FileUploadInputElement()..accept = accept; @@ -162,22 +164,22 @@ class ImagePickerPlugin extends ImagePickerPlatform { /// A function that creates a file input with the passed in `accept` and `capture` attributes. @visibleForTesting typedef OverrideCreateInputFunction = html.Element Function( - String accept, - String capture, + String? accept, + String? capture, ); /// A function that extracts a [html.File] from the file `input` passed in. @visibleForTesting typedef OverrideExtractFilesFromInputFunction = html.File Function( - html.Element input, + html.Element? input, ); /// Overrides for some of the functionality above. @visibleForTesting class ImagePickerPluginTestOverrides { /// Override the creation of the input element. - OverrideCreateInputFunction createInputElement; + late OverrideCreateInputFunction createInputElement; /// Override the extraction of the selected file from an input element. - OverrideExtractFilesFromInputFunction getFileFromInput; + late OverrideExtractFilesFromInputFunction getFileFromInput; } diff --git a/packages/image_picker/image_picker_for_web/pubspec.yaml b/packages/image_picker/image_picker_for_web/pubspec.yaml index b7e079b39ce0..c270cd597c87 100644 --- a/packages/image_picker/image_picker_for_web/pubspec.yaml +++ b/packages/image_picker/image_picker_for_web/pubspec.yaml @@ -1,10 +1,8 @@ name: image_picker_for_web description: Web platform implementation of image_picker homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker_for_web -# 0.1.y+z is compatible with 1.0.0, if you land a breaking change bump -# the version to 2.0.0. -# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.1.0+3 + +version: 2.0.0-nullsafety flutter: plugin: @@ -14,19 +12,19 @@ flutter: fileName: image_picker_for_web.dart dependencies: - image_picker_platform_interface: ^1.1.0 + image_picker_platform_interface: ^2.0.0-nullsafety flutter: sdk: flutter flutter_web_plugins: sdk: flutter - meta: ^1.1.7 - js: ^0.6.0 + meta: ^1.3.0-nullsafety.6 + js: ^0.6.3-nullsafety.3 dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0 environment: - sdk: ">=2.5.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.10.0" diff --git a/packages/image_picker/image_picker_for_web/test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/test/image_picker_for_web_test.dart index 96d048dd2a8e..fcc2c003a10b 100644 --- a/packages/image_picker/image_picker_for_web/test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/test/image_picker_for_web_test.dart @@ -13,12 +13,12 @@ import 'package:image_picker_for_web/image_picker_for_web.dart'; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; final String expectedStringContents = "Hello, world!"; -final Uint8List bytes = utf8.encode(expectedStringContents); +final Uint8List bytes = utf8.encode(expectedStringContents) as Uint8List; final html.File textFile = html.File([bytes], "hello.txt"); void main() { // Under test... - ImagePickerPlugin plugin; + late ImagePickerPlugin plugin; setUp(() { plugin = ImagePickerPlugin(); From aa22656648917816a49459b82f4fd95e8d983fc1 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 12 Feb 2021 17:04:59 -0800 Subject: [PATCH 0130/1565] Honor, and scrub, the 1.0 compatibility promise (#3545) --- packages/android_intent/README.md | 7 ------- .../connectivity/connectivity_macos/CHANGELOG.md | 4 ++++ .../connectivity/connectivity_macos/README.md | 8 -------- .../connectivity/connectivity_macos/pubspec.yaml | 5 +---- packages/device_info/device_info/pubspec.yaml | 3 --- packages/package_info/CHANGELOG.md | 4 ++++ packages/package_info/README.md | 15 ++++----------- packages/package_info/pubspec.yaml | 5 +---- .../path_provider_linux/CHANGELOG.md | 4 ++++ .../path_provider/path_provider_linux/README.md | 7 ------- .../path_provider_linux/pubspec.yaml | 2 +- .../path_provider_macos/CHANGELOG.md | 4 ++++ .../path_provider/path_provider_macos/README.md | 7 ------- .../path_provider_macos/pubspec.yaml | 5 +---- .../path_provider_windows/CHANGELOG.md | 4 ++++ .../path_provider/path_provider_windows/README.md | 8 -------- .../path_provider_windows/pubspec.yaml | 3 +-- packages/sensors/CHANGELOG.md | 4 ++++ packages/sensors/README.md | 7 ------- packages/sensors/pubspec.yaml | 5 +---- packages/share/README.md | 7 ------- .../shared_preferences/pubspec.yaml | 3 --- .../shared_preferences_linux/CHANGELOG.md | 4 ++++ .../shared_preferences_linux/pubspec.yaml | 2 +- .../shared_preferences_macos/CHANGELOG.md | 4 ++++ .../shared_preferences_macos/README.md | 7 ------- .../shared_preferences_macos/pubspec.yaml | 5 +---- .../shared_preferences_web/CHANGELOG.md | 4 ++++ .../shared_preferences_web/README.md | 7 ------- .../shared_preferences_web/pubspec.yaml | 5 +---- .../shared_preferences_windows/CHANGELOG.md | 4 ++++ .../shared_preferences_windows/pubspec.yaml | 2 +- .../url_launcher/url_launcher_linux/CHANGELOG.md | 4 ++++ .../url_launcher/url_launcher_linux/pubspec.yaml | 2 +- .../url_launcher/url_launcher_macos/CHANGELOG.md | 5 ++++- .../url_launcher/url_launcher_macos/README.md | 7 ------- .../url_launcher/url_launcher_macos/pubspec.yaml | 5 +---- .../url_launcher_windows/CHANGELOG.md | 4 ++++ .../url_launcher/url_launcher_windows/README.md | 7 ------- .../url_launcher_windows/pubspec.yaml | 5 +---- packages/video_player/video_player/pubspec.yaml | 3 --- packages/video_player/video_player_web/README.md | 7 ------- .../video_player/video_player_web/pubspec.yaml | 3 --- 43 files changed, 69 insertions(+), 148 deletions(-) diff --git a/packages/android_intent/README.md b/packages/android_intent/README.md index aabf059ea336..7d097e465926 100644 --- a/packages/android_intent/README.md +++ b/packages/android_intent/README.md @@ -5,13 +5,6 @@ is Android. If the plugin is invoked on iOS, it will crash your app. In checked mode, we assert that the platform should be Android. -**Please set your constraint to `android_intent: '>=0.3.y+x <2.0.0'`** - -## Backward compatible 1.0.0 version is coming -The plugin has reached a stable API, we guarantee that version `1.0.0` will be backward compatible with `0.3.y+z`. -Please use `android_intent: '>=0.3.y+x <2.0.0'` as your dependency constraint to allow a smoother ecosystem migration. -For more details see: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 - Use it by specifying action, category, data and extra arguments for the intent. It does not support returning the result of the launched activity. Sample usage: diff --git a/packages/connectivity/connectivity_macos/CHANGELOG.md b/packages/connectivity/connectivity_macos/CHANGELOG.md index 890c8938482f..8547db3441c3 100644 --- a/packages/connectivity/connectivity_macos/CHANGELOG.md +++ b/packages/connectivity/connectivity_macos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Update version to (semi-belatedly) meet 1.0-consistency promise. + ## 0.2.0-nullsafety.1 * Remove placeholder Dart file. diff --git a/packages/connectivity/connectivity_macos/README.md b/packages/connectivity/connectivity_macos/README.md index 464f7d79ccd1..6974fd1fcc7e 100644 --- a/packages/connectivity/connectivity_macos/README.md +++ b/packages/connectivity/connectivity_macos/README.md @@ -2,13 +2,6 @@ The macos implementation of [`connectivity`]. -**Please set your constraint to `connectivity_macos: '>=0.1.y+x <2.0.0'`** - -## Backward compatible 1.0.0 version is coming -The plugin has reached a stable API, we guarantee that version `1.0.0` will be backward compatible with `0.1.y+z`. -Please use `connectivity_macos: '>=0.1.y+x <2.0.0'` as your dependency constraint to allow a smoother ecosystem migration. -For more details see: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 - ## Usage ### Import the package @@ -29,4 +22,3 @@ dependencies: ``` Refer to the `connectivity` [documentation](https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity) for more details. - diff --git a/packages/connectivity/connectivity_macos/pubspec.yaml b/packages/connectivity/connectivity_macos/pubspec.yaml index 49c28f081ad7..0a22a8ba5f53 100644 --- a/packages/connectivity/connectivity_macos/pubspec.yaml +++ b/packages/connectivity/connectivity_macos/pubspec.yaml @@ -1,9 +1,6 @@ name: connectivity_macos description: macOS implementation of the connectivity plugin. -# 0.1.y+z is compatible with 1.0.0, if you land a breaking change bump -# the version to 2.0.0. -# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.2.0-nullsafety.1 +version: 2.0.0-nullsafety homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_macos flutter: diff --git a/packages/device_info/device_info/pubspec.yaml b/packages/device_info/device_info/pubspec.yaml index 1a222869a632..bcdc7c8b54d1 100644 --- a/packages/device_info/device_info/pubspec.yaml +++ b/packages/device_info/device_info/pubspec.yaml @@ -2,9 +2,6 @@ name: device_info description: Flutter plugin providing detailed information about the device (make, model, etc.), and Android or iOS version the app is running on. homepage: https://github.com/flutter/plugins/tree/master/packages/device_info -# 0.4.y+z is compatible with 1.0.0, if you land a breaking change bump -# the version to 2.0.0. -# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 version: 2.0.0-nullsafety.2 flutter: diff --git a/packages/package_info/CHANGELOG.md b/packages/package_info/CHANGELOG.md index 91da35966283..ddf01f0f3999 100644 --- a/packages/package_info/CHANGELOG.md +++ b/packages/package_info/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Update version to (semi-belatedly) meet 1.0-consistency promise. + ## 0.5.0-nullsafety * Migrate to null safety. diff --git a/packages/package_info/README.md b/packages/package_info/README.md index b5b2405a231a..a09db08dd484 100644 --- a/packages/package_info/README.md +++ b/packages/package_info/README.md @@ -3,13 +3,6 @@ This Flutter plugin provides an API for querying information about an application package. -**Please set your constraint to `package_info: '>=0.4.y+x <2.0.0'`** - -## Backward compatible 1.0.0 version is coming -The package_info plugin has reached a stable API, we guarantee that version `1.0.0` will be backward compatible with `0.4.y+z`. -Please use `package_info: '>=0.4.y+x <2.0.0'` as your dependency constraint to allow a smoother ecosystem migration. -For more details see: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 - # Usage You can use the PackageInfo to query information about the @@ -39,10 +32,10 @@ PackageInfo.fromPlatform().then((PackageInfo packageInfo) { ## Known Issue -As noted on [issue 20761](https://github.com/flutter/flutter/issues/20761#issuecomment-493434578), package_info on iOS -requires the Xcode build folder to be rebuilt after changes to the version string in `pubspec.yaml`. -Clean the Xcode build folder with: -`XCode Menu -> Product -> (Holding Option Key) Clean build folder`. +As noted on [issue 20761](https://github.com/flutter/flutter/issues/20761#issuecomment-493434578), package_info on iOS +requires the Xcode build folder to be rebuilt after changes to the version string in `pubspec.yaml`. +Clean the Xcode build folder with: +`XCode Menu -> Product -> (Holding Option Key) Clean build folder`. ## Issues and feedback diff --git a/packages/package_info/pubspec.yaml b/packages/package_info/pubspec.yaml index f575ad155e4e..67fbc5f626db 100644 --- a/packages/package_info/pubspec.yaml +++ b/packages/package_info/pubspec.yaml @@ -2,10 +2,7 @@ name: package_info description: Flutter plugin for querying information about the application package, such as CFBundleVersion on iOS or versionCode on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/package_info -# 0.4.y+z is compatible with 1.0.0, if you land a breaking change bump -# the version to 2.0.0. -# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.5.0-nullsafety +version: 2.0.0-nullsafety flutter: plugin: diff --git a/packages/path_provider/path_provider_linux/CHANGELOG.md b/packages/path_provider/path_provider_linux/CHANGELOG.md index 2deb84237712..126aadcffeb4 100644 --- a/packages/path_provider/path_provider_linux/CHANGELOG.md +++ b/packages/path_provider/path_provider_linux/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Update version to (semi-belatedly) meet 1.0-consistency promise. + ## 0.2.0-nullsafety * Migrate to null safety. diff --git a/packages/path_provider/path_provider_linux/README.md b/packages/path_provider/path_provider_linux/README.md index 373925d2d96d..ef9e0e855c86 100644 --- a/packages/path_provider/path_provider_linux/README.md +++ b/packages/path_provider/path_provider_linux/README.md @@ -2,13 +2,6 @@ The linux implementation of [`path_provider`]. -**Please set your constraint to `path_provider: '>=0.0.y+x <2.0.0'`** - -## Backward compatible 1.0.0 version is coming -The `path_provider` plugin has reached a stable API, we guarantee that version `1.0.0` will be backward compatible with `0.0.y+z`. -Please use `path_provider: '>=0.0.y+x <2.0.0'` as your dependency constraint to allow a smoother ecosystem migration. -For more details see: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 - ## Usage This package is already included as part of the `path_provider` package dependency, and will diff --git a/packages/path_provider/path_provider_linux/pubspec.yaml b/packages/path_provider/path_provider_linux/pubspec.yaml index df459e12d37f..c6940b1158ee 100644 --- a/packages/path_provider/path_provider_linux/pubspec.yaml +++ b/packages/path_provider/path_provider_linux/pubspec.yaml @@ -1,6 +1,6 @@ name: path_provider_linux description: linux implementation of the path_provider plugin -version: 0.2.0-nullsafety +version: 2.0.0-nullsafety homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_linux flutter: diff --git a/packages/path_provider/path_provider_macos/CHANGELOG.md b/packages/path_provider/path_provider_macos/CHANGELOG.md index 2f7290c2ced1..de7ab3e94f9d 100644 --- a/packages/path_provider/path_provider_macos/CHANGELOG.md +++ b/packages/path_provider/path_provider_macos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Update version to (semi-belatedly) meet 1.0-consistency promise. + ## 0.0.5-nullsafety * Update Dart SDK constraint for null safety. diff --git a/packages/path_provider/path_provider_macos/README.md b/packages/path_provider/path_provider_macos/README.md index b97d9e81b7db..23727fe7f370 100644 --- a/packages/path_provider/path_provider_macos/README.md +++ b/packages/path_provider/path_provider_macos/README.md @@ -2,13 +2,6 @@ The macos implementation of [`path_provider`]. -**Please set your constraint to `path_provider_macos: '>=0.0.y+x <2.0.0'`** - -## Backward compatible 1.0.0 version is coming -The plugin has reached a stable API, we guarantee that version `1.0.0` will be backward compatible with `0.0.y+z`. -Please use `path_provider_macos: '>=0.0.y+x <2.0.0'` as your dependency constraint to allow a smoother ecosystem migration. -For more details see: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 - ## Usage ### Import the package diff --git a/packages/path_provider/path_provider_macos/pubspec.yaml b/packages/path_provider/path_provider_macos/pubspec.yaml index a2bbd58b7289..bab79c27a94c 100644 --- a/packages/path_provider/path_provider_macos/pubspec.yaml +++ b/packages/path_provider/path_provider_macos/pubspec.yaml @@ -1,9 +1,6 @@ name: path_provider_macos description: macOS implementation of the path_provider plugin -# 0.0.y+z is compatible with 1.0.0, if you land a breaking change bump -# the version to 2.0.0. -# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.0.5-nullsafety +version: 2.0.0-nullsafety homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_macos flutter: diff --git a/packages/path_provider/path_provider_windows/CHANGELOG.md b/packages/path_provider/path_provider_windows/CHANGELOG.md index 8d365319c32a..2e1701cc53bf 100644 --- a/packages/path_provider/path_provider_windows/CHANGELOG.md +++ b/packages/path_provider/path_provider_windows/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Update version to (semi-belatedly) meet 1.0-consistency promise. + ## 0.1.0-nullsafety.3 * Bump ffi dependency to 1.0.0 diff --git a/packages/path_provider/path_provider_windows/README.md b/packages/path_provider/path_provider_windows/README.md index 66a05f9e7347..6d452e770469 100644 --- a/packages/path_provider/path_provider_windows/README.md +++ b/packages/path_provider/path_provider_windows/README.md @@ -2,14 +2,6 @@ The Windows implementation of [`path_provider`][1]. -**Please set your constraint to `path_provider_windows: '>=0.0.y+x <2.0.0'`** - -## Backward compatible 1.0.0 version is coming - -The plugin has reached a stable API, we guarantee that version `1.0.0` will be backward compatible with `0.0.y+z`. -Please use `path_provider_windows: '>=0.0.y+x <2.0.0'` as your dependency constraint to allow a smoother ecosystem migration. -For more details see: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 - ## Usage ### Import the package diff --git a/packages/path_provider/path_provider_windows/pubspec.yaml b/packages/path_provider/path_provider_windows/pubspec.yaml index d672ff90cdb9..384eae94f5e5 100644 --- a/packages/path_provider/path_provider_windows/pubspec.yaml +++ b/packages/path_provider/path_provider_windows/pubspec.yaml @@ -1,7 +1,7 @@ name: path_provider_windows description: Windows implementation of the path_provider plugin homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_windows -version: 0.1.0-nullsafety.3 +version: 2.0.0-nullsafety flutter: plugin: @@ -27,4 +27,3 @@ dev_dependencies: environment: sdk: '>=2.12.0-259.8.beta <3.0.0' flutter: ">=1.12.13+hotfix.4" - diff --git a/packages/sensors/CHANGELOG.md b/packages/sensors/CHANGELOG.md index 682d377a6b84..8ff904bf3943 100644 --- a/packages/sensors/CHANGELOG.md +++ b/packages/sensors/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* * Update version to (semi-belatedly) meet 1.0-consistency promise. + ## 0.5.0-nullsafety * Migrate to null safety. diff --git a/packages/sensors/README.md b/packages/sensors/README.md index 08a9b2ea2b8c..8c5ab008419b 100644 --- a/packages/sensors/README.md +++ b/packages/sensors/README.md @@ -1,12 +1,5 @@ # sensors -**Please set your constraint to `sensors: '>=0.4.y+x <2.0.0'`** - -## Backward compatible 1.0.0 version is coming -The sensors plugin has reached a stable API, we guarantee that version `1.0.0` will be backward compatible with `0.4.y+z`. -Please use `sensors: '>=0.4.y+x <2.0.0'` as your dependency constraint to allow a smoother ecosystem migration. -For more details see: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 - A Flutter plugin to access the accelerometer and gyroscope sensors. diff --git a/packages/sensors/pubspec.yaml b/packages/sensors/pubspec.yaml index e9b0392bae8d..0416779f1292 100644 --- a/packages/sensors/pubspec.yaml +++ b/packages/sensors/pubspec.yaml @@ -2,10 +2,7 @@ name: sensors description: Flutter plugin for accessing the Android and iOS accelerometer and gyroscope sensors. homepage: https://github.com/flutter/plugins/tree/master/packages/sensors -# 0.4.y+z is compatible with 1.0.0, if you land a breaking change bump -# the version to 2.0.0. -# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.5.0-nullsafety +version: 2.0.0-nullsafety flutter: plugin: diff --git a/packages/share/README.md b/packages/share/README.md index a6e572258a2b..59cfbf7c5665 100644 --- a/packages/share/README.md +++ b/packages/share/README.md @@ -8,13 +8,6 @@ share dialog. Wraps the ACTION_SEND Intent on Android and UIActivityViewController on iOS. -**Please set your constraint to `share: '>=0.6.y+x <2.0.0'`** - -## Backward compatible 1.0.0 version is coming -The plugin has reached a stable API, we guarantee that version `1.0.0` will be backward compatible with `0.6.y+z`. -Please use `share: '>=0.6.y+x <2.0.0'` as your dependency constraint to allow a smoother ecosystem migration. -For more details see: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 - ## Usage To use this plugin, add `share` as a [dependency in your pubspec.yaml file](https://flutter.dev/docs/development/packages-and-plugins/using-packages/). diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index 434c9c6bd4c2..1bf314cadcfa 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -2,9 +2,6 @@ name: shared_preferences description: Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences -# 0.5.y+z is compatible with 1.0.0, if you land a breaking change bump -# the version to 2.0.0. -# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 version: 2.0.0-nullsafety flutter: diff --git a/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md b/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md index 2be9c8ca075a..1d287cf57401 100644 --- a/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Update version for consistency. + ## 0.0.4-nullsafety * Migrate to null-safety. diff --git a/packages/shared_preferences/shared_preferences_linux/pubspec.yaml b/packages/shared_preferences/shared_preferences_linux/pubspec.yaml index df4b5db23b7f..ee2288a79b4a 100644 --- a/packages/shared_preferences/shared_preferences_linux/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_linux/pubspec.yaml @@ -1,6 +1,6 @@ name: shared_preferences_linux description: Linux implementation of the shared_preferences plugin -version: 0.0.4-nullsafety +version: 2.0.0-nullsafety homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_linux flutter: diff --git a/packages/shared_preferences/shared_preferences_macos/CHANGELOG.md b/packages/shared_preferences/shared_preferences_macos/CHANGELOG.md index ec5c5b4bc502..002e1b7224ea 100644 --- a/packages/shared_preferences/shared_preferences_macos/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_macos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Update version to (semi-belatedly) meet 1.0-consistency promise. + ## 0.0.2-nullsafety * Update Dart SDK constraint for null safety. diff --git a/packages/shared_preferences/shared_preferences_macos/README.md b/packages/shared_preferences/shared_preferences_macos/README.md index c2949c9f5d33..170a8270c402 100644 --- a/packages/shared_preferences/shared_preferences_macos/README.md +++ b/packages/shared_preferences/shared_preferences_macos/README.md @@ -2,13 +2,6 @@ The macos implementation of [`shared_preferences`][1]. -**Please set your constraint to `shared_preferences_macos: '>=0.0.y+x <2.0.0'`** - -## Backward compatible 1.0.0 version is coming -The plugin has reached a stable API, we guarantee that version `1.0.0` will be backward compatible with `0.0.y+z`. -Please use `shared_preferences_macos: '>=0.0.y+x <2.0.0'` as your dependency constraint to allow a smoother ecosystem migration. -For more details see: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 - ## Usage ### Import the package diff --git a/packages/shared_preferences/shared_preferences_macos/pubspec.yaml b/packages/shared_preferences/shared_preferences_macos/pubspec.yaml index 912e2f648a26..754cf14f18f0 100644 --- a/packages/shared_preferences/shared_preferences_macos/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_macos/pubspec.yaml @@ -1,9 +1,6 @@ name: shared_preferences_macos description: macOS implementation of the shared_preferences plugin. -# 0.0.y+z is compatible with 1.0.0, if you land a breaking change bump -# the version to 2.0.0. -# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.0.2-nullsafety +version: 2.0.0-nullsafety homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_macos flutter: diff --git a/packages/shared_preferences/shared_preferences_web/CHANGELOG.md b/packages/shared_preferences/shared_preferences_web/CHANGELOG.md index 0194ef8ade37..2526ffe4447d 100644 --- a/packages/shared_preferences/shared_preferences_web/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_web/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Update version to (semi-belatedly) meet 1.0-consistency promise. + ## 0.2.0-nullsafety * Migrate to null-safety. diff --git a/packages/shared_preferences/shared_preferences_web/README.md b/packages/shared_preferences/shared_preferences_web/README.md index 2bb8a9316d86..8f9d22d86ef5 100644 --- a/packages/shared_preferences/shared_preferences_web/README.md +++ b/packages/shared_preferences/shared_preferences_web/README.md @@ -2,13 +2,6 @@ The web implementation of [`shared_preferences`][1]. -**Please set your constraint to `shared_preferences_web: '>=0.1.y+x <2.0.0'`** - -## Backward compatible 1.0.0 version is coming -The plugin has reached a stable API, we guarantee that version `1.0.0` will be backward compatible with `0.1.y+z`. -Please use `shared_preferences_web: '>=0.1.y+x <2.0.0'` as your dependency constraint to allow a smoother ecosystem migration. -For more details see: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 - ## Usage ### Import the package diff --git a/packages/shared_preferences/shared_preferences_web/pubspec.yaml b/packages/shared_preferences/shared_preferences_web/pubspec.yaml index 60892bcf277c..33970f4d857d 100644 --- a/packages/shared_preferences/shared_preferences_web/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_web/pubspec.yaml @@ -1,10 +1,7 @@ name: shared_preferences_web description: Web platform implementation of shared_preferences homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_web -# 0.1.y+z is compatible with 1.0.0, if you land a breaking change bump -# the version to 2.0.0. -# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.2.0-nullsafety +version: 2.0.0-nullsafety flutter: plugin: diff --git a/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md b/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md index 41119901f396..d6a5fb336fe5 100644 --- a/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md @@ -1,4 +1,8 @@ +## 2.0.0-nullsafety + +* Update version for consistency. + ## 0.0.3-nullsafety * Migrate to null-safety. diff --git a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml index e2cf3d03f00d..0b95c0c0d14a 100644 --- a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml @@ -1,7 +1,7 @@ name: shared_preferences_windows description: Windows implementation of shared_preferences homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_windows -version: 0.0.3-nullsafety +version: 2.0.0-nullsafety flutter: diff --git a/packages/url_launcher/url_launcher_linux/CHANGELOG.md b/packages/url_launcher/url_launcher_linux/CHANGELOG.md index 2d5a9a7d05af..bd3c15cb31fb 100644 --- a/packages/url_launcher/url_launcher_linux/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_linux/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Update version for consistency with other implementations. + ## 0.1.0-nullsafety.3 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. diff --git a/packages/url_launcher/url_launcher_linux/pubspec.yaml b/packages/url_launcher/url_launcher_linux/pubspec.yaml index c7aac06b88e5..37a074a57436 100644 --- a/packages/url_launcher/url_launcher_linux/pubspec.yaml +++ b/packages/url_launcher/url_launcher_linux/pubspec.yaml @@ -1,6 +1,6 @@ name: url_launcher_linux description: Linux implementation of the url_launcher plugin. -version: 0.1.0-nullsafety.3 +version: 2.0.0-nullsafety homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_linux flutter: diff --git a/packages/url_launcher/url_launcher_macos/CHANGELOG.md b/packages/url_launcher/url_launcher_macos/CHANGELOG.md index a5477a1b1501..5835c15f64e0 100644 --- a/packages/url_launcher/url_launcher_macos/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_macos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Update version to (semi-belatedly) meet 1.0-consistency promise. + # 0.1.0-nullsafety.2 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. @@ -58,4 +62,3 @@ # 0.0.1 * Initial open source release. - diff --git a/packages/url_launcher/url_launcher_macos/README.md b/packages/url_launcher/url_launcher_macos/README.md index e0c326ba86bf..28aa18817d6c 100644 --- a/packages/url_launcher/url_launcher_macos/README.md +++ b/packages/url_launcher/url_launcher_macos/README.md @@ -2,13 +2,6 @@ The macos implementation of [`url_launcher`][1]. -**Please set your constraint to `url_launcher_macos: '>=0.0.y+x <2.0.0'`** - -## Backward compatible 1.0.0 version is coming -The plugin has reached a stable API, we guarantee that version `1.0.0` will be backward compatible with `0.0.y+z`. -Please use `url_launcher_macos: '>=0.0.y+x <2.0.0'` as your dependency constraint to allow a smoother ecosystem migration. -For more details see: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 - ## Usage ### Import the package diff --git a/packages/url_launcher/url_launcher_macos/pubspec.yaml b/packages/url_launcher/url_launcher_macos/pubspec.yaml index be2dd2739298..bd918bfda24e 100644 --- a/packages/url_launcher/url_launcher_macos/pubspec.yaml +++ b/packages/url_launcher/url_launcher_macos/pubspec.yaml @@ -1,9 +1,6 @@ name: url_launcher_macos description: macOS implementation of the url_launcher plugin. -# 0.0.y+z is compatible with 1.0.0, if you land a breaking change bump -# the version to 2.0.0. -# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.1.0-nullsafety.2 +version: 2.0.0-nullsafety homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_macos flutter: diff --git a/packages/url_launcher/url_launcher_windows/CHANGELOG.md b/packages/url_launcher/url_launcher_windows/CHANGELOG.md index a1998c92e2e2..b57785524d08 100644 --- a/packages/url_launcher/url_launcher_windows/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_windows/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety + +* Update version to (semi-belatedly) meet 1.0-consistency promise. + ## 0.1.0-nullsafety.2 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. diff --git a/packages/url_launcher/url_launcher_windows/README.md b/packages/url_launcher/url_launcher_windows/README.md index fb5ad6700d26..4cebb7ed91fb 100644 --- a/packages/url_launcher/url_launcher_windows/README.md +++ b/packages/url_launcher/url_launcher_windows/README.md @@ -2,13 +2,6 @@ The Windows implementation of [`url_launcher`][1]. -## Backward compatible 1.0.0 version is coming -The plugin has reached a stable API, we guarantee that version `1.0.0` will be backward compatible with `0.0.y+z`. If you use -url_launcher_windows directly, rather than as an implementation detail -of `url_launcher`, please use `url_launcher_windows: '>=0.0.y+x <2.0.0'` -as your dependency constraint to allow a smoother ecosystem migration. -For more details see: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 - ## Usage ### Import the package diff --git a/packages/url_launcher/url_launcher_windows/pubspec.yaml b/packages/url_launcher/url_launcher_windows/pubspec.yaml index f7c96bf4a1bd..368c3f831c2a 100644 --- a/packages/url_launcher/url_launcher_windows/pubspec.yaml +++ b/packages/url_launcher/url_launcher_windows/pubspec.yaml @@ -1,9 +1,6 @@ name: url_launcher_windows description: Windows implementation of the url_launcher plugin. -# 0.0.y+z is compatible with 1.0.0, if you land a breaking change bump -# the version to 2.0.0. -# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.1.0-nullsafety.2 +version: 2.0.0-nullsafety homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_windows flutter: diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index be005280609c..47b8f601e711 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -1,9 +1,6 @@ name: video_player description: Flutter plugin for displaying inline video with other Flutter widgets on Android, iOS, and web. -# 0.10.y+z is compatible with 1.0.0, if you land a breaking change bump -# the version to 2.0.0. -# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 version: 2.0.0-nullsafety.9 homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player diff --git a/packages/video_player/video_player_web/README.md b/packages/video_player/video_player_web/README.md index 216b926bf26e..4f222be914eb 100644 --- a/packages/video_player/video_player_web/README.md +++ b/packages/video_player/video_player_web/README.md @@ -3,13 +3,6 @@ The web implementation of [`video_player`][1]. -**Please set your constraint to `video_player_web: '>=0.1.y+x <2.0.0'`** - -## Backward compatible 1.0.0 version is coming -The plugin has reached a stable API, we guarantee that version `1.0.0` will be backward compatible with `0.1.y+z`. -Please use `video_player_web: '>=0.1.y+x <2.0.0'` as your dependency constraint to allow a smoother ecosystem migration. -For more details see: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 - ## Usage This package is the endorsed implementation of `video_player` for the web platform since version `0.10.5`, so it gets automatically added to your application by depending on `video_player: ^0.10.5`. diff --git a/packages/video_player/video_player_web/pubspec.yaml b/packages/video_player/video_player_web/pubspec.yaml index 9333ac0ac6f0..157ab9f1cf2f 100644 --- a/packages/video_player/video_player_web/pubspec.yaml +++ b/packages/video_player/video_player_web/pubspec.yaml @@ -1,9 +1,6 @@ name: video_player_web description: Web platform implementation of video_player. homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player_web -# 0.1.y+z is compatible with 1.0.0, if you land a breaking change bump -# the version to 2.0.0. -# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 version: 2.0.0-nullsafety.2 flutter: From 10b40ddae933068914df0794953805d1a9283516 Mon Sep 17 00:00:00 2001 From: Ian Hickson Date: Sat, 13 Feb 2021 14:23:43 -0800 Subject: [PATCH 0131/1565] Update video_player_web to point to new video_player_interface (#3536) --- packages/video_player/video_player_web/CHANGELOG.md | 4 ++++ packages/video_player/video_player_web/pubspec.yaml | 6 ++---- .../video_player_web/test/video_player_web_test.dart | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/video_player/video_player_web/CHANGELOG.md b/packages/video_player/video_player_web/CHANGELOG.md index 2becf5b85e0a..7b3fc7871628 100644 --- a/packages/video_player/video_player_web/CHANGELOG.md +++ b/packages/video_player/video_player_web/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.3 + +* Updated to video_player_platform_interface 4.0. + ## 2.0.0-nullsafety.2 * Fixed an issue where `isBuffering` was not updating on Web. diff --git a/packages/video_player/video_player_web/pubspec.yaml b/packages/video_player/video_player_web/pubspec.yaml index 157ab9f1cf2f..df5f4564bf4a 100644 --- a/packages/video_player/video_player_web/pubspec.yaml +++ b/packages/video_player/video_player_web/pubspec.yaml @@ -1,7 +1,7 @@ name: video_player_web description: Web platform implementation of video_player. homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player_web -version: 2.0.0-nullsafety.2 +version: 2.0.0-nullsafety.3 flutter: plugin: @@ -16,13 +16,11 @@ dependencies: flutter_web_plugins: sdk: flutter meta: ^1.3.0-nullsafety.3 - video_player_platform_interface: ^3.0.0-nullsafety.3 + video_player_platform_interface: ^4.0.0-nullsafety.0 dev_dependencies: flutter_test: sdk: flutter - video_player: - path: ../video_player pedantic: ^1.10.0-nullsafety.1 environment: diff --git a/packages/video_player/video_player_web/test/video_player_web_test.dart b/packages/video_player/video_player_web/test/video_player_web_test.dart index c433d82027f0..94b788872b03 100644 --- a/packages/video_player/video_player_web/test/video_player_web_test.dart +++ b/packages/video_player/video_player_web/test/video_player_web_test.dart @@ -1,6 +1,7 @@ // Copyright 2019 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. + @TestOn('browser') import 'dart:async'; @@ -8,7 +9,6 @@ import 'dart:async'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:video_player/video_player.dart'; import 'package:video_player_platform_interface/video_player_platform_interface.dart'; import 'package:video_player_web/video_player_web.dart'; From b3369c3d11df1b33b901cba2106f23e2ab792aa5 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Sun, 14 Feb 2021 13:15:22 -0800 Subject: [PATCH 0132/1565] [google_maps_flutter] Migrate platform interface to null safety (#3539) Part of flutter/flutter#75236 Includes a significant refactor of the various overlay objects to remove a lot of identical code across the objects. --- .../CHANGELOG.md | 9 + .../method_channel_google_maps_flutter.dart | 288 +++++++----------- .../google_maps_flutter_platform.dart | 89 +++--- .../lib/src/types/bitmap.dart | 93 +++--- .../lib/src/types/camera.dart | 46 +-- .../lib/src/types/cap.dart | 12 +- .../lib/src/types/circle.dart | 60 ++-- .../lib/src/types/circle_updates.dart | 98 +----- .../lib/src/types/location.dart | 22 +- .../lib/src/types/maps_object.dart | 49 +++ .../lib/src/types/maps_object_updates.dart | 126 ++++++++ .../lib/src/types/marker.dart | 105 +++---- .../lib/src/types/marker_updates.dart | 98 +----- .../lib/src/types/pattern_item.dart | 10 +- .../lib/src/types/polygon.dart | 72 ++--- .../lib/src/types/polygon_updates.dart | 98 +----- .../lib/src/types/polyline.dart | 80 ++--- .../lib/src/types/polyline_updates.dart | 100 +----- .../lib/src/types/screen_coordinate.dart | 8 +- .../lib/src/types/tile.dart | 8 +- .../lib/src/types/tile_overlay.dart | 53 ++-- .../lib/src/types/tile_overlay_updates.dart | 114 +------ .../lib/src/types/tile_provider.dart | 2 +- .../lib/src/types/types.dart | 2 + .../lib/src/types/ui.dart | 18 +- .../lib/src/types/utils/circle.dart | 14 +- .../lib/src/types/utils/maps_object.dart | 18 ++ .../lib/src/types/utils/marker.dart | 14 +- .../lib/src/types/utils/polygon.dart | 14 +- .../lib/src/types/utils/polyline.dart | 17 +- .../lib/src/types/utils/tile_overlay.dart | 23 +- .../pubspec.yaml | 10 +- .../test/types/maps_object_test.dart | 45 +++ .../test/types/maps_object_updates_test.dart | 160 ++++++++++ .../test/types/test_maps_object.dart | 46 +++ .../test/types/tile_overlay_test.dart | 16 +- .../test/types/tile_overlay_updates_test.dart | 12 +- .../test/types/tile_test.dart | 21 +- script/nnbd_plugins.sh | 3 +- 39 files changed, 961 insertions(+), 1112 deletions(-) create mode 100644 packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart create mode 100644 packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object_updates.dart create mode 100644 packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/maps_object.dart create mode 100644 packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart create mode 100644 packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart create mode 100644 packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md index 4273f596cf39..c530c31e488d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md @@ -1,3 +1,12 @@ +## 2.0.0-nullsafety + +* Migrated to null-safety. +* BREAKING CHANGE: Removed deprecated APIs. +* BREAKING CHANGE: Many sets in APIs that used to treat null and empty set as + equivalent now require passing an empty set. +* BREAKING CHANGE: toJson now always returns an `Object`; the details of the + object type and structure should be treated as an implementation detail. + ## 1.2.0 * Add TileOverlay support. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart index 8b7af2cc3515..3d16127ab7a9 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart @@ -15,6 +15,26 @@ import 'package:stream_transform/stream_transform.dart'; import '../types/tile_overlay_updates.dart'; import '../types/utils/tile_overlay.dart'; +/// Error thrown when an unknown map ID is provided to a method channel API. +class UnknownMapIDError extends Error { + /// Creates an assertion error with the provided [mapId] and optional + /// [message]. + UnknownMapIDError(this.mapId, [this.message]); + + /// The unknown ID. + final int mapId; + + /// Message describing the assertion error. + final Object? message; + + String toString() { + if (message != null) { + return "Unknown map ID $mapId: ${Error.safeToString(message)}"; + } + return "Unknown map ID $mapId"; + } +} + /// An implementation of [GoogleMapsFlutterPlatform] that uses [MethodChannel] to communicate with the native code. /// /// The `google_maps_flutter` plugin code itself never talks to the native code directly. It delegates @@ -32,19 +52,20 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { /// Accesses the MethodChannel associated to the passed mapId. MethodChannel channel(int mapId) { - return _channels[mapId]; + MethodChannel? channel = _channels[mapId]; + if (channel == null) { + throw UnknownMapIDError(mapId); + } + return channel; } // Keep a collection of mapId to a map of TileOverlays. final Map> _tileOverlays = {}; - /// Initializes the platform interface with [id]. - /// - /// This method is called when the plugin is first initialized. @override Future init(int mapId) { - MethodChannel channel; - if (!_channels.containsKey(mapId)) { + MethodChannel? channel = _channels[mapId]; + if (channel == null) { channel = MethodChannel('plugins.flutter.io/google_maps_$mapId'); channel.setMethodCallHandler( (MethodCall call) => _handleMethodCall(call, mapId)); @@ -53,9 +74,8 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { return channel.invokeMethod('map#waitForMap'); } - /// Dispose of the native resources. @override - void dispose({int mapId}) { + void dispose({required int mapId}) { // Noop! } @@ -72,57 +92,57 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { _mapEventStreamController.stream.where((event) => event.mapId == mapId); @override - Stream onCameraMoveStarted({@required int mapId}) { + Stream onCameraMoveStarted({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onCameraMove({@required int mapId}) { + Stream onCameraMove({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onCameraIdle({@required int mapId}) { + Stream onCameraIdle({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onMarkerTap({@required int mapId}) { + Stream onMarkerTap({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onInfoWindowTap({@required int mapId}) { + Stream onInfoWindowTap({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onMarkerDragEnd({@required int mapId}) { + Stream onMarkerDragEnd({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onPolylineTap({@required int mapId}) { + Stream onPolylineTap({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onPolygonTap({@required int mapId}) { + Stream onPolygonTap({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onCircleTap({@required int mapId}) { + Stream onCircleTap({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onTap({@required int mapId}) { + Stream onTap({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onLongPress({@required int mapId}) { + Stream onLongPress({required int mapId}) { return _events(mapId).whereType(); } @@ -134,7 +154,7 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { case 'camera#onMove': _mapEventStreamController.add(CameraMoveEvent( mapId, - CameraPosition.fromMap(call.arguments['position']), + CameraPosition.fromMap(call.arguments['position'])!, )); break; case 'camera#onIdle': @@ -149,7 +169,7 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { case 'marker#onDragEnd': _mapEventStreamController.add(MarkerDragEndEvent( mapId, - LatLng.fromJson(call.arguments['position']), + LatLng.fromJson(call.arguments['position'])!, MarkerId(call.arguments['markerId']), )); break; @@ -180,26 +200,26 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { case 'map#onTap': _mapEventStreamController.add(MapTapEvent( mapId, - LatLng.fromJson(call.arguments['position']), + LatLng.fromJson(call.arguments['position'])!, )); break; case 'map#onLongPress': _mapEventStreamController.add(MapLongPressEvent( mapId, - LatLng.fromJson(call.arguments['position']), + LatLng.fromJson(call.arguments['position'])!, )); break; case 'tileOverlay#getTile': - final Map tileOverlaysForThisMap = + final Map? tileOverlaysForThisMap = _tileOverlays[mapId]; final String tileOverlayId = call.arguments['tileOverlayId']; - final TileOverlay tileOverlay = - tileOverlaysForThisMap[TileOverlayId(tileOverlayId)]; - Tile tile; - if (tileOverlay == null || tileOverlay.tileProvider == null) { + final TileOverlay? tileOverlay = + tileOverlaysForThisMap?[TileOverlayId(tileOverlayId)]; + TileProvider? tileProvider = tileOverlay?.tileProvider; + if (tileProvider == null) { return TileProvider.noTile.toJson(); } - tile = await tileOverlay.tileProvider.getTile( + final Tile tile = await tileProvider.getTile( call.arguments['x'], call.arguments['y'], call.arguments['zoom'], @@ -210,16 +230,10 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { } } - /// Updates configuration options of the map user interface. - /// - /// Change listeners are notified once the update has been made on the - /// platform side. - /// - /// The returned [Future] completes after listeners have been notified. @override Future updateMapOptions( Map optionsUpdate, { - @required int mapId, + required int mapId, }) { assert(optionsUpdate != null); return channel(mapId).invokeMethod( @@ -230,16 +244,10 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { ); } - /// Updates marker configuration. - /// - /// Change listeners are notified once the update has been made on the - /// platform side. - /// - /// The returned [Future] completes after listeners have been notified. @override Future updateMarkers( MarkerUpdates markerUpdates, { - @required int mapId, + required int mapId, }) { assert(markerUpdates != null); return channel(mapId).invokeMethod( @@ -248,16 +256,10 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { ); } - /// Updates polygon configuration. - /// - /// Change listeners are notified once the update has been made on the - /// platform side. - /// - /// The returned [Future] completes after listeners have been notified. @override Future updatePolygons( PolygonUpdates polygonUpdates, { - @required int mapId, + required int mapId, }) { assert(polygonUpdates != null); return channel(mapId).invokeMethod( @@ -266,16 +268,10 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { ); } - /// Updates polyline configuration. - /// - /// Change listeners are notified once the update has been made on the - /// platform side. - /// - /// The returned [Future] completes after listeners have been notified. @override Future updatePolylines( PolylineUpdates polylineUpdates, { - @required int mapId, + required int mapId, }) { assert(polylineUpdates != null); return channel(mapId).invokeMethod( @@ -284,16 +280,10 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { ); } - /// Updates circle configuration. - /// - /// Change listeners are notified once the update has been made on the - /// platform side. - /// - /// The returned [Future] completes after listeners have been notified. @override Future updateCircles( CircleUpdates circleUpdates, { - @required int mapId, + required int mapId, }) { assert(circleUpdates != null); return channel(mapId).invokeMethod( @@ -302,23 +292,16 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { ); } - /// Updates tile overlay configuration. - /// - /// Change listeners are notified once the update has been made on the - /// platform side. - /// - /// The returned [Future] completes after listeners have been notified. - /// - /// If `newTileOverlays` is null, all the [TileOverlays] are removed for the Map with `mapId`. @override Future updateTileOverlays({ - Set newTileOverlays, - @required int mapId, + required Set newTileOverlays, + required int mapId, }) { - final Map currentTileOverlays = + final Map? currentTileOverlays = _tileOverlays[mapId]; - Set previousSet = - currentTileOverlays != null ? currentTileOverlays.values.toSet() : null; + Set previousSet = currentTileOverlays != null + ? currentTileOverlays.values.toSet() + : {}; final TileOverlayUpdates updates = TileOverlayUpdates.from(previousSet, newTileOverlays); _tileOverlays[mapId] = keyTileOverlayId(newTileOverlays); @@ -328,203 +311,152 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { ); } - /// Clears the tile cache so that all tiles will be requested again from the - /// [TileProvider]. - /// - /// The current tiles from this tile overlay will also be - /// cleared from the map after calling this method. The Google Map SDK maintains a small - /// in-memory cache of tiles. If you want to cache tiles for longer, you - /// should implement an on-disk cache. @override Future clearTileCache( TileOverlayId tileOverlayId, { - @required int mapId, + required int mapId, }) { return channel(mapId) - .invokeMethod('tileOverlays#clearTileCache', { + .invokeMethod('tileOverlays#clearTileCache', { 'tileOverlayId': tileOverlayId.value, }); } - /// Starts an animated change of the map camera position. - /// - /// The returned [Future] completes after the change has been started on the - /// platform side. @override Future animateCamera( CameraUpdate cameraUpdate, { - @required int mapId, + required int mapId, }) { - return channel(mapId) - .invokeMethod('camera#animate', { + return channel(mapId).invokeMethod('camera#animate', { 'cameraUpdate': cameraUpdate.toJson(), }); } - /// Changes the map camera position. - /// - /// The returned [Future] completes after the change has been made on the - /// platform side. @override Future moveCamera( CameraUpdate cameraUpdate, { - @required int mapId, + required int mapId, }) { return channel(mapId).invokeMethod('camera#move', { 'cameraUpdate': cameraUpdate.toJson(), }); } - /// Sets the styling of the base map. - /// - /// Set to `null` to clear any previous custom styling. - /// - /// If problems were detected with the [mapStyle], including un-parsable - /// styling JSON, unrecognized feature type, unrecognized element type, or - /// invalid styler keys: [MapStyleException] is thrown and the current - /// style is left unchanged. - /// - /// The style string can be generated using [map style tool](https://mapstyle.withgoogle.com/). - /// Also, refer [iOS](https://developers.google.com/maps/documentation/ios-sdk/style-reference) - /// and [Android](https://developers.google.com/maps/documentation/android-sdk/style-reference) - /// style reference for more information regarding the supported styles. @override Future setMapStyle( - String mapStyle, { - @required int mapId, + String? mapStyle, { + required int mapId, }) async { - final List successAndError = await channel(mapId) - .invokeMethod>('map#setStyle', mapStyle); + final List successAndError = (await channel(mapId) + .invokeMethod>('map#setStyle', mapStyle))!; final bool success = successAndError[0]; if (!success) { throw MapStyleException(successAndError[1]); } } - /// Return the region that is visible in a map. @override Future getVisibleRegion({ - @required int mapId, + required int mapId, }) async { - final Map latLngBounds = await channel(mapId) - .invokeMapMethod('map#getVisibleRegion'); - final LatLng southwest = LatLng.fromJson(latLngBounds['southwest']); - final LatLng northeast = LatLng.fromJson(latLngBounds['northeast']); + final Map latLngBounds = (await channel(mapId) + .invokeMapMethod('map#getVisibleRegion'))!; + final LatLng southwest = LatLng.fromJson(latLngBounds['southwest'])!; + final LatLng northeast = LatLng.fromJson(latLngBounds['northeast'])!; return LatLngBounds(northeast: northeast, southwest: southwest); } - /// Return point [Map] of the [screenCoordinateInJson] in the current map view. - /// - /// A projection is used to translate between on screen location and geographic coordinates. - /// Screen location is in screen pixels (not display pixels) with respect to the top left corner - /// of the map, not necessarily of the whole screen. @override Future getScreenCoordinate( LatLng latLng, { - @required int mapId, + required int mapId, }) async { - final Map point = await channel(mapId) + final Map point = (await channel(mapId) .invokeMapMethod( - 'map#getScreenCoordinate', latLng.toJson()); + 'map#getScreenCoordinate', latLng.toJson()))!; - return ScreenCoordinate(x: point['x'], y: point['y']); + return ScreenCoordinate(x: point['x']!, y: point['y']!); } - /// Returns [LatLng] corresponding to the [ScreenCoordinate] in the current map view. - /// - /// Returned [LatLng] corresponds to a screen location. The screen location is specified in screen - /// pixels (not display pixels) relative to the top left of the map, not top left of the whole screen. @override Future getLatLng( ScreenCoordinate screenCoordinate, { - @required int mapId, + required int mapId, }) async { - final List latLng = await channel(mapId) + final List latLng = (await channel(mapId) .invokeMethod>( - 'map#getLatLng', screenCoordinate.toJson()); + 'map#getLatLng', screenCoordinate.toJson()))!; return LatLng(latLng[0], latLng[1]); } - /// Programmatically show the Info Window for a [Marker]. - /// - /// The `markerId` must match one of the markers on the map. - /// An invalid `markerId` triggers an "Invalid markerId" error. - /// - /// * See also: - /// * [hideMarkerInfoWindow] to hide the Info Window. - /// * [isMarkerInfoWindowShown] to check if the Info Window is showing. @override Future showMarkerInfoWindow( MarkerId markerId, { - @required int mapId, + required int mapId, }) { assert(markerId != null); return channel(mapId).invokeMethod( 'markers#showInfoWindow', {'markerId': markerId.value}); } - /// Programmatically hide the Info Window for a [Marker]. - /// - /// The `markerId` must match one of the markers on the map. - /// An invalid `markerId` triggers an "Invalid markerId" error. - /// - /// * See also: - /// * [showMarkerInfoWindow] to show the Info Window. - /// * [isMarkerInfoWindowShown] to check if the Info Window is showing. @override Future hideMarkerInfoWindow( MarkerId markerId, { - @required int mapId, + required int mapId, }) { assert(markerId != null); return channel(mapId).invokeMethod( 'markers#hideInfoWindow', {'markerId': markerId.value}); } - /// Returns `true` when the [InfoWindow] is showing, `false` otherwise. - /// - /// The `markerId` must match one of the markers on the map. - /// An invalid `markerId` triggers an "Invalid markerId" error. - /// - /// * See also: - /// * [showMarkerInfoWindow] to show the Info Window. - /// * [hideMarkerInfoWindow] to hide the Info Window. @override Future isMarkerInfoWindowShown( MarkerId markerId, { - @required int mapId, + required int mapId, }) { assert(markerId != null); return channel(mapId).invokeMethod('markers#isInfoWindowShown', - {'markerId': markerId.value}); + {'markerId': markerId.value}) as Future; } - /// Returns the current zoom level of the map @override Future getZoomLevel({ - @required int mapId, + required int mapId, }) { - return channel(mapId).invokeMethod('map#getZoomLevel'); + return channel(mapId).invokeMethod('map#getZoomLevel') + as Future; } - /// Returns the image bytes of the map @override - Future takeSnapshot({ - @required int mapId, + Future takeSnapshot({ + required int mapId, }) { return channel(mapId).invokeMethod('map#takeSnapshot'); } - /// This method builds the appropriate platform view where the map - /// can be rendered. - /// The `mapId` is passed as a parameter from the framework on the - /// `onPlatformViewCreated` callback. @override Widget buildView( - Map creationParams, - Set> gestureRecognizers, - PlatformViewCreatedCallback onPlatformViewCreated) { + int creationId, + PlatformViewCreatedCallback onPlatformViewCreated, { + required CameraPosition initialCameraPosition, + Set markers = const {}, + Set polygons = const {}, + Set polylines = const {}, + Set circles = const {}, + Set tileOverlays = const {}, + Set>? gestureRecognizers, + Map mapOptions = const {}, + }) { + final Map creationParams = { + 'initialCameraPosition': initialCameraPosition.toMap(), + 'options': mapOptions, + 'markersToAdd': serializeMarkerSet(markers), + 'polygonsToAdd': serializePolygonSet(polygons), + 'polylinesToAdd': serializePolylineSet(polylines), + 'circlesToAdd': serializeCircleSet(circles), + 'tileOverlaysToAdd': serializeTileOverlaySet(tileOverlays), + }; if (defaultTargetPlatform == TargetPlatform.android) { return AndroidView( viewType: 'plugins.flutter.io/google_maps', diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart index b9d3fecc0d0a..a363fc30f83c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart @@ -58,7 +58,7 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { /// The returned [Future] completes after listeners have been notified. Future updateMapOptions( Map optionsUpdate, { - @required int mapId, + required int mapId, }) { throw UnimplementedError('updateMapOptions() has not been implemented.'); } @@ -71,7 +71,7 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { /// The returned [Future] completes after listeners have been notified. Future updateMarkers( MarkerUpdates markerUpdates, { - @required int mapId, + required int mapId, }) { throw UnimplementedError('updateMarkers() has not been implemented.'); } @@ -84,7 +84,7 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { /// The returned [Future] completes after listeners have been notified. Future updatePolygons( PolygonUpdates polygonUpdates, { - @required int mapId, + required int mapId, }) { throw UnimplementedError('updatePolygons() has not been implemented.'); } @@ -97,7 +97,7 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { /// The returned [Future] completes after listeners have been notified. Future updatePolylines( PolylineUpdates polylineUpdates, { - @required int mapId, + required int mapId, }) { throw UnimplementedError('updatePolylines() has not been implemented.'); } @@ -110,7 +110,7 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { /// The returned [Future] completes after listeners have been notified. Future updateCircles( CircleUpdates circleUpdates, { - @required int mapId, + required int mapId, }) { throw UnimplementedError('updateCircles() has not been implemented.'); } @@ -122,8 +122,8 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { /// /// The returned [Future] completes after listeners have been notified. Future updateTileOverlays({ - Set newTileOverlays, - @required int mapId, + required Set newTileOverlays, + required int mapId, }) { throw UnimplementedError('updateTileOverlays() has not been implemented.'); } @@ -137,7 +137,7 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { /// should implement an on-disk cache. Future clearTileCache( TileOverlayId tileOverlayId, { - @required int mapId, + required int mapId, }) { throw UnimplementedError('clearTileCache() has not been implemented.'); } @@ -148,7 +148,7 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { /// platform side. Future animateCamera( CameraUpdate cameraUpdate, { - @required int mapId, + required int mapId, }) { throw UnimplementedError('animateCamera() has not been implemented.'); } @@ -159,7 +159,7 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { /// platform side. Future moveCamera( CameraUpdate cameraUpdate, { - @required int mapId, + required int mapId, }) { throw UnimplementedError('moveCamera() has not been implemented.'); } @@ -175,15 +175,15 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { /// /// The style string can be generated using [map style tool](https://mapstyle.withgoogle.com/). Future setMapStyle( - String mapStyle, { - @required int mapId, + String? mapStyle, { + required int mapId, }) { throw UnimplementedError('setMapStyle() has not been implemented.'); } /// Return the region that is visible in a map. Future getVisibleRegion({ - @required int mapId, + required int mapId, }) { throw UnimplementedError('getVisibleRegion() has not been implemented.'); } @@ -195,7 +195,7 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { /// of the map, not necessarily of the whole screen. Future getScreenCoordinate( LatLng latLng, { - @required int mapId, + required int mapId, }) { throw UnimplementedError('getScreenCoordinate() has not been implemented.'); } @@ -207,7 +207,7 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { /// of the map, not necessarily of the whole screen. Future getLatLng( ScreenCoordinate screenCoordinate, { - @required int mapId, + required int mapId, }) { throw UnimplementedError('getLatLng() has not been implemented.'); } @@ -222,7 +222,7 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { /// * [isMarkerInfoWindowShown] to check if the Info Window is showing. Future showMarkerInfoWindow( MarkerId markerId, { - @required int mapId, + required int mapId, }) { throw UnimplementedError( 'showMarkerInfoWindow() has not been implemented.'); @@ -238,7 +238,7 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { /// * [isMarkerInfoWindowShown] to check if the Info Window is showing. Future hideMarkerInfoWindow( MarkerId markerId, { - @required int mapId, + required int mapId, }) { throw UnimplementedError( 'hideMarkerInfoWindow() has not been implemented.'); @@ -254,21 +254,23 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { /// * [hideMarkerInfoWindow] to hide the Info Window. Future isMarkerInfoWindowShown( MarkerId markerId, { - @required int mapId, + required int mapId, }) { throw UnimplementedError('updateMapOptions() has not been implemented.'); } - /// Returns the current zoom level of the map + /// Returns the current zoom level of the map. Future getZoomLevel({ - @required int mapId, + required int mapId, }) { throw UnimplementedError('getZoomLevel() has not been implemented.'); } - /// Returns the image bytes of the map - Future takeSnapshot({ - @required int mapId, + /// Returns the image bytes of the map. + /// + /// Returns null if a snapshot cannot be created. + Future takeSnapshot({ + required int mapId, }) { throw UnimplementedError('takeSnapshot() has not been implemented.'); } @@ -277,70 +279,81 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { // into the plugin /// The Camera started moving. - Stream onCameraMoveStarted({@required int mapId}) { + Stream onCameraMoveStarted({required int mapId}) { throw UnimplementedError('onCameraMoveStarted() has not been implemented.'); } /// The Camera finished moving to a new [CameraPosition]. - Stream onCameraMove({@required int mapId}) { + Stream onCameraMove({required int mapId}) { throw UnimplementedError('onCameraMove() has not been implemented.'); } /// The Camera is now idle. - Stream onCameraIdle({@required int mapId}) { + Stream onCameraIdle({required int mapId}) { throw UnimplementedError('onCameraMove() has not been implemented.'); } /// A [Marker] has been tapped. - Stream onMarkerTap({@required int mapId}) { + Stream onMarkerTap({required int mapId}) { throw UnimplementedError('onMarkerTap() has not been implemented.'); } /// An [InfoWindow] has been tapped. - Stream onInfoWindowTap({@required int mapId}) { + Stream onInfoWindowTap({required int mapId}) { throw UnimplementedError('onInfoWindowTap() has not been implemented.'); } /// A [Marker] has been dragged to a different [LatLng] position. - Stream onMarkerDragEnd({@required int mapId}) { + Stream onMarkerDragEnd({required int mapId}) { throw UnimplementedError('onMarkerDragEnd() has not been implemented.'); } /// A [Polyline] has been tapped. - Stream onPolylineTap({@required int mapId}) { + Stream onPolylineTap({required int mapId}) { throw UnimplementedError('onPolylineTap() has not been implemented.'); } /// A [Polygon] has been tapped. - Stream onPolygonTap({@required int mapId}) { + Stream onPolygonTap({required int mapId}) { throw UnimplementedError('onPolygonTap() has not been implemented.'); } /// A [Circle] has been tapped. - Stream onCircleTap({@required int mapId}) { + Stream onCircleTap({required int mapId}) { throw UnimplementedError('onCircleTap() has not been implemented.'); } /// A Map has been tapped at a certain [LatLng]. - Stream onTap({@required int mapId}) { + Stream onTap({required int mapId}) { throw UnimplementedError('onTap() has not been implemented.'); } /// A Map has been long-pressed at a certain [LatLng]. - Stream onLongPress({@required int mapId}) { + Stream onLongPress({required int mapId}) { throw UnimplementedError('onLongPress() has not been implemented.'); } /// Dispose of whatever resources the `mapId` is holding on to. - void dispose({@required int mapId}) { + void dispose({required int mapId}) { throw UnimplementedError('dispose() has not been implemented.'); } /// Returns a widget displaying the map view Widget buildView( - Map creationParams, - Set> gestureRecognizers, - PlatformViewCreatedCallback onPlatformViewCreated) { + int creationId, + PlatformViewCreatedCallback onPlatformViewCreated, { + required CameraPosition initialCameraPosition, + Set markers = const {}, + Set polygons = const {}, + Set polylines = const {}, + Set circles = const {}, + Set tileOverlays = const {}, + Set>? gestureRecognizers = + const >{}, + // TODO: Replace with a structured type that's part of the interface. + // See https://github.com/flutter/flutter/issues/70330. + Map mapOptions = const {}, + }) { throw UnimplementedError('buildView() has not been implemented.'); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart index e10481e321f5..cc9887512d0e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart @@ -4,6 +4,7 @@ import 'dart:async' show Future; import 'dart:typed_data' show Uint8List; +import 'dart:ui' show Size; import 'package:flutter/material.dart' show ImageConfiguration, AssetImage, AssetBundleImageKey; @@ -61,28 +62,14 @@ class BitmapDescriptor { /// Creates a BitmapDescriptor that refers to the default marker image. static const BitmapDescriptor defaultMarker = - BitmapDescriptor._([_defaultMarker]); + BitmapDescriptor._([_defaultMarker]); /// Creates a BitmapDescriptor that refers to a colorization of the default /// marker image. For convenience, there is a predefined set of hue values. /// See e.g. [hueYellow]. static BitmapDescriptor defaultMarkerWithHue(double hue) { assert(0.0 <= hue && hue < 360.0); - return BitmapDescriptor._([_defaultMarker, hue]); - } - - /// Creates a BitmapDescriptor using the name of a bitmap image in the assets - /// directory. - /// - /// Use [fromAssetImage]. This method does not respect the screen dpi when - /// picking an asset image. - @Deprecated("Use fromAssetImage instead") - static BitmapDescriptor fromAsset(String assetName, {String package}) { - if (package == null) { - return BitmapDescriptor._([_fromAsset, assetName]); - } else { - return BitmapDescriptor._([_fromAsset, assetName, package]); - } + return BitmapDescriptor._([_defaultMarker, hue]); } /// Creates a [BitmapDescriptor] from an asset image. @@ -95,29 +82,31 @@ class BitmapDescriptor { static Future fromAssetImage( ImageConfiguration configuration, String assetName, { - AssetBundle bundle, - String package, + AssetBundle? bundle, + String? package, bool mipmaps = true, }) async { - if (!mipmaps && configuration.devicePixelRatio != null) { - return BitmapDescriptor._([ + double? devicePixelRatio = configuration.devicePixelRatio; + if (!mipmaps && devicePixelRatio != null) { + return BitmapDescriptor._([ _fromAssetImage, assetName, - configuration.devicePixelRatio, + devicePixelRatio, ]); } final AssetImage assetImage = AssetImage(assetName, package: package, bundle: bundle); final AssetBundleImageKey assetBundleImageKey = await assetImage.obtainKey(configuration); - return BitmapDescriptor._([ + final Size? size = configuration.size; + return BitmapDescriptor._([ _fromAssetImage, assetBundleImageKey.name, assetBundleImageKey.scale, - if (kIsWeb && configuration?.size != null) + if (kIsWeb && size != null) [ - configuration.size.width, - configuration.size.height, + size.width, + size.height, ], ]); } @@ -125,45 +114,47 @@ class BitmapDescriptor { /// Creates a BitmapDescriptor using an array of bytes that must be encoded /// as PNG. static BitmapDescriptor fromBytes(Uint8List byteData) { - return BitmapDescriptor._([_fromBytes, byteData]); + return BitmapDescriptor._([_fromBytes, byteData]); } /// The inverse of .toJson. // This is needed in Web to re-hydrate BitmapDescriptors that have been // transformed to JSON for transport. // TODO(https://github.com/flutter/flutter/issues/70330): Clean this up. - BitmapDescriptor.fromJson(dynamic json) : _json = json { - assert(_validTypes.contains(_json[0])); - switch (_json[0]) { + BitmapDescriptor.fromJson(Object json) : _json = json { + assert(_json is List); + final jsonList = json as List; + assert(_validTypes.contains(jsonList[0])); + switch (jsonList[0]) { case _defaultMarker: - assert(_json.length <= 2); - if (_json.length == 2) { - assert(_json[1] is num); - assert(0 <= _json[1] && _json[1] < 360); + assert(jsonList.length <= 2); + if (jsonList.length == 2) { + assert(jsonList[1] is num); + assert(0 <= jsonList[1] && jsonList[1] < 360); } break; case _fromBytes: - assert(_json.length == 2); - assert(_json[1] != null && _json[1] is List); - assert((_json[1] as List).isNotEmpty); + assert(jsonList.length == 2); + assert(jsonList[1] != null && jsonList[1] is List); + assert((jsonList[1] as List).isNotEmpty); break; case _fromAsset: - assert(_json.length <= 3); - assert(_json[1] != null && _json[1] is String); - assert((_json[1] as String).isNotEmpty); - if (_json.length == 3) { - assert(_json[2] != null && _json[2] is String); - assert((_json[2] as String).isNotEmpty); + assert(jsonList.length <= 3); + assert(jsonList[1] != null && jsonList[1] is String); + assert((jsonList[1] as String).isNotEmpty); + if (jsonList.length == 3) { + assert(jsonList[2] != null && jsonList[2] is String); + assert((jsonList[2] as String).isNotEmpty); } break; case _fromAssetImage: - assert(_json.length <= 4); - assert(_json[1] != null && _json[1] is String); - assert((_json[1] as String).isNotEmpty); - assert(_json[2] != null && _json[2] is double); - if (_json.length == 4) { - assert(_json[3] != null && _json[3] is List); - assert((_json[3] as List).length == 2); + assert(jsonList.length <= 4); + assert(jsonList[1] != null && jsonList[1] is String); + assert((jsonList[1] as String).isNotEmpty); + assert(jsonList[2] != null && jsonList[2] is double); + if (jsonList.length == 4) { + assert(jsonList[3] != null && jsonList[3] is List); + assert((jsonList[3] as List).length == 2); } break; default: @@ -171,8 +162,8 @@ class BitmapDescriptor { } } - final dynamic _json; + final Object _json; /// Convert the object to a Json format. - dynamic toJson() => _json; + Object toJson() => _json; } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart index 10ea1e98846a..bdb039572624 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart @@ -4,8 +4,6 @@ import 'dart:ui' show hashValues, Offset; -import 'package:meta/meta.dart' show required; - import 'types.dart'; /// The position of the map "camera", the view point from which the world is shown in the map view. @@ -19,7 +17,7 @@ class CameraPosition { /// null. const CameraPosition({ this.bearing = 0.0, - @required this.target, + required this.target, this.tilt = 0.0, this.zoom = 0.0, }) : assert(bearing != null), @@ -63,7 +61,7 @@ class CameraPosition { /// Serializes [CameraPosition]. /// /// Mainly for internal use when calling [CameraUpdate.newCameraPosition]. - dynamic toMap() => { + Object toMap() => { 'bearing': bearing, 'target': target.toJson(), 'tilt': tilt, @@ -73,23 +71,27 @@ class CameraPosition { /// Deserializes [CameraPosition] from a map. /// /// Mainly for internal use. - static CameraPosition fromMap(dynamic json) { - if (json == null) { + static CameraPosition? fromMap(Object? json) { + if (json == null || !(json is Map)) { + return null; + } + final LatLng? target = LatLng.fromJson(json['target']); + if (target == null) { return null; } return CameraPosition( bearing: json['bearing'], - target: LatLng.fromJson(json['target']), + target: target, tilt: json['tilt'], zoom: json['zoom'], ); } @override - bool operator ==(dynamic other) { + bool operator ==(Object other) { if (identical(this, other)) return true; if (runtimeType != other.runtimeType) return false; - final CameraPosition typedOther = other; + final CameraPosition typedOther = other as CameraPosition; return bearing == typedOther.bearing && target == typedOther.target && tilt == typedOther.tilt && @@ -112,14 +114,14 @@ class CameraUpdate { /// Returns a camera update that moves the camera to the specified position. static CameraUpdate newCameraPosition(CameraPosition cameraPosition) { return CameraUpdate._( - ['newCameraPosition', cameraPosition.toMap()], + ['newCameraPosition', cameraPosition.toMap()], ); } /// Returns a camera update that moves the camera target to the specified /// geographical location. static CameraUpdate newLatLng(LatLng latLng) { - return CameraUpdate._(['newLatLng', latLng.toJson()]); + return CameraUpdate._(['newLatLng', latLng.toJson()]); } /// Returns a camera update that transforms the camera so that the specified @@ -127,7 +129,7 @@ class CameraUpdate { /// possible zoom level. A non-zero [padding] insets the bounding box from the /// map view's edges. The camera's new tilt and bearing will both be 0.0. static CameraUpdate newLatLngBounds(LatLngBounds bounds, double padding) { - return CameraUpdate._([ + return CameraUpdate._([ 'newLatLngBounds', bounds.toJson(), padding, @@ -138,7 +140,7 @@ class CameraUpdate { /// geographical location and zoom level. static CameraUpdate newLatLngZoom(LatLng latLng, double zoom) { return CameraUpdate._( - ['newLatLngZoom', latLng.toJson(), zoom], + ['newLatLngZoom', latLng.toJson(), zoom], ); } @@ -150,18 +152,18 @@ class CameraUpdate { /// 75 to the south of the current location, measured in screen coordinates. static CameraUpdate scrollBy(double dx, double dy) { return CameraUpdate._( - ['scrollBy', dx, dy], + ['scrollBy', dx, dy], ); } /// Returns a camera update that modifies the camera zoom level by the /// specified amount. The optional [focus] is a screen point whose underlying /// geographical location should be invariant, if possible, by the movement. - static CameraUpdate zoomBy(double amount, [Offset focus]) { + static CameraUpdate zoomBy(double amount, [Offset? focus]) { if (focus == null) { - return CameraUpdate._(['zoomBy', amount]); + return CameraUpdate._(['zoomBy', amount]); } else { - return CameraUpdate._([ + return CameraUpdate._([ 'zoomBy', amount, [focus.dx, focus.dy], @@ -174,7 +176,7 @@ class CameraUpdate { /// /// Equivalent to the result of calling `zoomBy(1.0)`. static CameraUpdate zoomIn() { - return CameraUpdate._(['zoomIn']); + return CameraUpdate._(['zoomIn']); } /// Returns a camera update that zooms the camera out, bringing the camera @@ -182,16 +184,16 @@ class CameraUpdate { /// /// Equivalent to the result of calling `zoomBy(-1.0)`. static CameraUpdate zoomOut() { - return CameraUpdate._(['zoomOut']); + return CameraUpdate._(['zoomOut']); } /// Returns a camera update that sets the camera zoom level. static CameraUpdate zoomTo(double zoom) { - return CameraUpdate._(['zoomTo', zoom]); + return CameraUpdate._(['zoomTo', zoom]); } - final dynamic _json; + final Object _json; /// Converts this object to something serializable in JSON. - dynamic toJson() => _json; + Object toJson() => _json; } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart index 68bf14c36408..c88923a59404 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart @@ -17,16 +17,16 @@ class Cap { /// /// This is the default cap type at start and end vertices of Polylines with /// solid stroke pattern. - static const Cap buttCap = Cap._(['buttCap']); + static const Cap buttCap = Cap._(['buttCap']); /// Cap that is a semicircle with radius equal to half the stroke width, /// centered at the start or end vertex of a [Polyline] with solid stroke /// pattern. - static const Cap roundCap = Cap._(['roundCap']); + static const Cap roundCap = Cap._(['roundCap']); /// Cap that is squared off after extending half the stroke width beyond the /// start or end vertex of a [Polyline] with solid stroke pattern. - static const Cap squareCap = Cap._(['squareCap']); + static const Cap squareCap = Cap._(['squareCap']); /// Constructs a new CustomCap with a bitmap overlay centered at the start or /// end vertex of a [Polyline], orientated according to the direction of the line's @@ -45,11 +45,11 @@ class Cap { }) { assert(bitmapDescriptor != null); assert(refWidth > 0.0); - return Cap._(['customCap', bitmapDescriptor.toJson(), refWidth]); + return Cap._(['customCap', bitmapDescriptor.toJson(), refWidth]); } - final dynamic _json; + final Object _json; /// Converts this object to something serializable in JSON. - dynamic toJson() => _json; + Object toJson() => _json; } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart index d1418a4c30b1..e3198dfd6512 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart @@ -4,7 +4,7 @@ import 'package:flutter/foundation.dart' show VoidCallback; import 'package:flutter/material.dart' show Color, Colors; -import 'package:meta/meta.dart' show immutable, required; +import 'package:meta/meta.dart' show immutable; import 'types.dart'; @@ -12,36 +12,17 @@ import 'types.dart'; /// /// This does not have to be globally unique, only unique among the list. @immutable -class CircleId { +class CircleId extends MapsObjectId { /// Creates an immutable identifier for a [Circle]. - CircleId(this.value) : assert(value != null); - - /// value of the [CircleId]. - final String value; - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - if (other.runtimeType != runtimeType) return false; - final CircleId typedOther = other; - return value == typedOther.value; - } - - @override - int get hashCode => value.hashCode; - - @override - String toString() { - return 'CircleId{value: $value}'; - } + CircleId(String value) : super(value); } /// Draws a circle on the map. @immutable -class Circle { +class Circle implements MapsObject { /// Creates an immutable representation of a [Circle] to draw on [GoogleMap]. const Circle({ - @required this.circleId, + required this.circleId, this.consumeTapEvents = false, this.fillColor = Colors.transparent, this.center = const LatLng(0.0, 0.0), @@ -56,6 +37,9 @@ class Circle { /// Uniquely identifies a [Circle]. final CircleId circleId; + @override + CircleId get mapsId => circleId; + /// True if the [Circle] consumes tap events. /// /// If this is false, [onTap] callback will not be triggered. @@ -91,20 +75,20 @@ class Circle { final int zIndex; /// Callbacks to receive tap events for circle placed on this map. - final VoidCallback onTap; + final VoidCallback? onTap; /// Creates a new [Circle] object whose values are the same as this instance, /// unless overwritten by the specified parameters. Circle copyWith({ - bool consumeTapEventsParam, - Color fillColorParam, - LatLng centerParam, - double radiusParam, - Color strokeColorParam, - int strokeWidthParam, - bool visibleParam, - int zIndexParam, - VoidCallback onTapParam, + bool? consumeTapEventsParam, + Color? fillColorParam, + LatLng? centerParam, + double? radiusParam, + Color? strokeColorParam, + int? strokeWidthParam, + bool? visibleParam, + int? zIndexParam, + VoidCallback? onTapParam, }) { return Circle( circleId: circleId, @@ -124,10 +108,10 @@ class Circle { Circle clone() => copyWith(); /// Converts this object to something serializable in JSON. - dynamic toJson() { - final Map json = {}; + Object toJson() { + final Map json = {}; - void addIfPresent(String fieldName, dynamic value) { + void addIfPresent(String fieldName, Object? value) { if (value != null) { json[fieldName] = value; } @@ -150,7 +134,7 @@ class Circle { bool operator ==(Object other) { if (identical(this, other)) return true; if (other.runtimeType != runtimeType) return false; - final Circle typedOther = other; + final Circle typedOther = other as Circle; return circleId == typedOther.circleId && consumeTapEvents == typedOther.consumeTapEvents && fillColor == typedOther.fillColor && diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle_updates.dart index 6f494423a38f..a0b064b7be2a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle_updates.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle_updates.dart @@ -2,109 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' show hashValues; - -import 'package:flutter/foundation.dart' show setEquals; - import 'types.dart'; -import 'utils/circle.dart'; /// [Circle] update events to be applied to the [GoogleMap]. /// /// Used in [GoogleMapController] when the map is updated. // (Do not re-export) -class CircleUpdates { +class CircleUpdates extends MapsObjectUpdates { /// Computes [CircleUpdates] given previous and current [Circle]s. - CircleUpdates.from(Set previous, Set current) { - if (previous == null) { - previous = Set.identity(); - } - - if (current == null) { - current = Set.identity(); - } - - final Map previousCircles = keyByCircleId(previous); - final Map currentCircles = keyByCircleId(current); - - final Set prevCircleIds = previousCircles.keys.toSet(); - final Set currentCircleIds = currentCircles.keys.toSet(); - - Circle idToCurrentCircle(CircleId id) { - return currentCircles[id]; - } - - final Set _circleIdsToRemove = - prevCircleIds.difference(currentCircleIds); - - final Set _circlesToAdd = currentCircleIds - .difference(prevCircleIds) - .map(idToCurrentCircle) - .toSet(); - - /// Returns `true` if [current] is not equals to previous one with the - /// same id. - bool hasChanged(Circle current) { - final Circle previous = previousCircles[current.circleId]; - return current != previous; - } - - final Set _circlesToChange = currentCircleIds - .intersection(prevCircleIds) - .map(idToCurrentCircle) - .where(hasChanged) - .toSet(); - - circlesToAdd = _circlesToAdd; - circleIdsToRemove = _circleIdsToRemove; - circlesToChange = _circlesToChange; - } + CircleUpdates.from(Set previous, Set current) + : super.from(previous, current, objectName: 'circle'); /// Set of Circles to be added in this update. - Set circlesToAdd; + Set get circlesToAdd => objectsToAdd; /// Set of CircleIds to be removed in this update. - Set circleIdsToRemove; + Set get circleIdsToRemove => objectIdsToRemove.cast(); /// Set of Circles to be changed in this update. - Set circlesToChange; - - /// Converts this object to something serializable in JSON. - Map toJson() { - final Map updateMap = {}; - - void addIfNonNull(String fieldName, dynamic value) { - if (value != null) { - updateMap[fieldName] = value; - } - } - - addIfNonNull('circlesToAdd', serializeCircleSet(circlesToAdd)); - addIfNonNull('circlesToChange', serializeCircleSet(circlesToChange)); - addIfNonNull('circleIdsToRemove', - circleIdsToRemove.map((CircleId m) => m.value).toList()); - - return updateMap; - } - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - if (other.runtimeType != runtimeType) return false; - final CircleUpdates typedOther = other; - return setEquals(circlesToAdd, typedOther.circlesToAdd) && - setEquals(circleIdsToRemove, typedOther.circleIdsToRemove) && - setEquals(circlesToChange, typedOther.circlesToChange); - } - - @override - int get hashCode => - hashValues(circlesToAdd, circleIdsToRemove, circlesToChange); - - @override - String toString() { - return '_CircleUpdates{circlesToAdd: $circlesToAdd, ' - 'circleIdsToRemove: $circleIdsToRemove, ' - 'circlesToChange: $circlesToChange}'; - } + Set get circlesToChange => objectsToChange; } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/location.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/location.dart index 6b76a6d496ac..a719f0bc741f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/location.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/location.dart @@ -29,16 +29,18 @@ class LatLng { final double longitude; /// Converts this object to something serializable in JSON. - dynamic toJson() { + Object toJson() { return [latitude, longitude]; } /// Initialize a LatLng from an \[lat, lng\] array. - static LatLng fromJson(dynamic json) { + static LatLng? fromJson(Object? json) { if (json == null) { return null; } - return LatLng(json[0], json[1]); + assert(json is List && json.length == 2); + final list = json as List; + return LatLng(list[0], list[1]); } @override @@ -66,7 +68,7 @@ class LatLngBounds { /// /// The latitude of the southwest corner cannot be larger than the /// latitude of the northeast corner. - LatLngBounds({@required this.southwest, @required this.northeast}) + LatLngBounds({required this.southwest, required this.northeast}) : assert(southwest != null), assert(northeast != null), assert(southwest.latitude <= northeast.latitude); @@ -78,8 +80,8 @@ class LatLngBounds { final LatLng northeast; /// Converts this object to something serializable in JSON. - dynamic toJson() { - return [southwest.toJson(), northeast.toJson()]; + Object toJson() { + return [southwest.toJson(), northeast.toJson()]; } /// Returns whether this rectangle contains the given [LatLng]. @@ -102,13 +104,15 @@ class LatLngBounds { /// Converts a list to [LatLngBounds]. @visibleForTesting - static LatLngBounds fromList(dynamic json) { + static LatLngBounds? fromList(Object? json) { if (json == null) { return null; } + assert(json is List && json.length == 2); + final list = json as List; return LatLngBounds( - southwest: LatLng.fromJson(json[0]), - northeast: LatLng.fromJson(json[1]), + southwest: LatLng.fromJson(list[0])!, + northeast: LatLng.fromJson(list[1])!, ); } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart new file mode 100644 index 000000000000..545d46272215 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart @@ -0,0 +1,49 @@ +// Copyright 2019 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. + +import 'package:flutter/foundation.dart' show objectRuntimeType; +import 'package:meta/meta.dart' show immutable; + +/// Uniquely identifies object an among [GoogleMap] collections of a specific +/// type. +/// +/// This does not have to be globally unique, only unique among the collection. +@immutable +class MapsObjectId { + /// Creates an immutable object representing a [T] among [GoogleMap] Ts. + /// + /// An [AssertionError] will be thrown if [value] is null. + MapsObjectId(this.value) : assert(value != null); + + /// The value of the id. + final String value; + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + if (other.runtimeType != runtimeType) return false; + final MapsObjectId typedOther = other as MapsObjectId; + return value == typedOther.value; + } + + @override + int get hashCode => value.hashCode; + + @override + String toString() { + return '${objectRuntimeType(this, 'MapsObjectId')}($value)'; + } +} + +/// A common interface for maps types. +abstract class MapsObject { + /// A identifier for this object. + MapsObjectId get mapsId; + + /// Returns a duplicate of this object. + T clone(); + + /// Converts this object to something serializable in JSON. + Object toJson(); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object_updates.dart new file mode 100644 index 000000000000..01cf967f54e3 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object_updates.dart @@ -0,0 +1,126 @@ +// Copyright 2018 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. + +import 'dart:ui' show hashValues, hashList; + +import 'package:flutter/foundation.dart' show objectRuntimeType, setEquals; + +import 'maps_object.dart'; +import 'utils/maps_object.dart'; + +/// Update specification for a set of objects. +class MapsObjectUpdates { + /// Computes updates given previous and current object sets. + /// + /// [objectName] is the prefix to use when serializing the updates into a JSON + /// dictionary. E.g., 'circle' will give 'circlesToAdd', 'circlesToUpdate', + /// 'circleIdsToRemove'. + MapsObjectUpdates.from( + Set previous, + Set current, { + required this.objectName, + }) { + final Map, T> previousObjects = keyByMapsObjectId(previous); + final Map, T> currentObjects = keyByMapsObjectId(current); + + final Set> previousObjectIds = previousObjects.keys.toSet(); + final Set> currentObjectIds = currentObjects.keys.toSet(); + + /// Maps an ID back to a [T] in [currentObjects]. + /// + /// It is a programming error to call this with an ID that is not guaranteed + /// to be in [currentObjects]. + T _idToCurrentObject(MapsObjectId id) { + return currentObjects[id]!; + } + + _objectIdsToRemove = previousObjectIds.difference(currentObjectIds); + + _objectsToAdd = currentObjectIds + .difference(previousObjectIds) + .map(_idToCurrentObject) + .toSet(); + + // Returns `true` if [current] is not equals to previous one with the + // same id. + bool hasChanged(T current) { + final T? previous = previousObjects[current.mapsId as MapsObjectId]; + return current != previous; + } + + _objectsToChange = currentObjectIds + .intersection(previousObjectIds) + .map(_idToCurrentObject) + .where(hasChanged) + .toSet(); + } + + /// The name of the objects being updated, for use in serialization. + final String objectName; + + /// Set of objects to be added in this update. + Set get objectsToAdd { + return _objectsToAdd; + } + + late Set _objectsToAdd; + + /// Set of objects to be removed in this update. + Set> get objectIdsToRemove { + return _objectIdsToRemove; + } + + late Set> _objectIdsToRemove; + + /// Set of objects to be changed in this update. + Set get objectsToChange { + return _objectsToChange; + } + + late Set _objectsToChange; + + /// Converts this object to JSON. + Object toJson() { + final Map updateMap = {}; + + void addIfNonNull(String fieldName, Object? value) { + if (value != null) { + updateMap[fieldName] = value; + } + } + + addIfNonNull('${objectName}sToAdd', serializeMapsObjectSet(_objectsToAdd)); + addIfNonNull( + '${objectName}sToChange', serializeMapsObjectSet(_objectsToChange)); + addIfNonNull( + '${objectName}IdsToRemove', + _objectIdsToRemove + .map((MapsObjectId m) => m.value) + .toList()); + + return updateMap; + } + + @override + bool operator ==(Object other) { + if (other.runtimeType != runtimeType) { + return false; + } + return other is MapsObjectUpdates && + setEquals(_objectsToAdd, other._objectsToAdd) && + setEquals(_objectIdsToRemove, other._objectIdsToRemove) && + setEquals(_objectsToChange, other._objectsToChange); + } + + @override + int get hashCode => hashValues(hashList(_objectsToAdd), + hashList(_objectIdsToRemove), hashList(_objectsToChange)); + + @override + String toString() { + return '${objectRuntimeType(this, 'MapsObjectUpdates')}(add: $objectsToAdd, ' + 'remove: $objectIdsToRemove, ' + 'change: $objectsToChange)'; + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart index 9b57f9676334..15351d58168b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart @@ -5,15 +5,12 @@ import 'dart:ui' show hashValues, Offset; import 'package:flutter/foundation.dart' show ValueChanged, VoidCallback; -import 'package:meta/meta.dart' show immutable, required; +import 'package:meta/meta.dart' show immutable; import 'types.dart'; -dynamic _offsetToJson(Offset offset) { - if (offset == null) { - return null; - } - return [offset.dx, offset.dy]; +Object _offsetToJson(Offset offset) { + return [offset.dx, offset.dy]; } /// Text labels for a [Marker] info window. @@ -32,12 +29,12 @@ class InfoWindow { /// Text displayed in an info window when the user taps the marker. /// /// A null value means no title. - final String title; + final String? title; /// Additional text displayed below the [title]. /// /// A null value means no additional text. - final String snippet; + final String? snippet; /// The icon image point that will be the anchor of the info window when /// displayed. @@ -48,15 +45,15 @@ class InfoWindow { final Offset anchor; /// onTap callback for this [InfoWindow]. - final VoidCallback onTap; + final VoidCallback? onTap; /// Creates a new [InfoWindow] object whose values are the same as this instance, /// unless overwritten by the specified parameters. InfoWindow copyWith({ - String titleParam, - String snippetParam, - Offset anchorParam, - VoidCallback onTapParam, + String? titleParam, + String? snippetParam, + Offset? anchorParam, + VoidCallback? onTapParam, }) { return InfoWindow( title: titleParam ?? title, @@ -66,10 +63,10 @@ class InfoWindow { ); } - dynamic _toJson() { - final Map json = {}; + Object _toJson() { + final Map json = {}; - void addIfPresent(String fieldName, dynamic value) { + void addIfPresent(String fieldName, Object? value) { if (value != null) { json[fieldName] = value; } @@ -86,7 +83,7 @@ class InfoWindow { bool operator ==(Object other) { if (identical(this, other)) return true; if (other.runtimeType != runtimeType) return false; - final InfoWindow typedOther = other; + final InfoWindow typedOther = other as InfoWindow; return title == typedOther.title && snippet == typedOther.snippet && anchor == typedOther.anchor; @@ -105,28 +102,9 @@ class InfoWindow { /// /// This does not have to be globally unique, only unique among the list. @immutable -class MarkerId { +class MarkerId extends MapsObjectId { /// Creates an immutable identifier for a [Marker]. - MarkerId(this.value) : assert(value != null); - - /// value of the [MarkerId]. - final String value; - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - if (other.runtimeType != runtimeType) return false; - final MarkerId typedOther = other; - return value == typedOther.value; - } - - @override - int get hashCode => value.hashCode; - - @override - String toString() { - return 'MarkerId{value: $value}'; - } + MarkerId(String value) : super(value); } /// Marks a geographical location on the map. @@ -135,7 +113,7 @@ class MarkerId { /// the map's surface; that is, it will not necessarily change orientation /// due to map rotations, tilting, or zooming. @immutable -class Marker { +class Marker implements MapsObject { /// Creates a set of marker configuration options. /// /// Default marker options. @@ -156,7 +134,7 @@ class Marker { /// * reports [onTap] events /// * reports [onDragEnd] events const Marker({ - @required this.markerId, + required this.markerId, this.alpha = 1.0, this.anchor = const Offset(0.5, 1.0), this.consumeTapEvents = false, @@ -175,6 +153,9 @@ class Marker { /// Uniquely identifies a [Marker]. final MarkerId markerId; + @override + MarkerId get mapsId => markerId; + /// The opacity of the marker, between 0.0 and 1.0 inclusive. /// /// 0.0 means fully transparent, 1.0 means fully opaque. @@ -224,27 +205,27 @@ class Marker { final double zIndex; /// Callbacks to receive tap events for markers placed on this map. - final VoidCallback onTap; + final VoidCallback? onTap; /// Signature reporting the new [LatLng] at the end of a drag event. - final ValueChanged onDragEnd; + final ValueChanged? onDragEnd; /// Creates a new [Marker] object whose values are the same as this instance, /// unless overwritten by the specified parameters. Marker copyWith({ - double alphaParam, - Offset anchorParam, - bool consumeTapEventsParam, - bool draggableParam, - bool flatParam, - BitmapDescriptor iconParam, - InfoWindow infoWindowParam, - LatLng positionParam, - double rotationParam, - bool visibleParam, - double zIndexParam, - VoidCallback onTapParam, - ValueChanged onDragEndParam, + double? alphaParam, + Offset? anchorParam, + bool? consumeTapEventsParam, + bool? draggableParam, + bool? flatParam, + BitmapDescriptor? iconParam, + InfoWindow? infoWindowParam, + LatLng? positionParam, + double? rotationParam, + bool? visibleParam, + double? zIndexParam, + VoidCallback? onTapParam, + ValueChanged? onDragEndParam, }) { return Marker( markerId: markerId, @@ -268,10 +249,10 @@ class Marker { Marker clone() => copyWith(); /// Converts this object to something serializable in JSON. - Map toJson() { - final Map json = {}; + Object toJson() { + final Map json = {}; - void addIfPresent(String fieldName, dynamic value) { + void addIfPresent(String fieldName, Object? value) { if (value != null) { json[fieldName] = value; } @@ -283,9 +264,9 @@ class Marker { addIfPresent('consumeTapEvents', consumeTapEvents); addIfPresent('draggable', draggable); addIfPresent('flat', flat); - addIfPresent('icon', icon?.toJson()); - addIfPresent('infoWindow', infoWindow?._toJson()); - addIfPresent('position', position?.toJson()); + addIfPresent('icon', icon.toJson()); + addIfPresent('infoWindow', infoWindow._toJson()); + addIfPresent('position', position.toJson()); addIfPresent('rotation', rotation); addIfPresent('visible', visible); addIfPresent('zIndex', zIndex); @@ -296,7 +277,7 @@ class Marker { bool operator ==(Object other) { if (identical(this, other)) return true; if (other.runtimeType != runtimeType) return false; - final Marker typedOther = other; + final Marker typedOther = other as Marker; return markerId == typedOther.markerId && alpha == typedOther.alpha && anchor == typedOther.anchor && diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker_updates.dart index bb6ea8813ea3..9c96ab63af18 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker_updates.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker_updates.dart @@ -2,109 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' show hashValues; - -import 'package:flutter/foundation.dart' show setEquals; - import 'types.dart'; -import 'utils/marker.dart'; /// [Marker] update events to be applied to the [GoogleMap]. /// /// Used in [GoogleMapController] when the map is updated. // (Do not re-export) -class MarkerUpdates { +class MarkerUpdates extends MapsObjectUpdates { /// Computes [MarkerUpdates] given previous and current [Marker]s. - MarkerUpdates.from(Set previous, Set current) { - if (previous == null) { - previous = Set.identity(); - } - - if (current == null) { - current = Set.identity(); - } - - final Map previousMarkers = keyByMarkerId(previous); - final Map currentMarkers = keyByMarkerId(current); - - final Set prevMarkerIds = previousMarkers.keys.toSet(); - final Set currentMarkerIds = currentMarkers.keys.toSet(); - - Marker idToCurrentMarker(MarkerId id) { - return currentMarkers[id]; - } - - final Set _markerIdsToRemove = - prevMarkerIds.difference(currentMarkerIds); - - final Set _markersToAdd = currentMarkerIds - .difference(prevMarkerIds) - .map(idToCurrentMarker) - .toSet(); - - /// Returns `true` if [current] is not equals to previous one with the - /// same id. - bool hasChanged(Marker current) { - final Marker previous = previousMarkers[current.markerId]; - return current != previous; - } - - final Set _markersToChange = currentMarkerIds - .intersection(prevMarkerIds) - .map(idToCurrentMarker) - .where(hasChanged) - .toSet(); - - markersToAdd = _markersToAdd; - markerIdsToRemove = _markerIdsToRemove; - markersToChange = _markersToChange; - } + MarkerUpdates.from(Set previous, Set current) + : super.from(previous, current, objectName: 'marker'); /// Set of Markers to be added in this update. - Set markersToAdd; + Set get markersToAdd => objectsToAdd; /// Set of MarkerIds to be removed in this update. - Set markerIdsToRemove; + Set get markerIdsToRemove => objectIdsToRemove.cast(); /// Set of Markers to be changed in this update. - Set markersToChange; - - /// Converts this object to something serializable in JSON. - Map toJson() { - final Map updateMap = {}; - - void addIfNonNull(String fieldName, dynamic value) { - if (value != null) { - updateMap[fieldName] = value; - } - } - - addIfNonNull('markersToAdd', serializeMarkerSet(markersToAdd)); - addIfNonNull('markersToChange', serializeMarkerSet(markersToChange)); - addIfNonNull('markerIdsToRemove', - markerIdsToRemove.map((MarkerId m) => m.value).toList()); - - return updateMap; - } - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - if (other.runtimeType != runtimeType) return false; - final MarkerUpdates typedOther = other; - return setEquals(markersToAdd, typedOther.markersToAdd) && - setEquals(markerIdsToRemove, typedOther.markerIdsToRemove) && - setEquals(markersToChange, typedOther.markersToChange); - } - - @override - int get hashCode => - hashValues(markersToAdd, markerIdsToRemove, markersToChange); - - @override - String toString() { - return '_MarkerUpdates{markersToAdd: $markersToAdd, ' - 'markerIdsToRemove: $markerIdsToRemove, ' - 'markersToChange: $markersToChange}'; - } + Set get markersToChange => objectsToChange; } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/pattern_item.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/pattern_item.dart index 28c7ce9d33dd..f1cd7f4cb8eb 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/pattern_item.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/pattern_item.dart @@ -10,14 +10,14 @@ class PatternItem { const PatternItem._(this._json); /// A dot used in the stroke pattern for a [Polyline]. - static const PatternItem dot = PatternItem._(['dot']); + static const PatternItem dot = PatternItem._(['dot']); /// A dash used in the stroke pattern for a [Polyline]. /// /// [length] has to be non-negative. static PatternItem dash(double length) { assert(length >= 0.0); - return PatternItem._(['dash', length]); + return PatternItem._(['dash', length]); } /// A gap used in the stroke pattern for a [Polyline]. @@ -25,11 +25,11 @@ class PatternItem { /// [length] has to be non-negative. static PatternItem gap(double length) { assert(length >= 0.0); - return PatternItem._(['gap', length]); + return PatternItem._(['gap', length]); } - final dynamic _json; + final Object _json; /// Converts this object to something serializable in JSON. - dynamic toJson() => _json; + Object toJson() => _json; } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart index 96b39157418d..4e5e9bf13d84 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart @@ -5,7 +5,7 @@ import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart' show listEquals, VoidCallback; import 'package:flutter/material.dart' show Color, Colors; -import 'package:meta/meta.dart' show immutable, required; +import 'package:meta/meta.dart' show immutable; import 'types.dart'; @@ -13,36 +13,17 @@ import 'types.dart'; /// /// This does not have to be globally unique, only unique among the list. @immutable -class PolygonId { +class PolygonId extends MapsObjectId { /// Creates an immutable identifier for a [Polygon]. - PolygonId(this.value) : assert(value != null); - - /// value of the [PolygonId]. - final String value; - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - if (other.runtimeType != runtimeType) return false; - final PolygonId typedOther = other; - return value == typedOther.value; - } - - @override - int get hashCode => value.hashCode; - - @override - String toString() { - return 'PolygonId{value: $value}'; - } + PolygonId(String value) : super(value); } /// Draws a polygon through geographical locations on the map. @immutable -class Polygon { +class Polygon implements MapsObject { /// Creates an immutable representation of a polygon through geographical locations on the map. const Polygon({ - @required this.polygonId, + required this.polygonId, this.consumeTapEvents = false, this.fillColor = Colors.black, this.geodesic = false, @@ -58,6 +39,9 @@ class Polygon { /// Uniquely identifies a [Polygon]. final PolygonId polygonId; + @override + PolygonId get mapsId => polygonId; + /// True if the [Polygon] consumes tap events. /// /// If this is false, [onTap] callback will not be triggered. @@ -107,21 +91,21 @@ class Polygon { final int zIndex; /// Callbacks to receive tap events for polygon placed on this map. - final VoidCallback onTap; + final VoidCallback? onTap; /// Creates a new [Polygon] object whose values are the same as this instance, /// unless overwritten by the specified parameters. Polygon copyWith({ - bool consumeTapEventsParam, - Color fillColorParam, - bool geodesicParam, - List pointsParam, - List> holesParam, - Color strokeColorParam, - int strokeWidthParam, - bool visibleParam, - int zIndexParam, - VoidCallback onTapParam, + bool? consumeTapEventsParam, + Color? fillColorParam, + bool? geodesicParam, + List? pointsParam, + List>? holesParam, + Color? strokeColorParam, + int? strokeWidthParam, + bool? visibleParam, + int? zIndexParam, + VoidCallback? onTapParam, }) { return Polygon( polygonId: polygonId, @@ -144,10 +128,10 @@ class Polygon { } /// Converts this object to something serializable in JSON. - dynamic toJson() { - final Map json = {}; + Object toJson() { + final Map json = {}; - void addIfPresent(String fieldName, dynamic value) { + void addIfPresent(String fieldName, Object? value) { if (value != null) { json[fieldName] = value; } @@ -177,7 +161,7 @@ class Polygon { bool operator ==(Object other) { if (identical(this, other)) return true; if (other.runtimeType != runtimeType) return false; - final Polygon typedOther = other; + final Polygon typedOther = other as Polygon; return polygonId == typedOther.polygonId && consumeTapEvents == typedOther.consumeTapEvents && fillColor == typedOther.fillColor && @@ -193,18 +177,18 @@ class Polygon { @override int get hashCode => polygonId.hashCode; - dynamic _pointsToJson() { - final List result = []; + Object _pointsToJson() { + final List result = []; for (final LatLng point in points) { result.add(point.toJson()); } return result; } - List> _holesToJson() { - final List> result = >[]; + List> _holesToJson() { + final List> result = >[]; for (final List hole in holes) { - final List jsonHole = []; + final List jsonHole = []; for (final LatLng point in hole) { jsonHole.add(point.toJson()); } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon_updates.dart index cc8b8e26c896..29b74aecbd66 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon_updates.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon_updates.dart @@ -2,109 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' show hashValues; - -import 'package:flutter/foundation.dart' show setEquals; - import 'types.dart'; -import 'utils/polygon.dart'; /// [Polygon] update events to be applied to the [GoogleMap]. /// /// Used in [GoogleMapController] when the map is updated. // (Do not re-export) -class PolygonUpdates { +class PolygonUpdates extends MapsObjectUpdates { /// Computes [PolygonUpdates] given previous and current [Polygon]s. - PolygonUpdates.from(Set previous, Set current) { - if (previous == null) { - previous = Set.identity(); - } - - if (current == null) { - current = Set.identity(); - } - - final Map previousPolygons = keyByPolygonId(previous); - final Map currentPolygons = keyByPolygonId(current); - - final Set prevPolygonIds = previousPolygons.keys.toSet(); - final Set currentPolygonIds = currentPolygons.keys.toSet(); - - Polygon idToCurrentPolygon(PolygonId id) { - return currentPolygons[id]; - } - - final Set _polygonIdsToRemove = - prevPolygonIds.difference(currentPolygonIds); - - final Set _polygonsToAdd = currentPolygonIds - .difference(prevPolygonIds) - .map(idToCurrentPolygon) - .toSet(); - - /// Returns `true` if [current] is not equals to previous one with the - /// same id. - bool hasChanged(Polygon current) { - final Polygon previous = previousPolygons[current.polygonId]; - return current != previous; - } - - final Set _polygonsToChange = currentPolygonIds - .intersection(prevPolygonIds) - .map(idToCurrentPolygon) - .where(hasChanged) - .toSet(); - - polygonsToAdd = _polygonsToAdd; - polygonIdsToRemove = _polygonIdsToRemove; - polygonsToChange = _polygonsToChange; - } + PolygonUpdates.from(Set previous, Set current) + : super.from(previous, current, objectName: 'polygon'); /// Set of Polygons to be added in this update. - Set polygonsToAdd; + Set get polygonsToAdd => objectsToAdd; /// Set of PolygonIds to be removed in this update. - Set polygonIdsToRemove; + Set get polygonIdsToRemove => objectIdsToRemove.cast(); /// Set of Polygons to be changed in this update. - Set polygonsToChange; - - /// Converts this object to something serializable in JSON. - Map toJson() { - final Map updateMap = {}; - - void addIfNonNull(String fieldName, dynamic value) { - if (value != null) { - updateMap[fieldName] = value; - } - } - - addIfNonNull('polygonsToAdd', serializePolygonSet(polygonsToAdd)); - addIfNonNull('polygonsToChange', serializePolygonSet(polygonsToChange)); - addIfNonNull('polygonIdsToRemove', - polygonIdsToRemove.map((PolygonId m) => m.value).toList()); - - return updateMap; - } - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - if (other.runtimeType != runtimeType) return false; - final PolygonUpdates typedOther = other; - return setEquals(polygonsToAdd, typedOther.polygonsToAdd) && - setEquals(polygonIdsToRemove, typedOther.polygonIdsToRemove) && - setEquals(polygonsToChange, typedOther.polygonsToChange); - } - - @override - int get hashCode => - hashValues(polygonsToAdd, polygonIdsToRemove, polygonsToChange); - - @override - String toString() { - return '_PolygonUpdates{polygonsToAdd: $polygonsToAdd, ' - 'polygonIdsToRemove: $polygonIdsToRemove, ' - 'polygonsToChange: $polygonsToChange}'; - } + Set get polygonsToChange => objectsToChange; } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart index ae5c3b976352..3f87395164f6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart @@ -4,7 +4,7 @@ import 'package:flutter/foundation.dart' show listEquals, VoidCallback; import 'package:flutter/material.dart' show Color, Colors; -import 'package:meta/meta.dart' show immutable, required; +import 'package:meta/meta.dart' show immutable; import 'types.dart'; @@ -12,38 +12,19 @@ import 'types.dart'; /// /// This does not have to be globally unique, only unique among the list. @immutable -class PolylineId { +class PolylineId extends MapsObjectId { /// Creates an immutable object representing a [PolylineId] among [GoogleMap] polylines. /// /// An [AssertionError] will be thrown if [value] is null. - PolylineId(this.value) : assert(value != null); - - /// value of the [PolylineId]. - final String value; - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - if (other.runtimeType != runtimeType) return false; - final PolylineId typedOther = other; - return value == typedOther.value; - } - - @override - int get hashCode => value.hashCode; - - @override - String toString() { - return 'PolylineId{value: $value}'; - } + PolylineId(String value) : super(value); } /// Draws a line through geographical locations on the map. @immutable -class Polyline { +class Polyline implements MapsObject { /// Creates an immutable object representing a line drawn through geographical locations on the map. const Polyline({ - @required this.polylineId, + required this.polylineId, this.consumeTapEvents = false, this.color = Colors.black, this.endCap = Cap.buttCap, @@ -61,6 +42,9 @@ class Polyline { /// Uniquely identifies a [Polyline]. final PolylineId polylineId; + @override + PolylineId get mapsId => polylineId; + /// True if the [Polyline] consumes tap events. /// /// If this is false, [onTap] callback will not be triggered. @@ -129,23 +113,23 @@ class Polyline { final int zIndex; /// Callbacks to receive tap events for polyline placed on this map. - final VoidCallback onTap; + final VoidCallback? onTap; /// Creates a new [Polyline] object whose values are the same as this instance, /// unless overwritten by the specified parameters. Polyline copyWith({ - Color colorParam, - bool consumeTapEventsParam, - Cap endCapParam, - bool geodesicParam, - JointType jointTypeParam, - List patternsParam, - List pointsParam, - Cap startCapParam, - bool visibleParam, - int widthParam, - int zIndexParam, - VoidCallback onTapParam, + Color? colorParam, + bool? consumeTapEventsParam, + Cap? endCapParam, + bool? geodesicParam, + JointType? jointTypeParam, + List? patternsParam, + List? pointsParam, + Cap? startCapParam, + bool? visibleParam, + int? widthParam, + int? zIndexParam, + VoidCallback? onTapParam, }) { return Polyline( polylineId: polylineId, @@ -174,10 +158,10 @@ class Polyline { } /// Converts this object to something serializable in JSON. - dynamic toJson() { - final Map json = {}; + Object toJson() { + final Map json = {}; - void addIfPresent(String fieldName, dynamic value) { + void addIfPresent(String fieldName, Object? value) { if (value != null) { json[fieldName] = value; } @@ -186,10 +170,10 @@ class Polyline { addIfPresent('polylineId', polylineId.value); addIfPresent('consumeTapEvents', consumeTapEvents); addIfPresent('color', color.value); - addIfPresent('endCap', endCap?.toJson()); + addIfPresent('endCap', endCap.toJson()); addIfPresent('geodesic', geodesic); - addIfPresent('jointType', jointType?.value); - addIfPresent('startCap', startCap?.toJson()); + addIfPresent('jointType', jointType.value); + addIfPresent('startCap', startCap.toJson()); addIfPresent('visible', visible); addIfPresent('width', width); addIfPresent('zIndex', zIndex); @@ -209,7 +193,7 @@ class Polyline { bool operator ==(Object other) { if (identical(this, other)) return true; if (other.runtimeType != runtimeType) return false; - final Polyline typedOther = other; + final Polyline typedOther = other as Polyline; return polylineId == typedOther.polylineId && consumeTapEvents == typedOther.consumeTapEvents && color == typedOther.color && @@ -227,16 +211,16 @@ class Polyline { @override int get hashCode => polylineId.hashCode; - dynamic _pointsToJson() { - final List result = []; + Object _pointsToJson() { + final List result = []; for (final LatLng point in points) { result.add(point.toJson()); } return result; } - dynamic _patternToJson() { - final List result = []; + Object _patternToJson() { + final List result = []; for (final PatternItem patternItem in patterns) { if (patternItem != null) { result.add(patternItem.toJson()); diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline_updates.dart index f871928c0ac4..60e0bfe6c7ce 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline_updates.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline_updates.dart @@ -2,110 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' show hashValues; - -import 'package:flutter/foundation.dart' show setEquals; - -import 'utils/polyline.dart'; import 'types.dart'; /// [Polyline] update events to be applied to the [GoogleMap]. /// /// Used in [GoogleMapController] when the map is updated. // (Do not re-export) -class PolylineUpdates { +class PolylineUpdates extends MapsObjectUpdates { /// Computes [PolylineUpdates] given previous and current [Polyline]s. - PolylineUpdates.from(Set previous, Set current) { - if (previous == null) { - previous = Set.identity(); - } - - if (current == null) { - current = Set.identity(); - } - - final Map previousPolylines = - keyByPolylineId(previous); - final Map currentPolylines = keyByPolylineId(current); - - final Set prevPolylineIds = previousPolylines.keys.toSet(); - final Set currentPolylineIds = currentPolylines.keys.toSet(); - - Polyline idToCurrentPolyline(PolylineId id) { - return currentPolylines[id]; - } - - final Set _polylineIdsToRemove = - prevPolylineIds.difference(currentPolylineIds); - - final Set _polylinesToAdd = currentPolylineIds - .difference(prevPolylineIds) - .map(idToCurrentPolyline) - .toSet(); - - /// Returns `true` if [current] is not equals to previous one with the - /// same id. - bool hasChanged(Polyline current) { - final Polyline previous = previousPolylines[current.polylineId]; - return current != previous; - } - - final Set _polylinesToChange = currentPolylineIds - .intersection(prevPolylineIds) - .map(idToCurrentPolyline) - .where(hasChanged) - .toSet(); - - polylinesToAdd = _polylinesToAdd; - polylineIdsToRemove = _polylineIdsToRemove; - polylinesToChange = _polylinesToChange; - } + PolylineUpdates.from(Set previous, Set current) + : super.from(previous, current, objectName: 'polyline'); /// Set of Polylines to be added in this update. - Set polylinesToAdd; + Set get polylinesToAdd => objectsToAdd; /// Set of PolylineIds to be removed in this update. - Set polylineIdsToRemove; + Set get polylineIdsToRemove => + objectIdsToRemove.cast(); /// Set of Polylines to be changed in this update. - Set polylinesToChange; - - /// Converts this object to something serializable in JSON. - Map toJson() { - final Map updateMap = {}; - - void addIfNonNull(String fieldName, dynamic value) { - if (value != null) { - updateMap[fieldName] = value; - } - } - - addIfNonNull('polylinesToAdd', serializePolylineSet(polylinesToAdd)); - addIfNonNull('polylinesToChange', serializePolylineSet(polylinesToChange)); - addIfNonNull('polylineIdsToRemove', - polylineIdsToRemove.map((PolylineId m) => m.value).toList()); - - return updateMap; - } - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - if (other.runtimeType != runtimeType) return false; - final PolylineUpdates typedOther = other; - return setEquals(polylinesToAdd, typedOther.polylinesToAdd) && - setEquals(polylineIdsToRemove, typedOther.polylineIdsToRemove) && - setEquals(polylinesToChange, typedOther.polylinesToChange); - } - - @override - int get hashCode => - hashValues(polylinesToAdd, polylineIdsToRemove, polylinesToChange); - - @override - String toString() { - return '_PolylineUpdates{polylinesToAdd: $polylinesToAdd, ' - 'polylineIdsToRemove: $polylineIdsToRemove, ' - 'polylinesToChange: $polylinesToChange}'; - } + Set get polylinesToChange => objectsToChange; } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/screen_coordinate.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/screen_coordinate.dart index 965db7969bc2..af7a951a149c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/screen_coordinate.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/screen_coordinate.dart @@ -4,7 +4,7 @@ import 'dart:ui' show hashValues; -import 'package:meta/meta.dart' show immutable, required; +import 'package:meta/meta.dart' show immutable; /// Represents a point coordinate in the [GoogleMap]'s view. /// @@ -15,8 +15,8 @@ import 'package:meta/meta.dart' show immutable, required; class ScreenCoordinate { /// Creates an immutable representation of a point coordinate in the [GoogleMap]'s view. const ScreenCoordinate({ - @required this.x, - @required this.y, + required this.x, + required this.y, }); /// Represents the number of pixels from the left of the [GoogleMap]. @@ -26,7 +26,7 @@ class ScreenCoordinate { final int y; /// Converts this object to something serializable in JSON. - dynamic toJson() { + Object toJson() { return { "x": x, "y": y, diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile.dart index a992b41fb6c0..bfc322856b5a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile.dart @@ -21,13 +21,13 @@ class Tile { /// /// The image data format must be natively supported for decoding by the platform. /// e.g on Android it can only be one of the [supported image formats for decoding](https://developer.android.com/guide/topics/media/media-formats#image-formats). - final Uint8List data; + final Uint8List? data; /// Converts this object to JSON. - Map toJson() { - final Map json = {}; + Object toJson() { + final Map json = {}; - void addIfPresent(String fieldName, dynamic value) { + void addIfPresent(String fieldName, Object? value) { if (value != null) { json[fieldName] = value; } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart index 3978f23f05f8..e31bfb461fb4 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart @@ -6,30 +6,13 @@ import 'dart:ui' show hashValues; import 'package:flutter/foundation.dart'; import 'types.dart'; -import 'package:meta/meta.dart' show immutable, required; +import 'package:meta/meta.dart' show immutable; /// Uniquely identifies a [TileOverlay] among [GoogleMap] tile overlays. @immutable -class TileOverlayId { +class TileOverlayId extends MapsObjectId { /// Creates an immutable identifier for a [TileOverlay]. - TileOverlayId(this.value) : assert(value != null); - - /// The value of the [TileOverlayId]. - final String value; - - @override - bool operator ==(Object other) { - if (other.runtimeType != runtimeType) { - return false; - } - return other is TileOverlayId && other.value == value; - } - - @override - int get hashCode => value.hashCode; - - @override - String toString() => '${objectRuntimeType(this, 'TileOverlayId')}($value)'; + TileOverlayId(String value) : super(value); } /// A set of images which are displayed on top of the base map tiles. @@ -61,14 +44,14 @@ class TileOverlayId { /// At zoom level N, the x values of the tile coordinates range from 0 to 2N - 1 and increase from /// west to east and the y values range from 0 to 2N - 1 and increase from north to south. /// -class TileOverlay { +class TileOverlay implements MapsObject { /// Creates an immutable representation of a [TileOverlay] to draw on [GoogleMap]. const TileOverlay({ - @required this.tileOverlayId, + required this.tileOverlayId, this.fadeIn = true, this.tileProvider, this.transparency = 0.0, - this.zIndex, + this.zIndex = 0, this.visible = true, this.tileSize = 256, }) : assert(transparency >= 0.0 && transparency <= 1.0); @@ -76,11 +59,14 @@ class TileOverlay { /// Uniquely identifies a [TileOverlay]. final TileOverlayId tileOverlayId; + @override + TileOverlayId get mapsId => tileOverlayId; + /// Whether the tiles should fade in. The default is true. final bool fadeIn; /// The tile provider to use for this tile overlay. - final TileProvider tileProvider; + final TileProvider? tileProvider; /// The transparency of the tile overlay. The default transparency is 0 (opaque). final double transparency; @@ -104,12 +90,11 @@ class TileOverlay { /// Creates a new [TileOverlay] object whose values are the same as this instance, /// unless overwritten by the specified parameters. TileOverlay copyWith({ - TileOverlayId tileOverlayId, - bool fadeInParam, - double transparencyParam, - int zIndexParam, - bool visibleParam, - int tileSizeParam, + bool? fadeInParam, + double? transparencyParam, + int? zIndexParam, + bool? visibleParam, + int? tileSizeParam, }) { return TileOverlay( tileOverlayId: tileOverlayId, @@ -121,11 +106,13 @@ class TileOverlay { ); } + TileOverlay clone() => copyWith(); + /// Converts this object to JSON. - Map toJson() { - final Map json = {}; + Object toJson() { + final Map json = {}; - void addIfPresent(String fieldName, dynamic value) { + void addIfPresent(String fieldName, Object? value) { if (value != null) { json[fieldName] = value; } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay_updates.dart index 2910fc37d495..1436880e9626 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay_updates.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay_updates.dart @@ -2,121 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:flutter/foundation.dart' show objectRuntimeType, setEquals; -import 'dart:ui' show hashValues, hashList; - -import 'utils/tile_overlay.dart'; import 'types.dart'; /// Update specification for a set of [TileOverlay]s. -class TileOverlayUpdates { +class TileOverlayUpdates extends MapsObjectUpdates { /// Computes [TileOverlayUpdates] given previous and current [TileOverlay]s. - TileOverlayUpdates.from(Set previous, Set current) { - if (previous == null) { - previous = Set.identity(); - } - - if (current == null) { - current = Set.identity(); - } - - final Map previousTileOverlays = - keyTileOverlayId(previous); - final Map currentTileOverlays = - keyTileOverlayId(current); - - final Set prevTileOverlayIds = - previousTileOverlays.keys.toSet(); - final Set currentTileOverlayIds = - currentTileOverlays.keys.toSet(); - - TileOverlay idToCurrentTileOverlay(TileOverlayId id) { - return currentTileOverlays[id]; - } - - _tileOverlayIdsToRemove = - prevTileOverlayIds.difference(currentTileOverlayIds); - - _tileOverlaysToAdd = currentTileOverlayIds - .difference(prevTileOverlayIds) - .map(idToCurrentTileOverlay) - .toSet(); - - // Returns `true` if [current] is not equals to previous one with the - // same id. - bool hasChanged(TileOverlay current) { - final TileOverlay previous = previousTileOverlays[current.tileOverlayId]; - return current != previous; - } - - _tileOverlaysToChange = currentTileOverlayIds - .intersection(prevTileOverlayIds) - .map(idToCurrentTileOverlay) - .where(hasChanged) - .toSet(); - } + TileOverlayUpdates.from(Set previous, Set current) + : super.from(previous, current, objectName: 'tileOverlay'); /// Set of TileOverlays to be added in this update. - Set get tileOverlaysToAdd { - return _tileOverlaysToAdd; - } - - Set _tileOverlaysToAdd; + Set get tileOverlaysToAdd => objectsToAdd; /// Set of TileOverlayIds to be removed in this update. - Set get tileOverlayIdsToRemove { - return _tileOverlayIdsToRemove; - } - - Set _tileOverlayIdsToRemove; + Set get tileOverlayIdsToRemove => + objectIdsToRemove.cast(); /// Set of TileOverlays to be changed in this update. - Set get tileOverlaysToChange { - return _tileOverlaysToChange; - } - - Set _tileOverlaysToChange; - - /// Converts this object to JSON. - Map toJson() { - final Map updateMap = {}; - - void addIfNonNull(String fieldName, dynamic value) { - if (value != null) { - updateMap[fieldName] = value; - } - } - - addIfNonNull( - 'tileOverlaysToAdd', serializeTileOverlaySet(_tileOverlaysToAdd)); - addIfNonNull( - 'tileOverlaysToChange', serializeTileOverlaySet(_tileOverlaysToChange)); - addIfNonNull( - 'tileOverlayIdsToRemove', - _tileOverlayIdsToRemove - .map((TileOverlayId m) => m.value) - .toList()); - - return updateMap; - } - - @override - bool operator ==(Object other) { - if (other.runtimeType != runtimeType) { - return false; - } - return other is TileOverlayUpdates && - setEquals(_tileOverlaysToAdd, other._tileOverlaysToAdd) && - setEquals(_tileOverlayIdsToRemove, other._tileOverlayIdsToRemove) && - setEquals(_tileOverlaysToChange, other._tileOverlaysToChange); - } - - @override - int get hashCode => hashValues(hashList(_tileOverlaysToAdd), - hashList(_tileOverlayIdsToRemove), hashList(_tileOverlaysToChange)); - - @override - String toString() { - return '${objectRuntimeType(this, 'TileOverlayUpdates')}($_tileOverlaysToAdd, $_tileOverlayIdsToRemove, $_tileOverlaysToChange)'; - } + Set get tileOverlaysToChange => objectsToChange; } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_provider.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_provider.dart index c3c4f807e283..abaf38ba719d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_provider.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_provider.dart @@ -12,5 +12,5 @@ abstract class TileProvider { /// Returns the tile to be used for this tile coordinate. /// /// See [TileOverlay] for the specification of tile coordinates. - Future getTile(int x, int y, int zoom); + Future getTile(int x, int y, int? zoom); } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart index 3e2002f80ae3..9b7da87f2cb0 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart @@ -11,6 +11,8 @@ export 'circle_updates.dart'; export 'circle.dart'; export 'joint_type.dart'; export 'location.dart'; +export 'maps_object_updates.dart'; +export 'maps_object.dart'; export 'marker_updates.dart'; export 'marker.dart'; export 'pattern_item.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/ui.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/ui.dart index 8d84171bac03..1c030e338353 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/ui.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/ui.dart @@ -39,19 +39,19 @@ class CameraTargetBounds { /// The geographical bounding box for the map camera target. /// /// A null value means the camera target is unbounded. - final LatLngBounds bounds; + final LatLngBounds? bounds; /// Unbounded camera target. static const CameraTargetBounds unbounded = CameraTargetBounds(null); /// Converts this object to something serializable in JSON. - dynamic toJson() => [bounds?.toJson()]; + Object toJson() => [bounds?.toJson()]; @override - bool operator ==(dynamic other) { + bool operator ==(Object other) { if (identical(this, other)) return true; if (runtimeType != other.runtimeType) return false; - final CameraTargetBounds typedOther = other; + final CameraTargetBounds typedOther = other as CameraTargetBounds; return bounds == typedOther.bounds; } @@ -76,23 +76,23 @@ class MinMaxZoomPreference { : assert(minZoom == null || maxZoom == null || minZoom <= maxZoom); /// The preferred minimum zoom level or null, if unbounded from below. - final double minZoom; + final double? minZoom; /// The preferred maximum zoom level or null, if unbounded from above. - final double maxZoom; + final double? maxZoom; /// Unbounded zooming. static const MinMaxZoomPreference unbounded = MinMaxZoomPreference(null, null); /// Converts this object to something serializable in JSON. - dynamic toJson() => [minZoom, maxZoom]; + Object toJson() => [minZoom, maxZoom]; @override - bool operator ==(dynamic other) { + bool operator ==(Object other) { if (identical(this, other)) return true; if (runtimeType != other.runtimeType) return false; - final MinMaxZoomPreference typedOther = other; + final MinMaxZoomPreference typedOther = other as MinMaxZoomPreference; return minZoom == typedOther.minZoom && maxZoom == typedOther.maxZoom; } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/circle.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/circle.dart index 5c3af96f8e02..18bd31ec7df6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/circle.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/circle.dart @@ -3,20 +3,14 @@ // found in the LICENSE file. import '../types.dart'; +import 'maps_object.dart'; /// Converts an [Iterable] of Circles in a Map of CircleId -> Circle. Map keyByCircleId(Iterable circles) { - if (circles == null) { - return {}; - } - return Map.fromEntries(circles.map((Circle circle) => - MapEntry(circle.circleId, circle.clone()))); + return keyByMapsObjectId(circles).cast(); } /// Converts a Set of Circles into something serializable in JSON. -List> serializeCircleSet(Set circles) { - if (circles == null) { - return null; - } - return circles.map>((Circle p) => p.toJson()).toList(); +Object serializeCircleSet(Set circles) { + return serializeMapsObjectSet(circles); } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/maps_object.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/maps_object.dart new file mode 100644 index 000000000000..fa5a7e7591ee --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/maps_object.dart @@ -0,0 +1,18 @@ +// Copyright 2019 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. + +import '../maps_object.dart'; + +/// Converts an [Iterable] of [MapsObject]s in a Map of [MapObjectId] -> [MapObject]. +Map, T> keyByMapsObjectId( + Iterable objects) { + return Map, T>.fromEntries(objects.map((T object) => + MapEntry, T>( + object.mapsId as MapsObjectId, object.clone()))); +} + +/// Converts a Set of [MapsObject]s into something serializable in JSON. +Object serializeMapsObjectSet(Set mapsObjects) { + return mapsObjects.map((MapsObject p) => p.toJson()).toList(); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/marker.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/marker.dart index 7a2c76d8055b..057bebdc8b8a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/marker.dart @@ -3,20 +3,14 @@ // found in the LICENSE file. import '../types.dart'; +import 'maps_object.dart'; /// Converts an [Iterable] of Markers in a Map of MarkerId -> Marker. Map keyByMarkerId(Iterable markers) { - if (markers == null) { - return {}; - } - return Map.fromEntries(markers.map((Marker marker) => - MapEntry(marker.markerId, marker.clone()))); + return keyByMapsObjectId(markers).cast(); } /// Converts a Set of Markers into something serializable in JSON. -List> serializeMarkerSet(Set markers) { - if (markers == null) { - return null; - } - return markers.map>((Marker m) => m.toJson()).toList(); +Object serializeMarkerSet(Set markers) { + return serializeMapsObjectSet(markers); } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polygon.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polygon.dart index 9434ddaa077d..050ecafce31f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polygon.dart @@ -3,20 +3,14 @@ // found in the LICENSE file. import '../types.dart'; +import 'maps_object.dart'; /// Converts an [Iterable] of Polygons in a Map of PolygonId -> Polygon. Map keyByPolygonId(Iterable polygons) { - if (polygons == null) { - return {}; - } - return Map.fromEntries(polygons.map((Polygon polygon) => - MapEntry(polygon.polygonId, polygon.clone()))); + return keyByMapsObjectId(polygons).cast(); } /// Converts a Set of Polygons into something serializable in JSON. -List> serializePolygonSet(Set polygons) { - if (polygons == null) { - return null; - } - return polygons.map>((Polygon p) => p.toJson()).toList(); +Object serializePolygonSet(Set polygons) { + return serializeMapsObjectSet(polygons); } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polyline.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polyline.dart index 9cef6319ddb5..8f4098feedf7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polyline.dart @@ -3,23 +3,14 @@ // found in the LICENSE file. import '../types.dart'; +import 'maps_object.dart'; /// Converts an [Iterable] of Polylines in a Map of PolylineId -> Polyline. Map keyByPolylineId(Iterable polylines) { - if (polylines == null) { - return {}; - } - return Map.fromEntries(polylines.map( - (Polyline polyline) => MapEntry( - polyline.polylineId, polyline.clone()))); + return keyByMapsObjectId(polylines).cast(); } /// Converts a Set of Polylines into something serializable in JSON. -List> serializePolylineSet(Set polylines) { - if (polylines == null) { - return null; - } - return polylines - .map>((Polyline p) => p.toJson()) - .toList(); +Object serializePolylineSet(Set polylines) { + return serializeMapsObjectSet(polylines); } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/tile_overlay.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/tile_overlay.dart index 0736c836481f..336f814d329a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/tile_overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/tile_overlay.dart @@ -1,23 +1,18 @@ +// Copyright 2019 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. + import '../types.dart'; +import 'maps_object.dart'; /// Converts an [Iterable] of TileOverlay in a Map of TileOverlayId -> TileOverlay. Map keyTileOverlayId( Iterable tileOverlays) { - if (tileOverlays == null) { - return {}; - } - return Map.fromEntries(tileOverlays.map( - (TileOverlay tileOverlay) => MapEntry( - tileOverlay.tileOverlayId, tileOverlay))); + return keyByMapsObjectId(tileOverlays) + .cast(); } /// Converts a Set of TileOverlays into something serializable in JSON. -List> serializeTileOverlaySet( - Set tileOverlays) { - if (tileOverlays == null) { - return null; - } - return tileOverlays - .map>((TileOverlay p) => p.toJson()) - .toList(); +Object serializeTileOverlaySet(Set tileOverlays) { + return serializeMapsObjectSet(tileOverlays); } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml index 487a54b08e5e..8b31feeb94a2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml @@ -3,22 +3,22 @@ description: A common platform interface for the google_maps_flutter plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.2.0 +version: 2.0.0-nullsafety dependencies: flutter: sdk: flutter meta: ^1.0.5 - plugin_platform_interface: ^1.0.1 - stream_transform: ^1.2.0 + plugin_platform_interface: ^1.1.0-nullsafety.2 + stream_transform: ^2.0.0-nullsafety.0 collection: ^1.14.13 dev_dependencies: flutter_test: sdk: flutter - mockito: ^4.1.1 + mockito: ^5.0.0-nullsafety.0 pedantic: ^1.8.0 environment: - sdk: ">=2.3.0 <3.0.0" + sdk: '>=2.12.0-0 <3.0.0' flutter: ">=1.9.1+hotfix.4" diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart new file mode 100644 index 000000000000..65692bd2a385 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart @@ -0,0 +1,45 @@ +// 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. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; +import 'package:google_maps_flutter_platform_interface/src/types/utils/maps_object.dart'; + +import 'test_maps_object.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + test('keyByMapsObjectId', () async { + final MapsObjectId id1 = MapsObjectId('1'); + final MapsObjectId id2 = MapsObjectId('2'); + final MapsObjectId id3 = MapsObjectId('3'); + final TestMapsObject object1 = TestMapsObject(id1); + final TestMapsObject object2 = TestMapsObject(id2, data: 2); + final TestMapsObject object3 = TestMapsObject(id3); + expect( + keyByMapsObjectId({object1, object2, object3}), + , TestMapsObject>{ + id1: object1, + id2: object2, + id3: object3, + }); + }); + + test('serializeMapsObjectSet', () async { + final MapsObjectId id1 = MapsObjectId('1'); + final MapsObjectId id2 = MapsObjectId('2'); + final MapsObjectId id3 = MapsObjectId('3'); + final TestMapsObject object1 = TestMapsObject(id1); + final TestMapsObject object2 = TestMapsObject(id2, data: 2); + final TestMapsObject object3 = TestMapsObject(id3); + expect( + serializeMapsObjectSet({object1, object2, object3}), + >[ + {'id': '1'}, + {'id': '2'}, + {'id': '3'} + ]); + }); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart new file mode 100644 index 000000000000..68f4c587c2f2 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart @@ -0,0 +1,160 @@ +// 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. + +import 'dart:ui' show hashValues, hashList; + +import 'package:flutter/rendering.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:google_maps_flutter_platform_interface/src/types/utils/maps_object.dart'; +import 'package:google_maps_flutter_platform_interface/src/types/maps_object_updates.dart'; +import 'package:google_maps_flutter_platform_interface/src/types/maps_object.dart'; + +import 'test_maps_object.dart'; + +class TestMapsObjectUpdate extends MapsObjectUpdates { + TestMapsObjectUpdate.from( + Set previous, Set current) + : super.from(previous, current, objectName: 'testObject'); +} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('tile overlay updates tests', () { + test('Correctly set toRemove, toAdd and toChange', () async { + final TestMapsObject to1 = + TestMapsObject(MapsObjectId('id1')); + final TestMapsObject to2 = + TestMapsObject(MapsObjectId('id2')); + final TestMapsObject to3 = + TestMapsObject(MapsObjectId('id3')); + final TestMapsObject to3Changed = + TestMapsObject(MapsObjectId('id3'), data: 2); + final TestMapsObject to4 = + TestMapsObject(MapsObjectId('id4')); + final Set previous = + Set.from([to1, to2, to3]); + final Set current = + Set.from([to2, to3Changed, to4]); + final TestMapsObjectUpdate updates = + TestMapsObjectUpdate.from(previous, current); + + final Set> toRemove = Set.from( + >[MapsObjectId('id1')]); + expect(updates.objectIdsToRemove, toRemove); + + final Set toAdd = Set.from([to4]); + expect(updates.objectsToAdd, toAdd); + + final Set toChange = + Set.from([to3Changed]); + expect(updates.objectsToChange, toChange); + }); + + test('toJson', () async { + final TestMapsObject to1 = + TestMapsObject(MapsObjectId('id1')); + final TestMapsObject to2 = + TestMapsObject(MapsObjectId('id2')); + final TestMapsObject to3 = + TestMapsObject(MapsObjectId('id3')); + final TestMapsObject to3Changed = + TestMapsObject(MapsObjectId('id3'), data: 2); + final TestMapsObject to4 = + TestMapsObject(MapsObjectId('id4')); + final Set previous = + Set.from([to1, to2, to3]); + final Set current = + Set.from([to2, to3Changed, to4]); + final TestMapsObjectUpdate updates = + TestMapsObjectUpdate.from(previous, current); + + final Object json = updates.toJson(); + expect(json, { + 'testObjectsToAdd': serializeMapsObjectSet(updates.objectsToAdd), + 'testObjectsToChange': serializeMapsObjectSet(updates.objectsToChange), + 'testObjectIdsToRemove': updates.objectIdsToRemove + .map((MapsObjectId m) => m.value) + .toList() + }); + }); + + test('equality', () async { + final TestMapsObject to1 = + TestMapsObject(MapsObjectId('id1')); + final TestMapsObject to2 = + TestMapsObject(MapsObjectId('id2')); + final TestMapsObject to3 = + TestMapsObject(MapsObjectId('id3')); + final TestMapsObject to3Changed = + TestMapsObject(MapsObjectId('id3'), data: 2); + final TestMapsObject to4 = + TestMapsObject(MapsObjectId('id4')); + final Set previous = + Set.from([to1, to2, to3]); + final Set current1 = + Set.from([to2, to3Changed, to4]); + final Set current2 = + Set.from([to2, to3Changed, to4]); + final Set current3 = Set.from([to2, to4]); + final TestMapsObjectUpdate updates1 = + TestMapsObjectUpdate.from(previous, current1); + final TestMapsObjectUpdate updates2 = + TestMapsObjectUpdate.from(previous, current2); + final TestMapsObjectUpdate updates3 = + TestMapsObjectUpdate.from(previous, current3); + expect(updates1, updates2); + expect(updates1, isNot(updates3)); + }); + + test('hashCode', () async { + final TestMapsObject to1 = + TestMapsObject(MapsObjectId('id1')); + final TestMapsObject to2 = + TestMapsObject(MapsObjectId('id2')); + final TestMapsObject to3 = + TestMapsObject(MapsObjectId('id3')); + final TestMapsObject to3Changed = + TestMapsObject(MapsObjectId('id3'), data: 2); + final TestMapsObject to4 = + TestMapsObject(MapsObjectId('id4')); + final Set previous = + Set.from([to1, to2, to3]); + final Set current = + Set.from([to2, to3Changed, to4]); + final TestMapsObjectUpdate updates = + TestMapsObjectUpdate.from(previous, current); + expect( + updates.hashCode, + hashValues( + hashList(updates.objectsToAdd), + hashList(updates.objectIdsToRemove), + hashList(updates.objectsToChange))); + }); + + test('toString', () async { + final TestMapsObject to1 = + TestMapsObject(MapsObjectId('id1')); + final TestMapsObject to2 = + TestMapsObject(MapsObjectId('id2')); + final TestMapsObject to3 = + TestMapsObject(MapsObjectId('id3')); + final TestMapsObject to3Changed = + TestMapsObject(MapsObjectId('id3'), data: 2); + final TestMapsObject to4 = + TestMapsObject(MapsObjectId('id4')); + final Set previous = + Set.from([to1, to2, to3]); + final Set current = + Set.from([to2, to3Changed, to4]); + final TestMapsObjectUpdate updates = + TestMapsObjectUpdate.from(previous, current); + expect( + updates.toString(), + 'TestMapsObjectUpdate(add: ${updates.objectsToAdd}, ' + 'remove: ${updates.objectIdsToRemove}, ' + 'change: ${updates.objectsToChange})'); + }); + }); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart new file mode 100644 index 000000000000..e15c73f08a54 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart @@ -0,0 +1,46 @@ +// 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. + +import 'dart:ui' show hashValues; +import 'package:flutter/rendering.dart'; +import 'package:google_maps_flutter_platform_interface/src/types/maps_object_updates.dart'; +import 'package:google_maps_flutter_platform_interface/src/types/maps_object.dart'; + +/// A trivial TestMapsObject implementation for testing updates with. +class TestMapsObject implements MapsObject { + TestMapsObject(this.mapsId, {this.data = 1}); + + final MapsObjectId mapsId; + + final int data; + + @override + TestMapsObject clone() { + return TestMapsObject(mapsId, data: data); + } + + @override + Object toJson() { + return {'id': mapsId.value}; + } + + @override + bool operator ==(Object other) { + if (other.runtimeType != runtimeType) { + return false; + } + return other is TestMapsObject && + mapsId == other.mapsId && + data == other.data; + } + + @override + int get hashCode => hashValues(mapsId, data); +} + +class TestMapsObjectUpdate extends MapsObjectUpdates { + TestMapsObjectUpdate.from( + Set previous, Set current) + : super.from(previous, current, objectName: 'testObject'); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart index bb0621d23ae3..87380fdd651b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart @@ -34,13 +34,15 @@ void main() { zIndex: 1, visible: false, tileSize: 128); - final Map json = tileOverlay.toJson(); - expect(json['tileOverlayId'], 'id'); - expect(json['fadeIn'], false); - expect(json['transparency'], moreOrLessEquals(0.1)); - expect(json['zIndex'], 1); - expect(json['visible'], false); - expect(json['tileSize'], 128); + final Object json = tileOverlay.toJson(); + expect(json, { + 'tileOverlayId': 'id', + 'fadeIn': false, + 'transparency': moreOrLessEquals(0.1), + 'zIndex': 1, + 'visible': false, + 'tileSize': 128, + }); }); test('invalid transparency throws', () async { diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart index 980a203f709e..f622ca5213ef 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart @@ -49,13 +49,13 @@ void main() { final TileOverlayUpdates updates = TileOverlayUpdates.from(previous, current); - final Map json = updates.toJson(); - expect(json, { + final Object json = updates.toJson(); + expect(json, { 'tileOverlaysToAdd': serializeTileOverlaySet(updates.tileOverlaysToAdd), 'tileOverlaysToChange': serializeTileOverlaySet(updates.tileOverlaysToChange), 'tileOverlayIdsToRemove': updates.tileOverlayIdsToRemove - .map((TileOverlayId m) => m.value) + .map((TileOverlayId m) => m.value) .toList() }); }); @@ -117,9 +117,9 @@ void main() { TileOverlayUpdates.from(previous, current); expect( updates.toString(), - 'TileOverlayUpdates(${updates.tileOverlaysToAdd}, ' - '${updates.tileOverlayIdsToRemove}, ' - '${updates.tileOverlaysToChange})'); + 'TileOverlayUpdates(add: ${updates.tileOverlaysToAdd}, ' + 'remove: ${updates.tileOverlayIdsToRemove}, ' + 'change: ${updates.tileOverlaysToChange})'); }); }); } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart index 0be9a7cea8f0..3e0fe99ec18c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart @@ -13,16 +13,21 @@ void main() { test('toJson returns correct format', () async { final Uint8List data = Uint8List.fromList([0, 1]); final Tile tile = Tile(100, 200, data); - final Map json = tile.toJson(); - expect(json['width'], 100); - expect(json['height'], 200); - expect(json['data'], data); + final Object json = tile.toJson(); + expect(json, { + 'width': 100, + 'height': 200, + 'data': data, + }); }); - test('toJson returns empty if nothing presents', () async { - final Tile tile = Tile(null, null, null); - final Map json = tile.toJson(); - expect(json.isEmpty, true); + test('toJson handles null data', () async { + final Tile tile = Tile(0, 0, null); + final Object json = tile.toJson(); + expect(json, { + 'width': 0, + 'height': 0, + }); }); }); } diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index 5a54a7ff30d6..3e82ac202a43 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -15,6 +15,7 @@ readonly NNBD_PLUGINS_LIST=( "file_selector" "flutter_plugin_android_lifecycle" "flutter_webview" + "google_maps_flutter" "google_sign_in" "image_picker" "ios_platform_images" @@ -38,7 +39,7 @@ readonly NNBD_PLUGINS_LIST=( readonly NON_NNBD_PLUGINS_LIST=( "camera" - # "google_maps_flutter" + "google_maps_flutter" # half migrated # "image_picker" # "in_app_purchase" # "quick_actions" From d054fa9a19bc4cb8165d8963f7323bf29a58cf19 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Sun, 14 Feb 2021 18:56:19 -0800 Subject: [PATCH 0133/1565] Enable CI tests on beta (#3538) --- .cirrus.yml | 12 ++++++++++++ script/build_all_plugins_app.sh | 8 +++----- script/nnbd_plugins.sh | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index a49a8b14ca83..c7323742e6e4 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -11,6 +11,8 @@ task: upgrade_script: - flutter channel stable - flutter upgrade + - flutter channel beta + - flutter upgrade - flutter channel master - flutter upgrade - git fetch origin master @@ -33,6 +35,7 @@ task: env: matrix: CHANNEL: "master" + CHANNEL: "beta" CHANNEL: "stable" test_script: # TODO(jackson): Allow web plugins once supported on stable @@ -44,12 +47,14 @@ task: env: matrix: CHANNEL: "master" + CHANNEL: "beta" CHANNEL: "stable" script: ./script/incremental_build.sh analyze - name: build_all_plugins_apk env: matrix: CHANNEL: "master" + CHANNEL: "beta" CHANNEL: "stable" script: # TODO(jackson): Allow web plugins once supported on stable @@ -79,6 +84,7 @@ task: PLUGIN_SHARDING: "--shardIndex 3 --shardCount 4" matrix: CHANNEL: "master" + CHANNEL: "beta" CHANNEL: "stable" MAPS_API_KEY: ENCRYPTED[596a9f6bca436694625ac50851dc5da6b4d34cba8025f7db5bc9465142e8cd44e15f69e3507787753accebfc4910d550] GCLOUD_FIREBASE_TESTLAB_KEY: ENCRYPTED[07586610af1fdfc894e5969f70ef2458341b9b7e9c3b7c4225a663b4a48732b7208a4d91c3b7d45305a6b55fa2a37fc4] @@ -121,6 +127,8 @@ task: upgrade_script: - flutter channel stable - flutter upgrade + - flutter channel beta + - flutter upgrade - flutter channel master - flutter upgrade - git fetch origin master @@ -148,6 +156,8 @@ task: - sudo gem install cocoapods - flutter channel stable - flutter upgrade + - flutter channel beta + - flutter upgrade - flutter channel master - flutter upgrade - git fetch origin master @@ -162,6 +172,7 @@ task: env: matrix: CHANNEL: "master" + CHANNEL: "beta" CHANNEL: "stable" script: # TODO(jackson): Allow web plugins once supported on stable @@ -180,6 +191,7 @@ task: PLUGIN_SHARDING: "--shardIndex 3 --shardCount 4" matrix: CHANNEL: "master" + CHANNEL: "beta" CHANNEL: "stable" SIMCTL_CHILD_MAPS_API_KEY: ENCRYPTED[596a9f6bca436694625ac50851dc5da6b4d34cba8025f7db5bc9465142e8cd44e15f69e3507787753accebfc4910d550] build_script: diff --git a/script/build_all_plugins_app.sh b/script/build_all_plugins_app.sh index 7807e6a98bce..399f1f1b79f7 100755 --- a/script/build_all_plugins_app.sh +++ b/script/build_all_plugins_app.sh @@ -54,13 +54,11 @@ readonly EXCLUDED_PLUGINS_LIST=( readonly EXCLUDED=$(IFS=, ; echo "${EXCLUDED_PLUGINS_LIST[*]}") ALL_EXCLUDED=($EXCLUDED) -# Exclude nnbd plugins from stable. +# Exclude nnbd plugins from stable, and conflicting plugins otherwise. if [ "$CHANNEL" == "stable" ]; then ALL_EXCLUDED=("$EXCLUDED,$EXCLUDED_PLUGINS_FROM_STABLE") -fi -# Exclude non-nnbd plugins from master. -if [ "$CHANNEL" != "stable" ]; then - ALL_EXCLUDED=("$EXCLUDED,$EXCLUDED_PLUGINS_FROM_MASTER") +else + ALL_EXCLUDED=("$EXCLUDED,$EXCLUDED_PLUGINS_FOR_NNBD") fi echo "Excluding the following plugins: $ALL_EXCLUDED" diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index 3e82ac202a43..a2c22c67948a 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -48,4 +48,4 @@ readonly NON_NNBD_PLUGINS_LIST=( ) export EXCLUDED_PLUGINS_FROM_STABLE=$(IFS=, ; echo "${NNBD_PLUGINS_LIST[*]}") -export EXCLUDED_PLUGINS_FROM_MASTER=$(IFS=, ; echo "${NON_NNBD_PLUGINS_LIST[*]}") +export EXCLUDED_PLUGINS_FOR_NNBD=$(IFS=, ; echo "${NON_NNBD_PLUGINS_LIST[*]}") From 57a40bf15a040d9c42a36d001918d724cca31fc2 Mon Sep 17 00:00:00 2001 From: hemanthrajdc <49126054+hemanthrajdc@users.noreply.github.com> Date: Mon, 15 Feb 2021 13:21:49 +0530 Subject: [PATCH 0134/1565] [camera] Fixes crash on takePicture() (#3537) * Fixes #75133 * Updated pubspec.yaml and change log * Fix format --- packages/camera/camera/CHANGELOG.md | 4 ++++ .../io/flutter/plugins/camera/DeviceOrientationManager.java | 6 ++++++ packages/camera/camera/pubspec.yaml | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 622bd095b021..e365e76cbafd 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.0+4 + +* Fix crash when taking picture with orientation lock + ## 0.7.0+3 * Clockwise rotation of focus point in android diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java index 7c6011b185fb..b2a504b629d6 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java @@ -55,6 +55,12 @@ public int getMediaOrientation() { public int getMediaOrientation(PlatformChannel.DeviceOrientation orientation) { int angle = 0; + + // Fallback to device orientation when the orientation value is null + if (orientation == null) { + orientation = getUIOrientation(); + } + switch (orientation) { case PORTRAIT_UP: angle = 0; diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index cebbb334c8f2..5ac4b57a15ef 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.7.0+3 +version: 0.7.0+4 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From 7e9c79b2282838149cc0a5c0b94243689bd5f6f8 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Mon, 15 Feb 2021 10:00:19 +0100 Subject: [PATCH 0135/1565] [camera] NNBD migration of the camera plugin (#3533) * Migrate camera_platform_interface to null safety * Exclude camera_platform_interface from all plugins script * Convert CameraId in test to non-nullable * Migrate to nullsafety * Attempt to fix dependency problem building all plugins * Update version information * Fix type * Make exposureMode and focusMode non-nullable * Mark google_maps_flutter as non-NNBD * Update dependencies * Added missing entry to CHANGELOG.md * Rebased on master --- packages/camera/camera/CHANGELOG.md | 4 + .../camera/example/ios/Flutter/Debug.xcconfig | 1 + .../example/ios/Flutter/Release.xcconfig | 1 + .../ios/Runner.xcodeproj/project.pbxproj | 19 -- .../contents.xcworkspacedata | 2 +- .../camera/lib/src/camera_controller.dart | 97 ++++---- .../camera/camera/lib/src/camera_image.dart | 6 +- .../camera/camera/lib/src/camera_preview.dart | 6 +- packages/camera/camera/pubspec.yaml | 21 +- packages/camera/camera/test/camera_test.dart | 225 ++++++++++++++---- .../camera/camera/test/camera_value_test.dart | 8 +- .../test/utils/method_channel_mock.dart | 6 +- script/nnbd_plugins.sh | 5 +- 13 files changed, 270 insertions(+), 131 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index e365e76cbafd..aee3774087ba 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.8.0-nullsafety + +* Migrated to null safety. + ## 0.7.0+4 * Fix crash when taking picture with orientation lock diff --git a/packages/camera/camera/example/ios/Flutter/Debug.xcconfig b/packages/camera/camera/example/ios/Flutter/Debug.xcconfig index e8efba114687..b2f5fae9c254 100644 --- a/packages/camera/camera/example/ios/Flutter/Debug.xcconfig +++ b/packages/camera/camera/example/ios/Flutter/Debug.xcconfig @@ -1,2 +1,3 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/packages/camera/camera/example/ios/Flutter/Release.xcconfig b/packages/camera/camera/example/ios/Flutter/Release.xcconfig index 399e9340e6f6..88c29144c836 100644 --- a/packages/camera/camera/example/ios/Flutter/Release.xcconfig +++ b/packages/camera/camera/example/ios/Flutter/Release.xcconfig @@ -1,2 +1,3 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/packages/camera/camera/example/ios/Runner.xcodeproj/project.pbxproj b/packages/camera/camera/example/ios/Runner.xcodeproj/project.pbxproj index d51240a02c14..3f71bb69d6b6 100644 --- a/packages/camera/camera/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/camera/camera/example/ios/Runner.xcodeproj/project.pbxproj @@ -147,7 +147,6 @@ 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - FE224661708E6DA2A0F8B952 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -252,24 +251,6 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; - FE224661708E6DA2A0F8B952 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", - "${PODS_ROOT}/../Flutter/Flutter.framework", - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ diff --git a/packages/camera/camera/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/camera/camera/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed0f..919434a6254f 100644 --- a/packages/camera/camera/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/packages/camera/camera/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index 80e83c867954..bb976d1c85fe 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -32,19 +32,19 @@ Future> availableCameras() async { class CameraValue { /// Creates a new camera controller state. const CameraValue({ - this.isInitialized, + required this.isInitialized, this.errorDescription, this.previewSize, - this.isRecordingVideo, - this.isTakingPicture, - this.isStreamingImages, - bool isRecordingPaused, - this.flashMode, - this.exposureMode, - this.focusMode, - this.exposurePointSupported, - this.focusPointSupported, - this.deviceOrientation, + required this.isRecordingVideo, + required this.isTakingPicture, + required this.isStreamingImages, + required bool isRecordingPaused, + required this.flashMode, + required this.exposureMode, + required this.focusMode, + required this.exposurePointSupported, + required this.focusPointSupported, + required this.deviceOrientation, this.lockedCaptureOrientation, this.recordingOrientation, }) : _isRecordingPaused = isRecordingPaused; @@ -58,7 +58,9 @@ class CameraValue { isStreamingImages: false, isRecordingPaused: false, flashMode: FlashMode.auto, + exposureMode: ExposureMode.auto, exposurePointSupported: false, + focusMode: FocusMode.auto, focusPointSupported: false, deviceOrientation: DeviceOrientation.portraitUp, ); @@ -84,17 +86,17 @@ class CameraValue { /// /// This is null while the controller is not in an error state. /// When [hasError] is true this contains the error description. - final String errorDescription; + final String? errorDescription; /// The size of the preview in pixels. /// - /// Is `null` until [isInitialized] is `true`. - final Size previewSize; + /// Is `null` until [isInitialized] is `true`. + final Size? previewSize; /// Convenience getter for `previewSize.width / previewSize.height`. /// /// Can only be called when [initialize] is done. - double get aspectRatio => previewSize.width / previewSize.height; + double get aspectRatio => previewSize!.width / previewSize!.height; /// Whether the controller is in an error state. /// @@ -120,34 +122,34 @@ class CameraValue { final DeviceOrientation deviceOrientation; /// The currently locked capture orientation. - final DeviceOrientation lockedCaptureOrientation; + final DeviceOrientation? lockedCaptureOrientation; /// Whether the capture orientation is currently locked. bool get isCaptureOrientationLocked => lockedCaptureOrientation != null; /// The orientation of the currently running video recording. - final DeviceOrientation recordingOrientation; + final DeviceOrientation? recordingOrientation; /// Creates a modified copy of the object. /// /// Explicitly specified fields get the specified value, all other fields get /// the same value of the current object. CameraValue copyWith({ - bool isInitialized, - bool isRecordingVideo, - bool isTakingPicture, - bool isStreamingImages, - String errorDescription, - Size previewSize, - bool isRecordingPaused, - FlashMode flashMode, - ExposureMode exposureMode, - FocusMode focusMode, - bool exposurePointSupported, - bool focusPointSupported, - DeviceOrientation deviceOrientation, - Optional lockedCaptureOrientation, - Optional recordingOrientation, + bool? isInitialized, + bool? isRecordingVideo, + bool? isTakingPicture, + bool? isStreamingImages, + String? errorDescription, + Size? previewSize, + bool? isRecordingPaused, + FlashMode? flashMode, + ExposureMode? exposureMode, + FocusMode? focusMode, + bool? exposurePointSupported, + bool? focusPointSupported, + DeviceOrientation? deviceOrientation, + Optional? lockedCaptureOrientation, + Optional? recordingOrientation, }) { return CameraValue( isInitialized: isInitialized ?? this.isInitialized, @@ -225,13 +227,17 @@ class CameraController extends ValueNotifier { /// The [ImageFormatGroup] describes the output of the raw image format. /// /// When null the imageFormat will fallback to the platforms default. - final ImageFormatGroup imageFormatGroup; + final ImageFormatGroup? imageFormatGroup; + + /// The id of a camera that hasn't been initialized. + @visibleForTesting + static const int kUninitializedCameraId = -1; + int _cameraId = kUninitializedCameraId; - int _cameraId; bool _isDisposed = false; - StreamSubscription _imageStreamSubscription; - FutureOr _initCalled; - StreamSubscription _deviceOrientationSubscription; + StreamSubscription? _imageStreamSubscription; + FutureOr? _initCalled; + StreamSubscription? _deviceOrientationSubscription; /// Checks whether [CameraController.dispose] has completed successfully. /// @@ -278,7 +284,7 @@ class CameraController extends ValueNotifier { await CameraPlatform.instance.initializeCamera( _cameraId, - imageFormatGroup: imageFormatGroup, + imageFormatGroup: imageFormatGroup ?? ImageFormatGroup.unknown, ); value = value.copyWith( @@ -422,7 +428,7 @@ class CameraController extends ValueNotifier { throw CameraException(e.code, e.message); } - await _imageStreamSubscription.cancel(); + await _imageStreamSubscription?.cancel(); _imageStreamSubscription = null; } @@ -583,12 +589,16 @@ class CameraController extends ValueNotifier { } /// Sets the exposure point for automatically determining the exposure value. - Future setExposurePoint(Offset point) async { + /// + /// Supplying a `null` value will reset the exposure point to it's default + /// value. + Future setExposurePoint(Offset? point) async { if (point != null && (point.dx < 0 || point.dx > 1 || point.dy < 0 || point.dy > 1)) { throw ArgumentError( 'The values of point should be anywhere between (0,0) and (1,1).'); } + try { await CameraPlatform.instance.setExposurePoint( _cameraId, @@ -682,7 +692,7 @@ class CameraController extends ValueNotifier { /// Locks the capture orientation. /// /// If [orientation] is omitted, the current device orientation is used. - Future lockCaptureOrientation([DeviceOrientation orientation]) async { + Future lockCaptureOrientation([DeviceOrientation? orientation]) async { try { await CameraPlatform.instance.lockCaptureOrientation( _cameraId, orientation ?? value.deviceOrientation); @@ -715,7 +725,10 @@ class CameraController extends ValueNotifier { } /// Sets the focus point for automatically determining the focus value. - Future setFocusPoint(Offset point) async { + /// + /// Supplying a `null` value will reset the focus point to it's default + /// value. + Future setFocusPoint(Offset? point) async { if (point != null && (point.dx < 0 || point.dx > 1 || point.dy < 0 || point.dy > 1)) { throw ArgumentError( diff --git a/packages/camera/camera/lib/src/camera_image.dart b/packages/camera/camera/lib/src/camera_image.dart index dffa5066d14f..46aa2a6e3091 100644 --- a/packages/camera/camera/lib/src/camera_image.dart +++ b/packages/camera/camera/lib/src/camera_image.dart @@ -26,7 +26,7 @@ class Plane { /// The distance between adjacent pixel samples on Android, in bytes. /// /// Will be `null` on iOS. - final int bytesPerPixel; + final int? bytesPerPixel; /// The row stride for this color plane, in bytes. final int bytesPerRow; @@ -34,12 +34,12 @@ class Plane { /// Height of the pixel buffer on iOS. /// /// Will be `null` on Android - final int height; + final int? height; /// Width of the pixel buffer on iOS. /// /// Will be `null` on Android. - final int width; + final int? width; } /// Describes how pixels are represented in an image. diff --git a/packages/camera/camera/lib/src/camera_preview.dart b/packages/camera/camera/lib/src/camera_preview.dart index 05e969004233..f6d357b41b77 100644 --- a/packages/camera/camera/lib/src/camera_preview.dart +++ b/packages/camera/camera/lib/src/camera_preview.dart @@ -17,7 +17,7 @@ class CameraPreview extends StatelessWidget { final CameraController controller; /// A widget to overlay on top of the camera preview - final Widget child; + final Widget? child; @override Widget build(BuildContext context) { @@ -43,7 +43,7 @@ class CameraPreview extends StatelessWidget { DeviceOrientation _getApplicableOrientation() { return controller.value.isRecordingVideo - ? controller.value.recordingOrientation + ? controller.value.recordingOrientation! : (controller.value.lockedCaptureOrientation ?? controller.value.deviceOrientation); } @@ -61,6 +61,6 @@ class CameraPreview extends StatelessWidget { DeviceOrientation.portraitDown: 2, DeviceOrientation.landscapeRight: 3, }; - return turns[_getApplicableOrientation()] + platformOffset; + return turns[_getApplicableOrientation()]! + platformOffset; } } diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 5ac4b57a15ef..7ed08d892de8 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,25 +2,26 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.7.0+4 +version: 0.8.0-nullsafety homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: flutter: sdk: flutter - camera_platform_interface: ^1.5.0 - pedantic: ^1.8.0 - quiver: ^2.1.5 + + camera_platform_interface: ^2.0.0-nullsafety + + pedantic: ^1.10.0 + quiver: ^3.0.0-nullsafety.3 dev_dependencies: - path_provider: ^0.5.0 - video_player: ^0.10.0 + video_player: ^2.0.0-nullsafety.7 flutter_test: sdk: flutter flutter_driver: sdk: flutter - mockito: ^4.1.3 - plugin_platform_interface: ^1.0.3 + mockito: ^5.0.0-nullsafety.5 + plugin_platform_interface: ^1.1.0-nullsafety.2 flutter: plugin: @@ -32,5 +33,5 @@ flutter: pluginClass: CameraPlugin environment: - sdk: ">=2.7.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5" + sdk: '>=2.12.0-0 <3.0.0' + flutter: ">=1.22.0" diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index d0b09fae1304..b37b7701a14f 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -426,10 +426,10 @@ void main() { await cameraController.initialize(); when(CameraPlatform.instance.getMaxZoomLevel(mockInitializeCamera)) - .thenThrow(PlatformException( - code: 'TEST_ERROR', - message: 'This is a test error messge', - details: null)); + .thenThrow(CameraException( + 'TEST_ERROR', + 'This is a test error messge', + )); expect( cameraController.getMaxZoomLevel, @@ -526,10 +526,10 @@ void main() { await cameraController.initialize(); when(CameraPlatform.instance.getMinZoomLevel(mockInitializeCamera)) - .thenThrow(PlatformException( - code: 'TEST_ERROR', - message: 'This is a test error messge', - details: null)); + .thenThrow(CameraException( + 'TEST_ERROR', + 'This is a test error messge', + )); expect( cameraController.getMinZoomLevel, @@ -625,10 +625,10 @@ void main() { await cameraController.initialize(); when(CameraPlatform.instance.setZoomLevel(mockInitializeCamera, 42.0)) - .thenThrow(PlatformException( - code: 'TEST_ERROR', - message: 'This is a test error messge', - details: null)); + .thenThrow(CameraException( + 'TEST_ERROR', + 'This is a test error messge', + )); expect( () => cameraController.setZoomLevel(42), @@ -804,6 +804,10 @@ void main() { ResolutionPreset.max); await cameraController.initialize(); + when(CameraPlatform.instance + .getMinExposureOffset(cameraController.cameraId)) + .thenAnswer((_) => Future.value(0.0)); + await cameraController.getMinExposureOffset(); verify(CameraPlatform.instance @@ -824,10 +828,9 @@ void main() { when(CameraPlatform.instance .getMinExposureOffset(cameraController.cameraId)) .thenThrow( - PlatformException( - code: 'TEST_ERROR', - message: 'This is a test error message', - details: null, + CameraException( + 'TEST_ERROR', + 'This is a test error message', ), ); @@ -849,6 +852,10 @@ void main() { ResolutionPreset.max); await cameraController.initialize(); + when(CameraPlatform.instance + .getMaxExposureOffset(cameraController.cameraId)) + .thenAnswer((_) => Future.value(1.0)); + await cameraController.getMaxExposureOffset(); verify(CameraPlatform.instance @@ -869,10 +876,9 @@ void main() { when(CameraPlatform.instance .getMaxExposureOffset(cameraController.cameraId)) .thenThrow( - PlatformException( - code: 'TEST_ERROR', - message: 'This is a test error message', - details: null, + CameraException( + 'TEST_ERROR', + 'This is a test error message', ), ); @@ -894,10 +900,14 @@ void main() { ResolutionPreset.max); await cameraController.initialize(); + when(CameraPlatform.instance + .getExposureOffsetStepSize(cameraController.cameraId)) + .thenAnswer((_) => Future.value(0.0)); + await cameraController.getExposureOffsetStepSize(); verify(CameraPlatform.instance - .getMinExposureOffset(cameraController.cameraId)) + .getExposureOffsetStepSize(cameraController.cameraId)) .called(1); }); @@ -915,10 +925,9 @@ void main() { when(CameraPlatform.instance .getExposureOffsetStepSize(cameraController.cameraId)) .thenThrow( - PlatformException( - code: 'TEST_ERROR', - message: 'This is a test error message', - details: null, + CameraException( + 'TEST_ERROR', + 'This is a test error message', ), ); @@ -948,6 +957,9 @@ void main() { when(CameraPlatform.instance .getExposureOffsetStepSize(cameraController.cameraId)) .thenAnswer((_) async => 1.0); + when(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, 1.0)) + .thenAnswer((_) async => 1.0); await cameraController.setExposureOffset(1.0); @@ -977,10 +989,9 @@ void main() { when(CameraPlatform.instance .setExposureOffset(cameraController.cameraId, 1.0)) .thenThrow( - PlatformException( - code: 'TEST_ERROR', - message: 'This is a test error message', - details: null, + CameraException( + 'TEST_ERROR', + 'This is a test error message', ), ); @@ -1012,6 +1023,15 @@ void main() { when(CameraPlatform.instance .getExposureOffsetStepSize(cameraController.cameraId)) .thenAnswer((_) async => 1.0); + when(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, 0.0)) + .thenAnswer((_) async => 0.0); + when(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, -1.0)) + .thenAnswer((_) async => 0.0); + when(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, 2.0)) + .thenAnswer((_) async => 0.0); expect( cameraController.setExposureOffset(3.0), @@ -1028,17 +1048,18 @@ void main() { 'The provided exposure offset was outside the supported range for this device.', ))); - await cameraController.setExposureOffset(2.0); + await cameraController.setExposureOffset(0.0); await cameraController.setExposureOffset(-1.0); - await cameraController.setExposureOffset(-0.0); + await cameraController.setExposureOffset(2.0); + verify(CameraPlatform.instance - .setExposureOffset(cameraController.cameraId, 2.0)) + .setExposureOffset(cameraController.cameraId, 0.0)) .called(1); verify(CameraPlatform.instance .setExposureOffset(cameraController.cameraId, -1.0)) .called(1); verify(CameraPlatform.instance - .setExposureOffset(cameraController.cameraId, 0.0)) + .setExposureOffset(cameraController.cameraId, 2.0)) .called(1); }); @@ -1052,19 +1073,38 @@ void main() { await cameraController.initialize(); when(CameraPlatform.instance .getMinExposureOffset(cameraController.cameraId)) - .thenAnswer((_) async => -1.0); + .thenAnswer((_) async => -1.2); when(CameraPlatform.instance .getMaxExposureOffset(cameraController.cameraId)) - .thenAnswer((_) async => 1.0); + .thenAnswer((_) async => 1.2); when(CameraPlatform.instance .getExposureOffsetStepSize(cameraController.cameraId)) .thenAnswer((_) async => 0.4); + when(CameraPlatform.instance - .setExposureOffset(cameraController.cameraId, 1.0)) - .thenAnswer((_) async => 1.0); + .setExposureOffset(cameraController.cameraId, -1.2)) + .thenAnswer((_) async => -1.2); + when(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, -0.8)) + .thenAnswer((_) async => -0.8); + when(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, -0.4)) + .thenAnswer((_) async => -0.4); + when(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, 0.0)) + .thenAnswer((_) async => 0.0); + when(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, 0.4)) + .thenAnswer((_) async => 0.4); + when(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, 0.8)) + .thenAnswer((_) async => 0.8); + when(CameraPlatform.instance + .setExposureOffset(cameraController.cameraId, 1.2)) + .thenAnswer((_) async => 1.2); - await cameraController.setExposureOffset(1.0); - await cameraController.setExposureOffset(-1.0); + await cameraController.setExposureOffset(1.2); + await cameraController.setExposureOffset(-1.2); await cameraController.setExposureOffset(0.1); await cameraController.setExposureOffset(0.2); await cameraController.setExposureOffset(0.3); @@ -1082,10 +1122,10 @@ void main() { verify(CameraPlatform.instance .setExposureOffset(cameraController.cameraId, 0.8)) - .called(3); + .called(2); verify(CameraPlatform.instance .setExposureOffset(cameraController.cameraId, -0.8)) - .called(3); + .called(2); verify(CameraPlatform.instance .setExposureOffset(cameraController.cameraId, 0.0)) .called(2); @@ -1203,8 +1243,22 @@ class MockCameraPlatform extends Mock with MockPlatformInterfaceMixin implements CameraPlatform { @override - Future initializeCamera(int cameraId, - {ImageFormatGroup imageFormatGroup}); + Future initializeCamera( + int? cameraId, { + ImageFormatGroup? imageFormatGroup = ImageFormatGroup.unknown, + }) async => + super.noSuchMethod(Invocation.method( + #initializeCamera, + [cameraId], + { + #imageFormatGroup: imageFormatGroup, + }, + )); + + @override + Future dispose(int? cameraId) async { + return super.noSuchMethod(Invocation.method(#dispose, [cameraId])); + } @override Future> availableCameras() => @@ -1213,8 +1267,8 @@ class MockCameraPlatform extends Mock @override Future createCamera( CameraDescription description, - ResolutionPreset resolutionPreset, { - bool enableAudio, + ResolutionPreset? resolutionPreset, { + bool enableAudio = true, }) => mockPlatformException ? throw PlatformException(code: 'foo', message: 'bar') @@ -1241,13 +1295,92 @@ class MockCameraPlatform extends Mock ? throw PlatformException(code: 'foo', message: 'bar') : Future.value(mockTakePicture); + @override + Future prepareForVideoRecording() async => + super.noSuchMethod(Invocation.method(#prepareForVideoRecording, null)); + @override Future startVideoRecording(int cameraId, - {Duration maxVideoDuration}) => + {Duration? maxVideoDuration}) => Future.value(mockVideoRecordingXFile); + + @override + Future lockCaptureOrientation( + int? cameraId, DeviceOrientation? orientation) async => + super.noSuchMethod( + Invocation.method(#lockCaptureOrientation, [cameraId, orientation])); + + @override + Future unlockCaptureOrientation(int? cameraId) async => super + .noSuchMethod(Invocation.method(#unlockCaptureOrientation, [cameraId])); + + @override + Future getMaxZoomLevel(int? cameraId) async => super.noSuchMethod( + Invocation.method(#getMaxZoomLevel, [cameraId]), + returnValue: 1.0, + ); + + @override + Future getMinZoomLevel(int? cameraId) async => super.noSuchMethod( + Invocation.method(#getMinZoomLevel, [cameraId]), + returnValue: 0.0, + ); + + @override + Future setZoomLevel(int? cameraId, double? zoom) async => + super.noSuchMethod(Invocation.method(#setZoomLevel, [cameraId, zoom])); + + @override + Future setFlashMode(int? cameraId, FlashMode? mode) async => + super.noSuchMethod(Invocation.method(#setFlashMode, [cameraId, mode])); + + @override + Future setExposureMode(int? cameraId, ExposureMode? mode) async => + super.noSuchMethod(Invocation.method(#setExposureMode, [cameraId, mode])); + + @override + Future setExposurePoint(int? cameraId, Point? point) async => + super.noSuchMethod( + Invocation.method(#setExposurePoint, [cameraId, point])); + + @override + Future getMinExposureOffset(int? cameraId) async => + super.noSuchMethod( + Invocation.method(#getMinExposureOffset, [cameraId]), + returnValue: 0.0, + ); + + @override + Future getMaxExposureOffset(int? cameraId) async => + super.noSuchMethod( + Invocation.method(#getMaxExposureOffset, [cameraId]), + returnValue: 1.0, + ); + + @override + Future getExposureOffsetStepSize(int? cameraId) async => + super.noSuchMethod( + Invocation.method(#getExposureOffsetStepSize, [cameraId]), + returnValue: 1.0, + ); + + @override + Future setExposureOffset(int? cameraId, double? offset) async => + super.noSuchMethod( + Invocation.method(#setExposureOffset, [cameraId, offset]), + returnValue: 1.0, + ); } class MockCameraDescription extends CameraDescription { + /// Creates a new camera description with the given properties. + MockCameraDescription() + : super( + name: 'Test', + lensDirection: CameraLensDirection.back, + sensorOrientation: 0, + ); + @override CameraLensDirection get lensDirection => CameraLensDirection.back; diff --git a/packages/camera/camera/test/camera_value_test.dart b/packages/camera/camera/test/camera_value_test.dart index c365f6ddb9de..de7971d963c0 100644 --- a/packages/camera/camera/test/camera_value_test.dart +++ b/packages/camera/camera/test/camera_value_test.dart @@ -24,9 +24,11 @@ void main() { flashMode: FlashMode.auto, exposureMode: ExposureMode.auto, exposurePointSupported: true, + focusMode: FocusMode.auto, deviceOrientation: DeviceOrientation.portraitUp, lockedCaptureOrientation: DeviceOrientation.portraitUp, recordingOrientation: DeviceOrientation.portraitUp, + focusPointSupported: true, ); expect(cameraValue, isA()); @@ -58,8 +60,9 @@ void main() { expect(cameraValue.isTakingPicture, isFalse); expect(cameraValue.isStreamingImages, isFalse); expect(cameraValue.flashMode, FlashMode.auto); - expect(cameraValue.exposureMode, null); + expect(cameraValue.exposureMode, ExposureMode.auto); expect(cameraValue.exposurePointSupported, false); + expect(cameraValue.focusMode, FocusMode.auto); expect(cameraValue.deviceOrientation, DeviceOrientation.portraitUp); expect(cameraValue.lockedCaptureOrientation, null); expect(cameraValue.recordingOrientation, null); @@ -78,7 +81,8 @@ void main() { expect(cameraValue.isTakingPicture, isFalse); expect(cameraValue.isStreamingImages, isFalse); expect(cameraValue.flashMode, FlashMode.auto); - expect(cameraValue.exposureMode, null); + expect(cameraValue.focusMode, FocusMode.auto); + expect(cameraValue.exposureMode, ExposureMode.auto); expect(cameraValue.exposurePointSupported, false); expect(cameraValue.deviceOrientation, DeviceOrientation.portraitUp); expect(cameraValue.lockedCaptureOrientation, null); diff --git a/packages/camera/camera/test/utils/method_channel_mock.dart b/packages/camera/camera/test/utils/method_channel_mock.dart index cdf393f82b5f..fdbd9a18f29c 100644 --- a/packages/camera/camera/test/utils/method_channel_mock.dart +++ b/packages/camera/camera/test/utils/method_channel_mock.dart @@ -5,15 +5,15 @@ import 'package:flutter/services.dart'; class MethodChannelMock { - final Duration delay; + final Duration? delay; final MethodChannel methodChannel; final Map methods; final log = []; MethodChannelMock({ - String channelName, + required String channelName, this.delay, - this.methods, + required this.methods, }) : methodChannel = MethodChannel(channelName) { methodChannel.setMockMethodCallHandler(_handler); } diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index a2c22c67948a..9a8f771352ad 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -9,6 +9,7 @@ readonly NNBD_PLUGINS_LIST=( "android_intent" "battery" "camera" + "camera_platform_interface" "connectivity" "cross_file" "device_info" @@ -38,8 +39,8 @@ readonly NNBD_PLUGINS_LIST=( # building the all plugins app. This list should be kept empty. readonly NON_NNBD_PLUGINS_LIST=( - "camera" - "google_maps_flutter" # half migrated + #"camera" + "google_maps_flutter" # "image_picker" # "in_app_purchase" # "quick_actions" From 907d8d3e90131f10d6b9dc8fbb3115201f1441ba Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Tue, 16 Feb 2021 06:41:53 -0800 Subject: [PATCH 0136/1565] Fix the build-all exclusion list (#3552) build_all_plugins_app.sh contains an exclusion list, which currently contains almost all of the non-app-facing plugins. However, the script those exclusions are passed to expects federated plugin exclusions to be of the form plugin_name/plugin_name_subplugin_name, not just plugin_name_subplugin_name, so in practice almost nothing on that list has actually been doing anything. This fixes the script to allow either mode of exclusion (since clearly people expect using just the name to work), and scrubs everything from the list that clearly wasn't actually needed. --- script/build_all_plugins_app.sh | 42 ++++++++++----------------------- script/nnbd_plugins.sh | 9 ++----- script/tool/lib/src/common.dart | 2 ++ 3 files changed, 16 insertions(+), 37 deletions(-) diff --git a/script/build_all_plugins_app.sh b/script/build_all_plugins_app.sh index 399f1f1b79f7..0cd6f4888e79 100755 --- a/script/build_all_plugins_app.sh +++ b/script/build_all_plugins_app.sh @@ -18,37 +18,19 @@ source "$SCRIPT_DIR/nnbd_plugins.sh" check_changed_packages > /dev/null +# This list should be kept as short as possible, and things should remain here +# only as long as necessary, since in general the goal is for all of the latest +# versions of plugins to be mutually compatible. +# +# An example use case for this list would be to temporarily add plugins while +# updating multiple plugins for a breaking change in a common dependency in +# cases where using a relaxed version constraint isn't possible. readonly EXCLUDED_PLUGINS_LIST=( - "connectivity_macos" - "connectivity_platform_interface" - "connectivity_web" - "extension_google_sign_in_as_googleapis_auth" - "file_selector" # currently out of sync with camera - "flutter_plugin_android_lifecycle" - "google_maps_flutter_platform_interface" - "google_maps_flutter_web" - "google_sign_in_platform_interface" - "google_sign_in_web" - "image_picker_platform_interface" - "image_picker" - "instrumentation_adapter" - "local_auth" # flutter_plugin_android_lifecycle conflict - "path_provider_linux" - "path_provider_macos" - "path_provider_platform_interface" - "path_provider_web" - "plugin_platform_interface" - "shared_preferences_linux" - "shared_preferences_macos" - "shared_preferences_platform_interface" - "shared_preferences_web" - "shared_preferences_windows" - "url_launcher_linux" - "url_launcher_macos" - "url_launcher_platform_interface" - "url_launcher_web" - "video_player_platform_interface" - "video_player_web" + # "file_selector" # currently out of sync with camera + # "flutter_plugin_android_lifecycle" + # "image_picker" + # "local_auth" # flutter_plugin_android_lifecycle conflict + "plugin_platform_interface" # This should never be a direct app dependency. ) # Comma-separated string of the list above readonly EXCLUDED=$(IFS=, ; echo "${EXCLUDED_PLUGINS_LIST[*]}") diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index 9a8f771352ad..112dccfcbba8 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -39,13 +39,8 @@ readonly NNBD_PLUGINS_LIST=( # building the all plugins app. This list should be kept empty. readonly NON_NNBD_PLUGINS_LIST=( - #"camera" - "google_maps_flutter" - # "image_picker" - # "in_app_purchase" - # "quick_actions" - # "sensors" - # "wifi_info_flutter" + "extension_google_sign_in_as_googleapis_auth" + "google_maps_flutter" # partially migrated ) export EXCLUDED_PLUGINS_FROM_STABLE=$(IFS=, ; echo "${NNBD_PLUGINS_LIST[*]}") diff --git a/script/tool/lib/src/common.dart b/script/tool/lib/src/common.dart index 78b91ee8a75b..08622df281b4 100644 --- a/script/tool/lib/src/common.dart +++ b/script/tool/lib/src/common.dart @@ -294,8 +294,10 @@ abstract class PluginCommand extends Command { // passed. final String relativePath = p.relative(subdir.path, from: packagesDir.path); + final String packageName = p.basename(subdir.path); final String basenamePath = p.basename(entity.path); if (!excludedPlugins.contains(basenamePath) && + !excludedPlugins.contains(packageName) && !excludedPlugins.contains(relativePath) && (plugins.isEmpty || plugins.contains(relativePath) || From 9136b68bd1b11b01515f82d35660530af552c2f2 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Tue, 16 Feb 2021 09:16:47 -0800 Subject: [PATCH 0137/1565] [path_provider] Update Windows implementation version (#3541) --- packages/path_provider/path_provider/CHANGELOG.md | 5 +++++ packages/path_provider/path_provider/pubspec.yaml | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/path_provider/path_provider/CHANGELOG.md b/packages/path_provider/path_provider/CHANGELOG.md index 7364305333cf..a52711bf0736 100644 --- a/packages/path_provider/path_provider/CHANGELOG.md +++ b/packages/path_provider/path_provider/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.0.0-nullsafety.1 + +* Require latest path_provider_windows to avoid potential issues + with breaking changes in `ffi` and `win32`. + ## 2.0.0-nullsafety * Migrate to null safety. diff --git a/packages/path_provider/path_provider/pubspec.yaml b/packages/path_provider/path_provider/pubspec.yaml index 6c4c851d8103..3d79c99e2223 100644 --- a/packages/path_provider/path_provider/pubspec.yaml +++ b/packages/path_provider/path_provider/pubspec.yaml @@ -1,7 +1,7 @@ name: path_provider description: Flutter plugin for getting commonly used locations on host platform file systems, such as the temp and app data directories. homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider -version: 2.0.0-nullsafety +version: 2.0.0-nullsafety.1 flutter: plugin: @@ -24,7 +24,7 @@ dependencies: path_provider_platform_interface: ^2.0.0-nullsafety path_provider_macos: ^0.0.5-nullsafety path_provider_linux: ^0.2.0-nullsafety - path_provider_windows: ^0.1.0-nullsafety + path_provider_windows: ^0.1.0-nullsafety.3 dev_dependencies: integration_test: From 7a3b4ae8c3d96cd2ef49bdbe5db04f5d2fdc8e24 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Tue, 16 Feb 2021 10:48:46 -0800 Subject: [PATCH 0138/1565] [google_maps_flutter] Fix CameraPosition regression (#3547) The nullability conversion added a type check when recreating a CameraPosition from JSON that was too restrictive, and regressed the app-facing package. This relaxes that assertion, and adds a test to catch the issue. --- .../CHANGELOG.md | 4 ++++ .../lib/src/types/camera.dart | 2 +- .../pubspec.yaml | 2 +- .../test/types/camera_test.dart | 23 +++++++++++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md index c530c31e488d..7b2268395caf 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.1 + +* Fix overly-restrictive type check. + ## 2.0.0-nullsafety * Migrated to null-safety. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart index bdb039572624..28acf35962b6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart @@ -72,7 +72,7 @@ class CameraPosition { /// /// Mainly for internal use. static CameraPosition? fromMap(Object? json) { - if (json == null || !(json is Map)) { + if (json == null || !(json is Map)) { return null; } final LatLng? target = LatLng.fromJson(json['target']); diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml index 8b31feeb94a2..2ec9e449a335 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the google_maps_flutter plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0-nullsafety +version: 2.0.0-nullsafety.1 dependencies: flutter: diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart new file mode 100644 index 000000000000..3b6d237e05d4 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart @@ -0,0 +1,23 @@ +// 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. + +import 'package:flutter_test/flutter_test.dart'; + +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + test('toMap / fromMap', () { + final cameraPosition = CameraPosition( + target: LatLng(10.0, 15.0), bearing: 0.5, tilt: 30.0, zoom: 1.5); + // Cast to to ensure that recreating from JSON, where + // type information will have likely been lost, still works. + final json = (cameraPosition.toMap() as Map) + .cast(); + final cameraPositionFromJson = CameraPosition.fromMap(json); + + expect(cameraPosition, cameraPositionFromJson); + }); +} From 4df088098be04f9b26be528bc3f250aca9a76d27 Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Tue, 16 Feb 2021 11:41:46 -0800 Subject: [PATCH 0139/1565] [url_launcher_web] Migrate to null-safety (#3522) This version uses auto-generated Mocks from mockito5 for its tests. For now, tests only run in the `master` channel. Co-authored-by: Maurits van Beusekom --- analysis_options.yaml | 1 + .../url_launcher_web/CHANGELOG.md | 4 + .../url_launcher_web/example/README.md | 31 + .../url_launcher_web/example/build.yaml | 6 + .../integration_test/link_widget_test.dart | 150 ++++ .../url_launcher_web_test.dart} | 178 +---- .../url_launcher_web_test.mocks.dart | 660 ++++++++++++++++++ .../{test => example}/lib/main.dart | 0 .../{test => example}/pubspec.yaml | 16 +- .../url_launcher_web/example/run_test.sh | 23 + .../test_driver/integration_test_driver.dart} | 1 - .../{test => example}/web/index.html | 0 .../url_launcher_web/lib/src/link.dart | 54 +- .../lib/url_launcher_web.dart | 20 +- .../url_launcher_web/pubspec.yaml | 28 +- .../url_launcher_web/test/README.md | 18 +- .../url_launcher_web/test/run_test | 17 - .../test/tests_exist_elsewhere_test.dart | 10 + 18 files changed, 956 insertions(+), 261 deletions(-) create mode 100644 packages/url_launcher/url_launcher_web/example/README.md create mode 100644 packages/url_launcher/url_launcher_web/example/build.yaml create mode 100644 packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart rename packages/url_launcher/url_launcher_web/{test/test_driver/url_launcher_web_integration.dart => example/integration_test/url_launcher_web_test.dart} (53%) create mode 100644 packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart rename packages/url_launcher/url_launcher_web/{test => example}/lib/main.dart (100%) rename packages/url_launcher/url_launcher_web/{test => example}/pubspec.yaml (61%) create mode 100755 packages/url_launcher/url_launcher_web/example/run_test.sh rename packages/url_launcher/url_launcher_web/{test/test_driver/url_launcher_web_integration_test.dart => example/test_driver/integration_test_driver.dart} (94%) rename packages/url_launcher/url_launcher_web/{test => example}/web/index.html (100%) delete mode 100755 packages/url_launcher/url_launcher_web/test/run_test create mode 100644 packages/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart diff --git a/analysis_options.yaml b/analysis_options.yaml index 47cdbd2f98dc..2b62a6a9e2b9 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -4,6 +4,7 @@ analyzer: # Ignore generated files - '**/*.g.dart' - 'lib/src/generated/*.dart' + - '**/*.mocks.dart' # Mockito @GenerateMocks errors: always_require_non_null_named_parameters: false # not needed with nnbd unnecessary_null_comparison: false # Turned as long as nnbd mix-mode is supported. diff --git a/packages/url_launcher/url_launcher_web/CHANGELOG.md b/packages/url_launcher/url_launcher_web/CHANGELOG.md index 0416c033bf2b..49d72457ecd9 100644 --- a/packages/url_launcher/url_launcher_web/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_web/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.0.0-nullsafety + +- Migrate to null safety. + # 0.1.5+3 - Fix Link misalignment [issue](https://github.com/flutter/flutter/issues/70053). diff --git a/packages/url_launcher/url_launcher_web/example/README.md b/packages/url_launcher/url_launcher_web/example/README.md new file mode 100644 index 000000000000..b75df09c33f1 --- /dev/null +++ b/packages/url_launcher/url_launcher_web/example/README.md @@ -0,0 +1,31 @@ +# Testing + +This package utilizes the `integration_test` package to run its tests in a web browser. + +See [flutter.dev > Integration testing](https://flutter.dev/docs/testing/integration-tests) for more info. + +## Running the tests + +Make sure you have updated to the latest Flutter master. + +1. Check what version of Chrome is running on the machine you're running tests on. + +2. Download and install driver for that version from here: + * + +3. Start the driver using `chromedriver --port=4444` + +4. Run tests: `flutter drive -d web-server --browser-name=chrome --driver=test_driver/integration_test_driver.dart --target=integration_test/TEST_NAME.dart`, or (in Linux): + + * Single: `./run_test.sh integration_test/TEST_NAME.dart` + * All: `./run_test.sh` + +## Mocks + +There's `.mocks.dart` files next to the test files that use them. + +They're [generated by Mockito](https://github.com/dart-lang/mockito/blob/master/NULL_SAFETY_README.md#code-generation). + +Mocks might be manually re-generated with the following command: `flutter pub run build_runner build`. If there are any changes in the mocks, feel free to commit them. + +(Mocks will be auto-generated by the `run_test.sh` script as well.) diff --git a/packages/url_launcher/url_launcher_web/example/build.yaml b/packages/url_launcher/url_launcher_web/example/build.yaml new file mode 100644 index 000000000000..db3104bb04c6 --- /dev/null +++ b/packages/url_launcher/url_launcher_web/example/build.yaml @@ -0,0 +1,6 @@ +targets: + $default: + sources: + - integration_test/*.dart + - lib/$lib$ + - $package$ diff --git a/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart b/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart new file mode 100644 index 000000000000..3c1dbd8b1b89 --- /dev/null +++ b/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart @@ -0,0 +1,150 @@ +// Copyright 2019 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. + +import 'dart:html' as html; +import 'dart:js_util'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:url_launcher_platform_interface/link.dart'; +import 'package:url_launcher_web/src/link.dart'; +import 'package:integration_test/integration_test.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('Link Widget', () { + testWidgets('creates anchor with correct attributes', + (WidgetTester tester) async { + final Uri uri = Uri.parse('http://foobar/example?q=1'); + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: WebLinkDelegate(TestLinkInfo( + uri: uri, + target: LinkTarget.blank, + builder: (BuildContext context, FollowLink? followLink) { + return Container(width: 100, height: 100); + }, + )), + )); + // Platform view creation happens asynchronously. + await tester.pumpAndSettle(); + + final html.Element anchor = _findSingleAnchor(); + expect(anchor.getAttribute('href'), uri.toString()); + expect(anchor.getAttribute('target'), '_blank'); + + final Uri uri2 = Uri.parse('http://foobar2/example?q=2'); + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: WebLinkDelegate(TestLinkInfo( + uri: uri2, + target: LinkTarget.self, + builder: (BuildContext context, FollowLink? followLink) { + return Container(width: 100, height: 100); + }, + )), + )); + await tester.pumpAndSettle(); + + // Check that the same anchor has been updated. + expect(anchor.getAttribute('href'), uri2.toString()); + expect(anchor.getAttribute('target'), '_self'); + }); + + testWidgets('sizes itself correctly', (WidgetTester tester) async { + final Key containerKey = GlobalKey(); + final Uri uri = Uri.parse('http://foobar'); + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: ConstrainedBox( + constraints: BoxConstraints.tight(Size(100.0, 100.0)), + child: WebLinkDelegate(TestLinkInfo( + uri: uri, + target: LinkTarget.blank, + builder: (BuildContext context, FollowLink? followLink) { + return Container( + key: containerKey, + child: SizedBox(width: 50.0, height: 50.0), + ); + }, + )), + ), + ), + )); + await tester.pumpAndSettle(); + + final Size containerSize = tester.getSize(find.byKey(containerKey)); + // The Stack widget inserted by the `WebLinkDelegate` shouldn't loosen the + // constraints before passing them to the inner container. So the inner + // container should respect the tight constraints given by the ancestor + // `ConstrainedBox` widget. + expect(containerSize.width, 100.0); + expect(containerSize.height, 100.0); + }); + + // See: https://github.com/flutter/plugins/pull/3522#discussion_r574703724 + testWidgets('uri can be null', (WidgetTester tester) async { + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: WebLinkDelegate(TestLinkInfo( + uri: null, + target: LinkTarget.defaultTarget, + builder: (BuildContext context, FollowLink? followLink) { + return Container(width: 100, height: 100); + }, + )), + )); + // Platform view creation happens asynchronously. + await tester.pumpAndSettle(); + + final html.Element anchor = _findSingleAnchor(); + expect(anchor.hasAttribute('href'), false); + }); + }); +} + +html.Element _findSingleAnchor() { + final List foundAnchors = []; + for (final html.Element anchor in html.document.querySelectorAll('a')) { + if (hasProperty(anchor, linkViewIdProperty)) { + foundAnchors.add(anchor); + } + } + + // Search inside platform views with shadow roots as well. + for (final html.Element platformView + in html.document.querySelectorAll('flt-platform-view')) { + final html.ShadowRoot shadowRoot = platformView.shadowRoot!; + if (shadowRoot != null) { + for (final html.Element anchor in shadowRoot.querySelectorAll('a')) { + if (hasProperty(anchor, linkViewIdProperty)) { + foundAnchors.add(anchor); + } + } + } + } + + return foundAnchors.single; +} + +class TestLinkInfo extends LinkInfo { + @override + final LinkWidgetBuilder builder; + + @override + final Uri? uri; + + @override + final LinkTarget target; + + @override + bool get isDisabled => uri == null; + + TestLinkInfo({ + required this.uri, + required this.target, + required this.builder, + }); +} diff --git a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart similarity index 53% rename from packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart rename to packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart index bfa94821e41a..f7ea35667530 100644 --- a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration.dart +++ b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart @@ -2,35 +2,36 @@ // 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; -import 'dart:js_util'; -import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:url_launcher_platform_interface/link.dart'; +import 'package:mockito/annotations.dart'; import 'package:url_launcher_web/url_launcher_web.dart'; -import 'package:url_launcher_web/src/link.dart'; import 'package:mockito/mockito.dart'; import 'package:integration_test/integration_test.dart'; -class _MockWindow extends Mock implements html.Window {} - -class _MockNavigator extends Mock implements html.Navigator {} +import 'url_launcher_web_test.mocks.dart'; +@GenerateMocks([html.Window, html.Navigator]) void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('UrlLauncherPlugin', () { - _MockWindow mockWindow; - _MockNavigator mockNavigator; + late MockWindow mockWindow; + late MockNavigator mockNavigator; - UrlLauncherPlugin plugin; + late UrlLauncherPlugin plugin; setUp(() { - mockWindow = _MockWindow(); - mockNavigator = _MockNavigator(); + mockWindow = MockWindow(); + mockNavigator = MockNavigator(); when(mockWindow.navigator).thenReturn(mockNavigator); + // Simulate that window.open does something. + when(mockWindow.open(any, any)).thenReturn(MockWindow()); + + when(mockNavigator.vendor).thenReturn('Google LLC'); + when(mockNavigator.appVersion).thenReturn('Mock version!'); + plugin = UrlLauncherPlugin(debugWindow: mockWindow); }); @@ -60,27 +61,10 @@ void main() { }); group('launch', () { - setUp(() { - // Simulate that window.open does something. - when(mockWindow.open('https://www.google.com', '')) - .thenReturn(_MockWindow()); - when(mockWindow.open('mailto:name@mydomain.com', '')) - .thenReturn(_MockWindow()); - when(mockWindow.open('tel:5551234567', '')).thenReturn(_MockWindow()); - when(mockWindow.open('sms:+19725551212?body=hello%20there', '')) - .thenReturn(_MockWindow()); - }); - testWidgets('launching a URL returns true', (WidgetTester _) async { expect( plugin.launch( 'https://www.google.com', - useSafariVC: null, - useWebView: null, - universalLinksOnly: null, - enableDomStorage: null, - enableJavaScript: null, - headers: null, ), completion(isTrue)); }); @@ -89,12 +73,6 @@ void main() { expect( plugin.launch( 'mailto:name@mydomain.com', - useSafariVC: null, - useWebView: null, - universalLinksOnly: null, - enableDomStorage: null, - enableJavaScript: null, - headers: null, ), completion(isTrue)); }); @@ -103,12 +81,6 @@ void main() { expect( plugin.launch( 'tel:5551234567', - useSafariVC: null, - useWebView: null, - universalLinksOnly: null, - enableDomStorage: null, - enableJavaScript: null, - headers: null, ), completion(isTrue)); }); @@ -117,12 +89,6 @@ void main() { expect( plugin.launch( 'sms:+19725551212?body=hello%20there', - useSafariVC: null, - useWebView: null, - universalLinksOnly: null, - enableDomStorage: null, - enableJavaScript: null, - headers: null, ), completion(isTrue)); }); @@ -233,120 +199,4 @@ void main() { }); }); }); - - group('link', () { - testWidgets('creates anchor with correct attributes', - (WidgetTester tester) async { - final Uri uri = Uri.parse('http://foobar/example?q=1'); - await tester.pumpWidget(Directionality( - textDirection: TextDirection.ltr, - child: WebLinkDelegate(TestLinkInfo( - uri: uri, - target: LinkTarget.blank, - builder: (BuildContext context, FollowLink followLink) { - return Container(width: 100, height: 100); - }, - )), - )); - // Platform view creation happens asynchronously. - await tester.pumpAndSettle(); - - final html.Element anchor = _findSingleAnchor(); - expect(anchor.getAttribute('href'), uri.toString()); - expect(anchor.getAttribute('target'), '_blank'); - - final Uri uri2 = Uri.parse('http://foobar2/example?q=2'); - await tester.pumpWidget(Directionality( - textDirection: TextDirection.ltr, - child: WebLinkDelegate(TestLinkInfo( - uri: uri2, - target: LinkTarget.self, - builder: (BuildContext context, FollowLink followLink) { - return Container(width: 100, height: 100); - }, - )), - )); - await tester.pumpAndSettle(); - - // Check that the same anchor has been updated. - expect(anchor.getAttribute('href'), uri2.toString()); - expect(anchor.getAttribute('target'), '_self'); - }); - - testWidgets('sizes itself correctly', (WidgetTester tester) async { - final Key containerKey = GlobalKey(); - final Uri uri = Uri.parse('http://foobar'); - await tester.pumpWidget(Directionality( - textDirection: TextDirection.ltr, - child: Center( - child: ConstrainedBox( - constraints: BoxConstraints.tight(Size(100.0, 100.0)), - child: WebLinkDelegate(TestLinkInfo( - uri: uri, - target: LinkTarget.blank, - builder: (BuildContext context, FollowLink followLink) { - return Container( - key: containerKey, - child: SizedBox(width: 50.0, height: 50.0), - ); - }, - )), - ), - ), - )); - await tester.pumpAndSettle(); - - final Size containerSize = tester.getSize(find.byKey(containerKey)); - // The Stack widget inserted by the `WebLinkDelegate` shouldn't loosen the - // constraints before passing them to the inner container. So the inner - // container should respect the tight constraints given by the ancestor - // `ConstrainedBox` widget. - expect(containerSize.width, 100.0); - expect(containerSize.height, 100.0); - }); - }); -} - -html.Element _findSingleAnchor() { - final List foundAnchors = []; - for (final html.Element anchor in html.document.querySelectorAll('a')) { - if (hasProperty(anchor, linkViewIdProperty)) { - foundAnchors.add(anchor); - } - } - - // Search inside platform views with shadow roots as well. - for (final html.Element platformView - in html.document.querySelectorAll('flt-platform-view')) { - final html.ShadowRoot shadowRoot = platformView.shadowRoot; - if (shadowRoot != null) { - for (final html.Element anchor in shadowRoot.querySelectorAll('a')) { - if (hasProperty(anchor, linkViewIdProperty)) { - foundAnchors.add(anchor); - } - } - } - } - - return foundAnchors.single; -} - -class TestLinkInfo extends LinkInfo { - @override - final LinkWidgetBuilder builder; - - @override - final Uri uri; - - @override - final LinkTarget target; - - @override - bool get isDisabled => uri == null; - - TestLinkInfo({ - @required this.uri, - @required this.target, - @required this.builder, - }); } diff --git a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart new file mode 100644 index 000000000000..73d3bf355d67 --- /dev/null +++ b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart @@ -0,0 +1,660 @@ +import 'dart:async' as _i4; +import 'dart:html' as _i2; +import 'dart:math' as _i5; +import 'dart:web_sql' as _i3; + +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: comment_references + +// ignore_for_file: unnecessary_parenthesis + +class _FakeDocument extends _i1.Fake implements _i2.Document {} + +class _FakeLocation extends _i1.Fake implements _i2.Location {} + +class _FakeConsole extends _i1.Fake implements _i2.Console {} + +class _FakeHistory extends _i1.Fake implements _i2.History {} + +class _FakeStorage extends _i1.Fake implements _i2.Storage {} + +class _FakeNavigator extends _i1.Fake implements _i2.Navigator {} + +class _FakePerformance extends _i1.Fake implements _i2.Performance {} + +class _FakeEvents extends _i1.Fake implements _i2.Events {} + +class _FakeType extends _i1.Fake implements Type {} + +class _FakeWindowBase extends _i1.Fake implements _i2.WindowBase {} + +class _FakeFileSystem extends _i1.Fake implements _i2.FileSystem {} + +class _FakeStylePropertyMapReadonly extends _i1.Fake + implements _i2.StylePropertyMapReadonly {} + +class _FakeMediaQueryList extends _i1.Fake implements _i2.MediaQueryList {} + +class _FakeEntry extends _i1.Fake implements _i2.Entry {} + +class _FakeSqlDatabase extends _i1.Fake implements _i3.SqlDatabase {} + +class _FakeGeolocation extends _i1.Fake implements _i2.Geolocation {} + +class _FakeMediaStream extends _i1.Fake implements _i2.MediaStream {} + +class _FakeRelatedApplication extends _i1.Fake + implements _i2.RelatedApplication {} + +/// A class which mocks [Window]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockWindow extends _i1.Mock implements _i2.Window { + MockWindow() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future get animationFrame => + (super.noSuchMethod(Invocation.getter(#animationFrame), Future.value(0)) + as _i4.Future); + @override + _i2.Document get document => + (super.noSuchMethod(Invocation.getter(#document), _FakeDocument()) + as _i2.Document); + @override + _i2.Location get location => + (super.noSuchMethod(Invocation.getter(#location), _FakeLocation()) + as _i2.Location); + @override + set location(_i2.LocationBase? value) => + super.noSuchMethod(Invocation.setter(#location, value)); + @override + _i2.Console get console => + (super.noSuchMethod(Invocation.getter(#console), _FakeConsole()) + as _i2.Console); + @override + num get devicePixelRatio => + (super.noSuchMethod(Invocation.getter(#devicePixelRatio), 0) as num); + @override + _i2.History get history => + (super.noSuchMethod(Invocation.getter(#history), _FakeHistory()) + as _i2.History); + @override + _i2.Storage get localStorage => + (super.noSuchMethod(Invocation.getter(#localStorage), _FakeStorage()) + as _i2.Storage); + @override + _i2.Navigator get navigator => + (super.noSuchMethod(Invocation.getter(#navigator), _FakeNavigator()) + as _i2.Navigator); + @override + int get outerHeight => + (super.noSuchMethod(Invocation.getter(#outerHeight), 0) as int); + @override + int get outerWidth => + (super.noSuchMethod(Invocation.getter(#outerWidth), 0) as int); + @override + _i2.Performance get performance => + (super.noSuchMethod(Invocation.getter(#performance), _FakePerformance()) + as _i2.Performance); + @override + _i2.Storage get sessionStorage => + (super.noSuchMethod(Invocation.getter(#sessionStorage), _FakeStorage()) + as _i2.Storage); + @override + _i4.Stream<_i2.Event> get onContentLoaded => (super.noSuchMethod( + Invocation.getter(#onContentLoaded), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onAbort => (super + .noSuchMethod(Invocation.getter(#onAbort), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onBlur => + (super.noSuchMethod(Invocation.getter(#onBlur), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onCanPlay => (super.noSuchMethod( + Invocation.getter(#onCanPlay), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onCanPlayThrough => (super.noSuchMethod( + Invocation.getter(#onCanPlayThrough), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onChange => (super + .noSuchMethod(Invocation.getter(#onChange), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.MouseEvent> get onClick => (super.noSuchMethod( + Invocation.getter(#onClick), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onContextMenu => (super.noSuchMethod( + Invocation.getter(#onContextMenu), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.Event> get onDoubleClick => (super.noSuchMethod( + Invocation.getter(#onDoubleClick), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.DeviceMotionEvent> get onDeviceMotion => (super.noSuchMethod( + Invocation.getter(#onDeviceMotion), + Stream<_i2.DeviceMotionEvent>.empty()) + as _i4.Stream<_i2.DeviceMotionEvent>); + @override + _i4.Stream<_i2.DeviceOrientationEvent> get onDeviceOrientation => + (super.noSuchMethod(Invocation.getter(#onDeviceOrientation), + Stream<_i2.DeviceOrientationEvent>.empty()) + as _i4.Stream<_i2.DeviceOrientationEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDrag => (super.noSuchMethod( + Invocation.getter(#onDrag), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDragEnd => (super.noSuchMethod( + Invocation.getter(#onDragEnd), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDragEnter => (super.noSuchMethod( + Invocation.getter(#onDragEnter), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDragLeave => (super.noSuchMethod( + Invocation.getter(#onDragLeave), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDragOver => (super.noSuchMethod( + Invocation.getter(#onDragOver), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDragStart => (super.noSuchMethod( + Invocation.getter(#onDragStart), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDrop => (super.noSuchMethod( + Invocation.getter(#onDrop), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.Event> get onDurationChange => (super.noSuchMethod( + Invocation.getter(#onDurationChange), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onEmptied => (super.noSuchMethod( + Invocation.getter(#onEmptied), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onEnded => (super + .noSuchMethod(Invocation.getter(#onEnded), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onError => (super + .noSuchMethod(Invocation.getter(#onError), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onFocus => (super + .noSuchMethod(Invocation.getter(#onFocus), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onHashChange => (super.noSuchMethod( + Invocation.getter(#onHashChange), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onInput => (super + .noSuchMethod(Invocation.getter(#onInput), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onInvalid => (super.noSuchMethod( + Invocation.getter(#onInvalid), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.KeyboardEvent> get onKeyDown => (super.noSuchMethod( + Invocation.getter(#onKeyDown), Stream<_i2.KeyboardEvent>.empty()) + as _i4.Stream<_i2.KeyboardEvent>); + @override + _i4.Stream<_i2.KeyboardEvent> get onKeyPress => (super.noSuchMethod( + Invocation.getter(#onKeyPress), Stream<_i2.KeyboardEvent>.empty()) + as _i4.Stream<_i2.KeyboardEvent>); + @override + _i4.Stream<_i2.KeyboardEvent> get onKeyUp => (super.noSuchMethod( + Invocation.getter(#onKeyUp), Stream<_i2.KeyboardEvent>.empty()) + as _i4.Stream<_i2.KeyboardEvent>); + @override + _i4.Stream<_i2.Event> get onLoad => + (super.noSuchMethod(Invocation.getter(#onLoad), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onLoadedData => (super.noSuchMethod( + Invocation.getter(#onLoadedData), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onLoadedMetadata => (super.noSuchMethod( + Invocation.getter(#onLoadedMetadata), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onLoadStart => (super.noSuchMethod( + Invocation.getter(#onLoadStart), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.MessageEvent> get onMessage => (super.noSuchMethod( + Invocation.getter(#onMessage), Stream<_i2.MessageEvent>.empty()) + as _i4.Stream<_i2.MessageEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseDown => (super.noSuchMethod( + Invocation.getter(#onMouseDown), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseEnter => (super.noSuchMethod( + Invocation.getter(#onMouseEnter), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseLeave => (super.noSuchMethod( + Invocation.getter(#onMouseLeave), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseMove => (super.noSuchMethod( + Invocation.getter(#onMouseMove), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseOut => (super.noSuchMethod( + Invocation.getter(#onMouseOut), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseOver => (super.noSuchMethod( + Invocation.getter(#onMouseOver), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseUp => (super.noSuchMethod( + Invocation.getter(#onMouseUp), Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.WheelEvent> get onMouseWheel => (super.noSuchMethod( + Invocation.getter(#onMouseWheel), Stream<_i2.WheelEvent>.empty()) + as _i4.Stream<_i2.WheelEvent>); + @override + _i4.Stream<_i2.Event> get onOffline => (super.noSuchMethod( + Invocation.getter(#onOffline), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onOnline => (super + .noSuchMethod(Invocation.getter(#onOnline), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onPageHide => (super.noSuchMethod( + Invocation.getter(#onPageHide), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onPageShow => (super.noSuchMethod( + Invocation.getter(#onPageShow), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onPause => (super + .noSuchMethod(Invocation.getter(#onPause), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onPlay => + (super.noSuchMethod(Invocation.getter(#onPlay), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onPlaying => (super.noSuchMethod( + Invocation.getter(#onPlaying), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.PopStateEvent> get onPopState => (super.noSuchMethod( + Invocation.getter(#onPopState), Stream<_i2.PopStateEvent>.empty()) + as _i4.Stream<_i2.PopStateEvent>); + @override + _i4.Stream<_i2.Event> get onProgress => (super.noSuchMethod( + Invocation.getter(#onProgress), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onRateChange => (super.noSuchMethod( + Invocation.getter(#onRateChange), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onReset => (super + .noSuchMethod(Invocation.getter(#onReset), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onResize => (super + .noSuchMethod(Invocation.getter(#onResize), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onScroll => (super + .noSuchMethod(Invocation.getter(#onScroll), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onSearch => (super + .noSuchMethod(Invocation.getter(#onSearch), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onSeeked => (super + .noSuchMethod(Invocation.getter(#onSeeked), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onSeeking => (super.noSuchMethod( + Invocation.getter(#onSeeking), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onSelect => (super + .noSuchMethod(Invocation.getter(#onSelect), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onStalled => (super.noSuchMethod( + Invocation.getter(#onStalled), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.StorageEvent> get onStorage => (super.noSuchMethod( + Invocation.getter(#onStorage), Stream<_i2.StorageEvent>.empty()) + as _i4.Stream<_i2.StorageEvent>); + @override + _i4.Stream<_i2.Event> get onSubmit => (super + .noSuchMethod(Invocation.getter(#onSubmit), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onSuspend => (super.noSuchMethod( + Invocation.getter(#onSuspend), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onTimeUpdate => (super.noSuchMethod( + Invocation.getter(#onTimeUpdate), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.TouchEvent> get onTouchCancel => (super.noSuchMethod( + Invocation.getter(#onTouchCancel), Stream<_i2.TouchEvent>.empty()) + as _i4.Stream<_i2.TouchEvent>); + @override + _i4.Stream<_i2.TouchEvent> get onTouchEnd => (super.noSuchMethod( + Invocation.getter(#onTouchEnd), Stream<_i2.TouchEvent>.empty()) + as _i4.Stream<_i2.TouchEvent>); + @override + _i4.Stream<_i2.TouchEvent> get onTouchMove => (super.noSuchMethod( + Invocation.getter(#onTouchMove), Stream<_i2.TouchEvent>.empty()) + as _i4.Stream<_i2.TouchEvent>); + @override + _i4.Stream<_i2.TouchEvent> get onTouchStart => (super.noSuchMethod( + Invocation.getter(#onTouchStart), Stream<_i2.TouchEvent>.empty()) + as _i4.Stream<_i2.TouchEvent>); + @override + _i4.Stream<_i2.TransitionEvent> get onTransitionEnd => (super.noSuchMethod( + Invocation.getter(#onTransitionEnd), + Stream<_i2.TransitionEvent>.empty()) as _i4.Stream<_i2.TransitionEvent>); + @override + _i4.Stream<_i2.Event> get onUnload => (super + .noSuchMethod(Invocation.getter(#onUnload), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onVolumeChange => (super.noSuchMethod( + Invocation.getter(#onVolumeChange), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onWaiting => (super.noSuchMethod( + Invocation.getter(#onWaiting), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.AnimationEvent> get onAnimationEnd => (super.noSuchMethod( + Invocation.getter(#onAnimationEnd), + Stream<_i2.AnimationEvent>.empty()) as _i4.Stream<_i2.AnimationEvent>); + @override + _i4.Stream<_i2.AnimationEvent> get onAnimationIteration => + (super.noSuchMethod(Invocation.getter(#onAnimationIteration), + Stream<_i2.AnimationEvent>.empty()) + as _i4.Stream<_i2.AnimationEvent>); + @override + _i4.Stream<_i2.AnimationEvent> get onAnimationStart => (super.noSuchMethod( + Invocation.getter(#onAnimationStart), + Stream<_i2.AnimationEvent>.empty()) as _i4.Stream<_i2.AnimationEvent>); + @override + _i4.Stream<_i2.Event> get onBeforeUnload => (super.noSuchMethod( + Invocation.getter(#onBeforeUnload), Stream<_i2.Event>.empty()) + as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.WheelEvent> get onWheel => (super.noSuchMethod( + Invocation.getter(#onWheel), Stream<_i2.WheelEvent>.empty()) + as _i4.Stream<_i2.WheelEvent>); + @override + int get pageXOffset => + (super.noSuchMethod(Invocation.getter(#pageXOffset), 0) as int); + @override + int get pageYOffset => + (super.noSuchMethod(Invocation.getter(#pageYOffset), 0) as int); + @override + int get scrollX => + (super.noSuchMethod(Invocation.getter(#scrollX), 0) as int); + @override + int get scrollY => + (super.noSuchMethod(Invocation.getter(#scrollY), 0) as int); + @override + _i2.Events get on => + (super.noSuchMethod(Invocation.getter(#on), _FakeEvents()) as _i2.Events); + @override + int get hashCode => + (super.noSuchMethod(Invocation.getter(#hashCode), 0) as int); + @override + Type get runtimeType => + (super.noSuchMethod(Invocation.getter(#runtimeType), _FakeType()) + as Type); + @override + _i2.WindowBase open(String? url, String? name, [String? options]) => + (super.noSuchMethod( + Invocation.method(#open, [url, name, options]), _FakeWindowBase()) + as _i2.WindowBase); + @override + int requestAnimationFrame(_i2.FrameRequestCallback? callback) => + (super.noSuchMethod( + Invocation.method(#requestAnimationFrame, [callback]), 0) as int); + @override + void cancelAnimationFrame(int? id) => + super.noSuchMethod(Invocation.method(#cancelAnimationFrame, [id])); + @override + _i4.Future<_i2.FileSystem> requestFileSystem(int? size, {bool? persistent}) => + (super.noSuchMethod( + Invocation.method( + #requestFileSystem, [size], {#persistent: persistent}), + Future.value(_FakeFileSystem())) as _i4.Future<_i2.FileSystem>); + @override + void cancelIdleCallback(int? handle) => + super.noSuchMethod(Invocation.method(#cancelIdleCallback, [handle])); + @override + bool confirm([String? message]) => + (super.noSuchMethod(Invocation.method(#confirm, [message]), false) + as bool); + @override + _i4.Future fetch(dynamic input, [Map? init]) => + (super.noSuchMethod( + Invocation.method(#fetch, [input, init]), Future.value(null)) + as _i4.Future); + @override + bool find(String? string, bool? caseSensitive, bool? backwards, bool? wrap, + bool? wholeWord, bool? searchInFrames, bool? showDialog) => + (super.noSuchMethod( + Invocation.method(#find, [ + string, + caseSensitive, + backwards, + wrap, + wholeWord, + searchInFrames, + showDialog + ]), + false) as bool); + @override + _i2.StylePropertyMapReadonly getComputedStyleMap( + _i2.Element? element, String? pseudoElement) => + (super.noSuchMethod( + Invocation.method(#getComputedStyleMap, [element, pseudoElement]), + _FakeStylePropertyMapReadonly()) as _i2.StylePropertyMapReadonly); + @override + List<_i2.CssRule> getMatchedCssRules( + _i2.Element? element, String? pseudoElement) => + (super.noSuchMethod( + Invocation.method(#getMatchedCssRules, [element, pseudoElement]), + <_i2.CssRule>[]) as List<_i2.CssRule>); + @override + _i2.MediaQueryList matchMedia(String? query) => (super.noSuchMethod( + Invocation.method(#matchMedia, [query]), _FakeMediaQueryList()) + as _i2.MediaQueryList); + @override + void moveBy(int? x, int? y) => + super.noSuchMethod(Invocation.method(#moveBy, [x, y])); + @override + void postMessage(dynamic message, String? targetOrigin, + [List? transfer]) => + super.noSuchMethod( + Invocation.method(#postMessage, [message, targetOrigin, transfer])); + @override + int requestIdleCallback(_i2.IdleRequestCallback? callback, + [Map? options]) => + (super.noSuchMethod( + Invocation.method(#requestIdleCallback, [callback, options]), 0) + as int); + @override + void resizeBy(int? x, int? y) => + super.noSuchMethod(Invocation.method(#resizeBy, [x, y])); + @override + void resizeTo(int? x, int? y) => + super.noSuchMethod(Invocation.method(#resizeTo, [x, y])); + @override + _i4.Future<_i2.Entry> resolveLocalFileSystemUrl(String? url) => + (super.noSuchMethod(Invocation.method(#resolveLocalFileSystemUrl, [url]), + Future.value(_FakeEntry())) as _i4.Future<_i2.Entry>); + @override + String atob(String? atob) => + (super.noSuchMethod(Invocation.method(#atob, [atob]), '') as String); + @override + String btoa(String? btoa) => + (super.noSuchMethod(Invocation.method(#btoa, [btoa]), '') as String); + @override + void moveTo(_i5.Point? p) => + super.noSuchMethod(Invocation.method(#moveTo, [p])); + @override + _i3.SqlDatabase openDatabase(String? name, String? version, + String? displayName, int? estimatedSize, + [_i2.DatabaseCallback? creationCallback]) => + (super.noSuchMethod( + Invocation.method(#openDatabase, + [name, version, displayName, estimatedSize, creationCallback]), + _FakeSqlDatabase()) as _i3.SqlDatabase); + @override + void addEventListener(String? type, _i2.EventListener? listener, + [bool? useCapture]) => + super.noSuchMethod( + Invocation.method(#addEventListener, [type, listener, useCapture])); + @override + void removeEventListener(String? type, _i2.EventListener? listener, + [bool? useCapture]) => + super.noSuchMethod(Invocation.method( + #removeEventListener, [type, listener, useCapture])); + @override + bool dispatchEvent(_i2.Event? event) => + (super.noSuchMethod(Invocation.method(#dispatchEvent, [event]), false) + as bool); + @override + bool operator ==(Object? other) => + (super.noSuchMethod(Invocation.method(#==, [other]), false) as bool); + @override + String toString() => + (super.noSuchMethod(Invocation.method(#toString, []), '') as String); +} + +/// A class which mocks [Navigator]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockNavigator extends _i1.Mock implements _i2.Navigator { + MockNavigator() { + _i1.throwOnMissingStub(this); + } + + @override + String get language => + (super.noSuchMethod(Invocation.getter(#language), '') as String); + @override + _i2.Geolocation get geolocation => + (super.noSuchMethod(Invocation.getter(#geolocation), _FakeGeolocation()) + as _i2.Geolocation); + @override + String get vendor => + (super.noSuchMethod(Invocation.getter(#vendor), '') as String); + @override + String get vendorSub => + (super.noSuchMethod(Invocation.getter(#vendorSub), '') as String); + @override + String get appCodeName => + (super.noSuchMethod(Invocation.getter(#appCodeName), '') as String); + @override + String get appName => + (super.noSuchMethod(Invocation.getter(#appName), '') as String); + @override + String get appVersion => + (super.noSuchMethod(Invocation.getter(#appVersion), '') as String); + @override + String get product => + (super.noSuchMethod(Invocation.getter(#product), '') as String); + @override + String get userAgent => + (super.noSuchMethod(Invocation.getter(#userAgent), '') as String); + @override + int get hashCode => + (super.noSuchMethod(Invocation.getter(#hashCode), 0) as int); + @override + Type get runtimeType => + (super.noSuchMethod(Invocation.getter(#runtimeType), _FakeType()) + as Type); + @override + List<_i2.Gamepad?> getGamepads() => + (super.noSuchMethod(Invocation.method(#getGamepads, []), <_i2.Gamepad?>[]) + as List<_i2.Gamepad?>); + @override + _i4.Future<_i2.MediaStream> getUserMedia({dynamic audio, dynamic video}) => + (super.noSuchMethod( + Invocation.method(#getUserMedia, [], {#audio: audio, #video: video}), + Future.value(_FakeMediaStream())) as _i4.Future<_i2.MediaStream>); + @override + _i4.Future getBattery() => (super + .noSuchMethod(Invocation.method(#getBattery, []), Future.value(null)) + as _i4.Future); + @override + _i4.Future<_i2.RelatedApplication> getInstalledRelatedApps() => + (super.noSuchMethod(Invocation.method(#getInstalledRelatedApps, []), + Future.value(_FakeRelatedApplication())) + as _i4.Future<_i2.RelatedApplication>); + @override + _i4.Future getVRDisplays() => (super.noSuchMethod( + Invocation.method(#getVRDisplays, []), Future.value(null)) + as _i4.Future); + @override + void registerProtocolHandler(String? scheme, String? url, String? title) => + super.noSuchMethod( + Invocation.method(#registerProtocolHandler, [scheme, url, title])); + @override + _i4.Future requestKeyboardLock([List? keyCodes]) => + (super.noSuchMethod(Invocation.method(#requestKeyboardLock, [keyCodes]), + Future.value(null)) as _i4.Future); + @override + _i4.Future requestMidiAccess([Map? options]) => + (super.noSuchMethod(Invocation.method(#requestMidiAccess, [options]), + Future.value(null)) as _i4.Future); + @override + _i4.Future requestMediaKeySystemAccess(String? keySystem, + List>? supportedConfigurations) => + (super.noSuchMethod( + Invocation.method(#requestMediaKeySystemAccess, + [keySystem, supportedConfigurations]), + Future.value(null)) as _i4.Future); + @override + bool sendBeacon(String? url, Object? data) => + (super.noSuchMethod(Invocation.method(#sendBeacon, [url, data]), false) + as bool); + @override + _i4.Future share([Map? data]) => + (super.noSuchMethod(Invocation.method(#share, [data]), Future.value(null)) + as _i4.Future); + @override + bool operator ==(Object? other) => + (super.noSuchMethod(Invocation.method(#==, [other]), false) as bool); + @override + String toString() => + (super.noSuchMethod(Invocation.method(#toString, []), '') as String); +} diff --git a/packages/url_launcher/url_launcher_web/test/lib/main.dart b/packages/url_launcher/url_launcher_web/example/lib/main.dart similarity index 100% rename from packages/url_launcher/url_launcher_web/test/lib/main.dart rename to packages/url_launcher/url_launcher_web/example/lib/main.dart diff --git a/packages/url_launcher/url_launcher_web/test/pubspec.yaml b/packages/url_launcher/url_launcher_web/example/pubspec.yaml similarity index 61% rename from packages/url_launcher/url_launcher_web/test/pubspec.yaml rename to packages/url_launcher/url_launcher_web/example/pubspec.yaml index b8c541f72986..5fc060fe7abe 100644 --- a/packages/url_launcher/url_launcher_web/test/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/example/pubspec.yaml @@ -1,22 +1,22 @@ name: regular_integration_tests publish_to: none -environment: - sdk: ">=2.10.0-56.0.dev <3.0.0" - dependencies: flutter: sdk: flutter dev_dependencies: + build_runner: ^1.10.0 + mockito: ^5.0.0-nullsafety.5 + url_launcher_web: + path: ../ flutter_driver: sdk: flutter flutter_test: sdk: flutter - http: ^0.12.2 - mockito: ^4.1.1 - url_launcher_web: - path: ../ integration_test: - path: ../../../integration_test + sdk: flutter +environment: + sdk: ">=2.12.0-0 <3.0.0" + flutter: ">=1.26.0-0" # For integration_test from sdk diff --git a/packages/url_launcher/url_launcher_web/example/run_test.sh b/packages/url_launcher/url_launcher_web/example/run_test.sh new file mode 100755 index 000000000000..b243f2938b1f --- /dev/null +++ b/packages/url_launcher/url_launcher_web/example/run_test.sh @@ -0,0 +1,23 @@ +#!/usr/bin/bash +if pgrep -lf chromedriver > /dev/null; then + echo "chromedriver is running." + + flutter pub get + + echo "(Re)generating mocks." + flutter pub run build_runner build --delete-conflicting-outputs + + if [ $# -eq 0 ]; then + echo "No target specified, running all tests..." + find integration_test/ -iname *_test.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_test_driver.dart --target='{}' + else + echo "Running test target: $1..." + set -x + flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_test_driver.dart --target=$1 + fi + + else + echo "chromedriver is not running." + echo "Please, check the README.md for instructions on how to use run_test.sh" +fi + diff --git a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration_test.dart b/packages/url_launcher/url_launcher_web/example/test_driver/integration_test_driver.dart similarity index 94% rename from packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration_test.dart rename to packages/url_launcher/url_launcher_web/example/test_driver/integration_test_driver.dart index 2d68bb93e9a7..64e2248a4f9b 100644 --- a/packages/url_launcher/url_launcher_web/test/test_driver/url_launcher_web_integration_test.dart +++ b/packages/url_launcher/url_launcher_web/example/test_driver/integration_test_driver.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 'package:integration_test/integration_test_driver.dart'; Future main() async => integrationDriver(); diff --git a/packages/url_launcher/url_launcher_web/test/web/index.html b/packages/url_launcher/url_launcher_web/example/web/index.html similarity index 100% rename from packages/url_launcher/url_launcher_web/test/web/index.html rename to packages/url_launcher/url_launcher_web/example/web/index.html diff --git a/packages/url_launcher/url_launcher_web/lib/src/link.dart b/packages/url_launcher/url_launcher_web/lib/src/link.dart index 8169a9c11b94..42c711b7d818 100644 --- a/packages/url_launcher/url_launcher_web/lib/src/link.dart +++ b/packages/url_launcher/url_launcher_web/lib/src/link.dart @@ -45,16 +45,16 @@ class WebLinkDelegate extends StatefulWidget { /// For external URIs, it lets the browser do its thing. For app route names, it /// pushes the route name to the framework. class WebLinkDelegateState extends State { - LinkViewController _controller; + late LinkViewController _controller; @override void didUpdateWidget(WebLinkDelegate oldWidget) { super.didUpdateWidget(oldWidget); if (widget.link.uri != oldWidget.link.uri) { - _controller?.setUri(widget.link.uri); + _controller.setUri(widget.link.uri); } if (widget.link.target != oldWidget.link.target) { - _controller?.setTarget(widget.link.target); + _controller.setTarget(widget.link.target); } } @@ -126,15 +126,15 @@ class LinkViewController extends PlatformViewController { static Map _instances = {}; static html.Element _viewFactory(int viewId) { - return _instances[viewId]?._element; + return _instances[viewId]!._element; } - static int _hitTestedViewId; + static int? _hitTestedViewId; - static StreamSubscription _clickSubscription; + static late StreamSubscription _clickSubscription; static void _onGlobalClick(html.MouseEvent event) { - final int viewId = getViewIdFromTarget(event); + final int? viewId = getViewIdFromTarget(event); _instances[viewId]?._onDomClick(event); // After the DOM click event has been received, clean up the hit test state // so we can start fresh on the next click. @@ -161,7 +161,7 @@ class LinkViewController extends PlatformViewController { /// The context of the [Link] widget that created this controller. final BuildContext context; - html.Element _element; + late html.Element _element; bool get _isInitialized => _element != null; Future _initialize() async { @@ -193,7 +193,7 @@ class LinkViewController extends PlatformViewController { return; } - if (_uri.hasScheme) { + if (_uri != null && _uri!.hasScheme) { // External links will be handled by the browser, so we don't have to do // anything. return; @@ -207,10 +207,12 @@ class LinkViewController extends PlatformViewController { pushRouteNameToFramework(context, routeName); } - Uri _uri; + Uri? _uri; /// Set the [Uri] value for this link. - void setUri(Uri uri) { + /// + /// When Uri is null, the `href` attribute of the link is removed. + void setUri(Uri? uri) { assert(_isInitialized); _uri = uri; if (uri == null) { @@ -264,8 +266,8 @@ class LinkViewController extends PlatformViewController { } /// Finds the view id of the DOM element targeted by the [event]. -int getViewIdFromTarget(html.Event event) { - final html.Element linkElement = getLinkElementFromTarget(event); +int? getViewIdFromTarget(html.Event event) { + final html.Element? linkElement = getLinkElementFromTarget(event); if (linkElement != null) { return getProperty(linkElement, linkViewIdProperty); } @@ -275,15 +277,17 @@ int getViewIdFromTarget(html.Event event) { /// Finds the targeted DOM element by the [event]. /// /// It handles the case where the target element is inside a shadow DOM too. -html.Element getLinkElementFromTarget(html.Event event) { - final html.Element target = event.target; - if (isLinkElement(target)) { - return target; - } - if (target.shadowRoot != null) { - final html.Element child = target.shadowRoot.lastChild; - if (isLinkElement(child)) { - return child; +html.Element? getLinkElementFromTarget(html.Event event) { + final html.EventTarget? target = event.target; + if (target != null && target is html.Element) { + if (isLinkElement(target)) { + return target; + } + if (target.shadowRoot != null) { + final html.Node? child = target.shadowRoot!.lastChild; + if (child != null && child is html.Element && isLinkElement(child)) { + return child; + } } } return null; @@ -291,6 +295,8 @@ html.Element getLinkElementFromTarget(html.Event event) { /// Checks if the given [element] is a link that was created by /// [LinkViewController]. -bool isLinkElement(html.Element element) { - return element.tagName == 'A' && hasProperty(element, linkViewIdProperty); +bool isLinkElement(html.Element? element) { + return element != null && + element.tagName == 'A' && + hasProperty(element, linkViewIdProperty); } diff --git a/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart b/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart index 969cfbaa2dfd..e4d2116445cf 100644 --- a/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart +++ b/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart @@ -19,7 +19,7 @@ const _safariTargetTopSchemes = { 'tel', 'sms', }; -String _getUrlScheme(String url) => Uri.tryParse(url)?.scheme; +String? _getUrlScheme(String url) => Uri.tryParse(url)?.scheme; bool _isSafariTargetTopScheme(String url) => _safariTargetTopSchemes.contains(_getUrlScheme(url)); @@ -38,7 +38,7 @@ class UrlLauncherPlugin extends UrlLauncherPlatform { }.union(_safariTargetTopSchemes); /// A constructor that allows tests to override the window object used by the plugin. - UrlLauncherPlugin({@visibleForTesting html.Window debugWindow}) + UrlLauncherPlugin({@visibleForTesting html.Window? debugWindow}) : _window = debugWindow ?? html.window { _isSafari = navigatorIsSafari(_window.navigator); } @@ -58,7 +58,7 @@ class UrlLauncherPlugin extends UrlLauncherPlatform { /// /// Returns the newly created window. @visibleForTesting - html.WindowBase openNewWindow(String url, {String webOnlyWindowName}) { + html.WindowBase openNewWindow(String url, {String? webOnlyWindowName}) { // We need to open mailto, tel and sms urls on the _top window context on safari browsers. // See https://github.com/flutter/flutter/issues/51461 for reference. final target = webOnlyWindowName ?? @@ -74,13 +74,13 @@ class UrlLauncherPlugin extends UrlLauncherPlatform { @override Future launch( String url, { - @required bool useSafariVC, - @required bool useWebView, - @required bool enableJavaScript, - @required bool enableDomStorage, - @required bool universalLinksOnly, - @required Map headers, - String webOnlyWindowName, + bool useSafariVC = false, + bool useWebView = false, + bool enableJavaScript = false, + bool enableDomStorage = false, + bool universalLinksOnly = false, + Map headers = const {}, + String? webOnlyWindowName, }) { return Future.value( openNewWindow(url, webOnlyWindowName: webOnlyWindowName) != null); diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml index 77a958677015..b9f957a7ee76 100644 --- a/packages/url_launcher/url_launcher_web/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/pubspec.yaml @@ -1,10 +1,7 @@ name: url_launcher_web description: Web platform implementation of url_launcher homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_web -# 0.1.y+z is compatible with 1.0.0, if you land a breaking change bump -# the version to 2.0.0. -# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.1.5+3 +version: 2.0.0-nullsafety flutter: plugin: @@ -14,31 +11,18 @@ flutter: fileName: url_launcher_web.dart dependencies: - url_launcher_platform_interface: ^1.0.9 - # TODO(mvanbeusekom): Update to use pub.dev once null safety version is published. - # url_launcher_platform_interface: - # git: - # url: https://github.com/flutter/plugins.git - # ref: nnbd - # path: packages/url_launcher/url_launcher_platform_interface + url_launcher_platform_interface: ^2.0.0-nullsafety + meta: ^1.3.0 # null safe flutter: sdk: flutter flutter_web_plugins: sdk: flutter - meta: ^1.1.7 dev_dependencies: + pedantic: ^1.10.0 # null safe flutter_test: sdk: flutter - url_launcher: ^5.2.5 - # TODO(mvanbeusekom): Update to use pub.dev once null safety version is published. - # url_launcher: - # path: ../url_launcher - pedantic: ^1.8.0 - mockito: ^4.1.1 - integration_test: - path: ../../integration_test environment: - sdk: ">=2.2.0 <3.0.0" - flutter: ">=1.10.0" + sdk: ">=2.12.0-0 <3.0.0" + flutter: ">=1.12.13+hotfix.5" diff --git a/packages/url_launcher/url_launcher_web/test/README.md b/packages/url_launcher/url_launcher_web/test/README.md index 7c48d024ba57..7c5b4ad682ba 100644 --- a/packages/url_launcher/url_launcher_web/test/README.md +++ b/packages/url_launcher/url_launcher_web/test/README.md @@ -1,17 +1,5 @@ -# Running browser_tests +## test -Make sure you have updated to the latest Flutter master. +This package uses integration tests for testing. -1. Check what version of Chrome is running on the machine you're running tests on. - -2. Download and install driver for that version from here: - * - -3. Start the driver using `chromedriver --port=4444` - -4. Change into the `test` directory of your clone. - -5. Run tests: `flutter drive -d web-server --browser-name=chrome --target=test_driver/TEST_NAME_integration.dart`, or (in Linux): - - * Single: `./run_test test_driver/TEST_NAME_integration.dart` - * All: `./run_test` +See `example/README.md` for more info. diff --git a/packages/url_launcher/url_launcher_web/test/run_test b/packages/url_launcher/url_launcher_web/test/run_test deleted file mode 100755 index 74a8526a0fa3..000000000000 --- a/packages/url_launcher/url_launcher_web/test/run_test +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/bash -if pgrep -lf chromedriver > /dev/null; then - echo "chromedriver is running." - - if [ $# -eq 0 ]; then - echo "No target specified, running all tests..." - find test_driver/ -iname *_integration.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --target='{}' - else - echo "Running test target: $1..." - set -x - flutter drive -d web-server --web-port=7357 --browser-name=chrome --target=$1 - fi - - else - echo "chromedriver is not running." -fi - diff --git a/packages/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart b/packages/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart new file mode 100644 index 000000000000..334f52186d9d --- /dev/null +++ b/packages/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart @@ -0,0 +1,10 @@ +import 'package:flutter_test/flutter_test.dart'; + +void main() { + test('Tell the user where to find the real tests', () { + print('---'); + print('This package uses integration_test for its tests.'); + print('See `example/README.md` for more info.'); + print('---'); + }); +} From 95f856eaea69b19d483a38e8b73856440dab84ec Mon Sep 17 00:00:00 2001 From: Bharat Biradar <62872048+bharat-biradar@users.noreply.github.com> Date: Wed, 17 Feb 2021 04:07:58 +0530 Subject: [PATCH 0140/1565] [file_selector_web] update documentation #76067 (#3554) Fix documentation typo. This package is file_selector, not file_picker! Co-authored-by: David Iglesias --- .../file_selector/file_selector_web/README.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/file_selector/file_selector_web/README.md b/packages/file_selector/file_selector_web/README.md index 36e0b446ffe8..24d48f48586f 100644 --- a/packages/file_selector/file_selector_web/README.md +++ b/packages/file_selector/file_selector_web/README.md @@ -1,16 +1,16 @@ -# file_picker_web +# file_selector_web -The web implementation of [`file_picker`][1]. +The web implementation of [`file_selector`][1]. ## Usage ### Import the package To use this plugin in your Flutter Web app, simply add it as a dependency in -your pubspec alongside the base `file_picker` plugin. +your pubspec alongside the base `file_selector` plugin. _(This is only temporary: in the future we hope to make this package an -"endorsed" implementation of `file_picker`, so that it is automatically -included in your Flutter Web app when you depend on `package:file_picker`.)_ +"endorsed" implementation of `file_selector`, so that it is automatically +included in your Flutter Web app when you depend on `package:file_selector`.)_ This is what the above means to your `pubspec.yaml`: @@ -18,13 +18,13 @@ This is what the above means to your `pubspec.yaml`: ... dependencies: ... - file_picker: ^0.7.0 - file_picker_web: ^0.7.0 + file_selector: ^0.7.0 + file_selector_web: ^0.7.0 ... ``` ### Use the plugin -Once you have the `file_picker_web` dependency in your pubspec, you should -be able to use `package:file_picker` as normal. +Once you have the `file_selector_web` dependency in your pubspec, you should +be able to use `package:file_selector` as normal. -[1]: ../file_picker/file_picker +[1]: https://pub.dev/packages/file_selector From aaabec0083d7f2a89c1522086b8ae7b5a446b4b9 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Tue, 16 Feb 2021 16:01:31 -0800 Subject: [PATCH 0141/1565] Remove iOS stubs (#3490) Plugins that don't actually support iOS are no longer required to have an iOS stub to prevent build failures. This removes all iOS stubs from plugins that don't support iOS. --- .cirrus.yml | 2 +- .../ios/Flutter/AppFrameworkInfo.plist | 30 - .../example/ios/Flutter/Debug.xcconfig | 2 - .../example/ios/Flutter/Release.xcconfig | 2 - .../ios/Runner.xcodeproj/project.pbxproj | 490 --------------- .../contents.xcworkspacedata | 7 - .../xcshareddata/xcschemes/Runner.xcscheme | 87 --- .../contents.xcworkspacedata | 10 - .../example/ios/Runner/AppDelegate.h | 6 - .../example/ios/Runner/AppDelegate.m | 13 - .../AppIcon.appiconset/Contents.json | 116 ---- .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 564 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 1588 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 1025 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 1716 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 1920 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 1895 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 3831 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 1888 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 3294 -> 0 bytes .../Icon-App-83.5x83.5@2x.png | Bin 3612 -> 0 bytes .../LaunchImage.imageset/Contents.json | 23 - .../LaunchImage.imageset/LaunchImage.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/README.md | 5 - .../Runner/Base.lproj/LaunchScreen.storyboard | 37 -- .../ios/Runner/Base.lproj/Main.storyboard | 26 - .../example/ios/Runner/Info.plist | 49 -- .../example/ios/Runner/main.m | 9 - .../android_alarm_manager/ios/Assets/.gitkeep | 0 .../ios/Classes/AndroidAlarmManagerPlugin.h | 8 - .../ios/Classes/AndroidAlarmManagerPlugin.m | 21 - .../ios/android_alarm_manager.podspec | 23 - .../ios/Flutter/AppFrameworkInfo.plist | 30 - .../example/ios/Flutter/Debug.xcconfig | 2 - .../example/ios/Flutter/Release.xcconfig | 2 - .../ios/Runner.xcodeproj/project.pbxproj | 490 --------------- .../contents.xcworkspacedata | 7 - .../xcshareddata/xcschemes/Runner.xcscheme | 87 --- .../contents.xcworkspacedata | 10 - .../example/ios/Runner/AppDelegate.h | 10 - .../example/ios/Runner/AppDelegate.m | 17 - .../AppIcon.appiconset/Contents.json | 116 ---- .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 564 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 1588 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 1025 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 1716 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 1920 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 1895 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 3831 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 1888 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 3294 -> 0 bytes .../Icon-App-83.5x83.5@2x.png | Bin 3612 -> 0 bytes .../Runner/Base.lproj/LaunchScreen.storyboard | 27 - .../ios/Runner/Base.lproj/Main.storyboard | 26 - .../example/ios/Runner/Info.plist | 49 -- .../android_intent/example/ios/Runner/main.m | 13 - packages/android_intent/ios/Assets/.gitkeep | 0 .../ios/Classes/AndroidIntentPlugin.h | 8 - .../ios/Classes/AndroidIntentPlugin.m | 20 - .../android_intent/ios/android_intent.podspec | 24 - .../ios/connectivity_for_web.podspec | 23 - .../ios/Flutter/AppFrameworkInfo.plist | 30 - .../example/ios/Flutter/Debug.xcconfig | 2 - .../example/ios/Flutter/Release.xcconfig | 2 - .../ios/Runner.xcodeproj/project.pbxproj | 490 --------------- .../contents.xcworkspacedata | 7 - .../xcshareddata/xcschemes/Runner.xcscheme | 87 --- .../contents.xcworkspacedata | 10 - .../example/ios/Runner/AppDelegate.h | 10 - .../example/ios/Runner/AppDelegate.m | 17 - .../AppIcon.appiconset/Contents.json | 116 ---- .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 564 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 1588 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 1025 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 1716 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 1920 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 1895 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 3831 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 1888 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 3294 -> 0 bytes .../Icon-App-83.5x83.5@2x.png | Bin 3612 -> 0 bytes .../Runner/Base.lproj/LaunchScreen.storyboard | 27 - .../ios/Runner/Base.lproj/Main.storyboard | 26 - .../example/ios/Runner/Info.plist | 53 -- .../example/ios/Runner/Runner.entitlements | 8 - .../example/ios/Runner/main.m | 13 - .../ios/connectivity_macos.podspec | 21 - packages/espresso/example/ios/.gitignore | 32 - .../ios/Flutter/AppFrameworkInfo.plist | 26 - .../example/ios/Flutter/Debug.xcconfig | 2 - .../example/ios/Flutter/Release.xcconfig | 2 - .../ios/Runner.xcodeproj/project.pbxproj | 584 ------------------ .../xcshareddata/xcschemes/Runner.xcscheme | 91 --- .../example/ios/Runner/AppDelegate.swift | 13 - .../AppIcon.appiconset/Contents.json | 122 ---- .../Icon-App-1024x1024@1x.png | Bin 10932 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 564 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 1588 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 1025 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 1716 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 1920 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 1895 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 3831 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 1888 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 3294 -> 0 bytes .../Icon-App-83.5x83.5@2x.png | Bin 3612 -> 0 bytes .../LaunchImage.imageset/Contents.json | 23 - .../LaunchImage.imageset/LaunchImage.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/README.md | 5 - .../Runner/Base.lproj/LaunchScreen.storyboard | 37 -- .../ios/Runner/Base.lproj/Main.storyboard | 26 - .../espresso/example/ios/Runner/Info.plist | 45 -- .../ios/Runner/Runner-Bridging-Header.h | 1 - packages/espresso/ios/.gitignore | 37 -- packages/espresso/ios/Assets/.gitkeep | 0 .../espresso/ios/Classes/EspressoPlugin.h | 4 - .../espresso/ios/Classes/EspressoPlugin.m | 15 - packages/espresso/ios/espresso.podspec | 25 - packages/espresso/pubspec.yaml | 2 - .../ios/file_selector_web.podspec | 21 - .../example/ios/.gitignore | 31 - .../ios/Flutter/AppFrameworkInfo.plist | 26 - .../example/ios/Flutter/Debug.xcconfig | 2 - .../example/ios/Flutter/Release.xcconfig | 2 - .../ios/Runner.xcodeproj/project.pbxproj | 576 ----------------- .../xcshareddata/xcschemes/Runner.xcscheme | 91 --- .../example/ios/Runner/AppDelegate.h | 6 - .../example/ios/Runner/AppDelegate.m | 13 - .../AppIcon.appiconset/Contents.json | 122 ---- .../Icon-App-1024x1024@1x.png | Bin 10932 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 564 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 1588 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 1025 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 1716 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 1920 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 1895 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 3831 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 1888 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 3294 -> 0 bytes .../Icon-App-83.5x83.5@2x.png | Bin 3612 -> 0 bytes .../LaunchImage.imageset/Contents.json | 23 - .../LaunchImage.imageset/LaunchImage.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/README.md | 5 - .../Runner/Base.lproj/LaunchScreen.storyboard | 37 -- .../ios/Runner/Base.lproj/Main.storyboard | 26 - .../example/ios/Runner/Info.plist | 45 -- .../example/ios/Runner/main.m | 9 - .../ios/.gitignore | 37 -- .../ios/Assets/.gitkeep | 0 .../Classes/FlutterAndroidLifecyclePlugin.h | 8 - .../Classes/FlutterAndroidLifecyclePlugin.m | 10 - .../flutter_plugin_android_lifecycle.podspec | 26 - .../ios/google_maps_flutter_web.podspec | 23 - .../ios/google_sign_in_web.podspec | 21 - .../ios/image_picker_for_web.podspec | 20 - .../ios/integration_test_macos.podspec | 21 - .../path_provider_linux/ios/.gitignore | 37 -- .../ios/path_provider_linux.podspec | 19 - .../ios/Flutter/AppFrameworkInfo.plist | 30 - .../example/ios/Flutter/Debug.xcconfig | 2 - .../example/ios/Flutter/Release.xcconfig | 2 - .../ios/Runner.xcodeproj/project.pbxproj | 490 --------------- .../contents.xcworkspacedata | 10 - .../xcshareddata/xcschemes/Runner.xcscheme | 87 --- .../contents.xcworkspacedata | 10 - .../example/ios/Runner/AppDelegate.h | 10 - .../example/ios/Runner/AppDelegate.m | 16 - .../AppIcon.appiconset/Contents.json | 116 ---- .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 564 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 1588 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 1025 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 1716 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 1920 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 1895 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 3831 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 1888 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 3294 -> 0 bytes .../Icon-App-83.5x83.5@2x.png | Bin 3612 -> 0 bytes .../Runner/Base.lproj/LaunchScreen.storyboard | 27 - .../ios/Runner/Base.lproj/Main.storyboard | 26 - .../example/ios/Runner/Info.plist | 49 -- .../example/ios/Runner/main.m | 13 - .../ios/path_provider_macos.podspec | 22 - .../ios/path_provider_windows.podspec | 22 - .../ios/shared_preferences_linux.podspec | 22 - .../ios/shared_preferences_macos.podspec | 21 - .../ios/shared_preferences_web.podspec | 20 - .../ios/shared_preferences_windows.podspec | 22 - .../url_launcher_linux/ios/.gitignore | 37 -- .../ios/url_launcher_linux.podspec | 22 - .../ios/Flutter/AppFrameworkInfo.plist | 30 - .../example/ios/Flutter/Debug.xcconfig | 2 - .../example/ios/Flutter/Release.xcconfig | 2 - .../ios/Runner.xcodeproj/project.pbxproj | 490 --------------- .../xcshareddata/xcschemes/Runner.xcscheme | 87 --- .../example/ios/Runner/AppDelegate.h | 10 - .../example/ios/Runner/AppDelegate.m | 17 - .../AppIcon.appiconset/Contents.json | 116 ---- .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 564 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 1588 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 1025 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 1716 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 1920 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 1895 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 3831 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 1888 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 3294 -> 0 bytes .../Icon-App-83.5x83.5@2x.png | Bin 3612 -> 0 bytes .../Runner/Base.lproj/LaunchScreen.storyboard | 27 - .../ios/Runner/Base.lproj/Main.storyboard | 26 - .../example/ios/Runner/Info.plist | 49 -- .../example/ios/Runner/main.m | 13 - .../ios/url_launcher_macos.podspec | 21 - .../ios/url_launcher_web.podspec | 20 - .../ios/url_launcher_windows.podspec | 22 - .../ios/video_player_web.podspec | 20 - .../tool/lib/src/drive_examples_command.dart | 9 +- 251 files changed, 5 insertions(+), 7227 deletions(-) delete mode 100644 packages/android_alarm_manager/example/ios/Flutter/AppFrameworkInfo.plist delete mode 100644 packages/android_alarm_manager/example/ios/Flutter/Debug.xcconfig delete mode 100644 packages/android_alarm_manager/example/ios/Flutter/Release.xcconfig delete mode 100644 packages/android_alarm_manager/example/ios/Runner.xcodeproj/project.pbxproj delete mode 100644 packages/android_alarm_manager/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 packages/android_alarm_manager/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme delete mode 100644 packages/android_alarm_manager/example/ios/Runner.xcworkspace/contents.xcworkspacedata delete mode 100644 packages/android_alarm_manager/example/ios/Runner/AppDelegate.h delete mode 100644 packages/android_alarm_manager/example/ios/Runner/AppDelegate.m delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Base.lproj/LaunchScreen.storyboard delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Base.lproj/Main.storyboard delete mode 100644 packages/android_alarm_manager/example/ios/Runner/Info.plist delete mode 100644 packages/android_alarm_manager/example/ios/Runner/main.m delete mode 100644 packages/android_alarm_manager/ios/Assets/.gitkeep delete mode 100644 packages/android_alarm_manager/ios/Classes/AndroidAlarmManagerPlugin.h delete mode 100644 packages/android_alarm_manager/ios/Classes/AndroidAlarmManagerPlugin.m delete mode 100644 packages/android_alarm_manager/ios/android_alarm_manager.podspec delete mode 100644 packages/android_intent/example/ios/Flutter/AppFrameworkInfo.plist delete mode 100644 packages/android_intent/example/ios/Flutter/Debug.xcconfig delete mode 100644 packages/android_intent/example/ios/Flutter/Release.xcconfig delete mode 100644 packages/android_intent/example/ios/Runner.xcodeproj/project.pbxproj delete mode 100644 packages/android_intent/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 packages/android_intent/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme delete mode 100644 packages/android_intent/example/ios/Runner.xcworkspace/contents.xcworkspacedata delete mode 100644 packages/android_intent/example/ios/Runner/AppDelegate.h delete mode 100644 packages/android_intent/example/ios/Runner/AppDelegate.m delete mode 100644 packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png delete mode 100644 packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png delete mode 100644 packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png delete mode 100644 packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png delete mode 100644 packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png delete mode 100644 packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png delete mode 100644 packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png delete mode 100644 packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png delete mode 100644 packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png delete mode 100644 packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png delete mode 100644 packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png delete mode 100644 packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png delete mode 100644 packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png delete mode 100644 packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png delete mode 100644 packages/android_intent/example/ios/Runner/Base.lproj/LaunchScreen.storyboard delete mode 100644 packages/android_intent/example/ios/Runner/Base.lproj/Main.storyboard delete mode 100644 packages/android_intent/example/ios/Runner/Info.plist delete mode 100644 packages/android_intent/example/ios/Runner/main.m delete mode 100644 packages/android_intent/ios/Assets/.gitkeep delete mode 100644 packages/android_intent/ios/Classes/AndroidIntentPlugin.h delete mode 100644 packages/android_intent/ios/Classes/AndroidIntentPlugin.m delete mode 100644 packages/android_intent/ios/android_intent.podspec delete mode 100644 packages/connectivity/connectivity_for_web/ios/connectivity_for_web.podspec delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Flutter/AppFrameworkInfo.plist delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Flutter/Debug.xcconfig delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Flutter/Release.xcconfig delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner.xcodeproj/project.pbxproj delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner.xcworkspace/contents.xcworkspacedata delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/AppDelegate.h delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/AppDelegate.m delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Base.lproj/LaunchScreen.storyboard delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Base.lproj/Main.storyboard delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Info.plist delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/Runner.entitlements delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner/main.m delete mode 100644 packages/connectivity/connectivity_macos/ios/connectivity_macos.podspec delete mode 100644 packages/espresso/example/ios/.gitignore delete mode 100644 packages/espresso/example/ios/Flutter/AppFrameworkInfo.plist delete mode 100644 packages/espresso/example/ios/Flutter/Debug.xcconfig delete mode 100644 packages/espresso/example/ios/Flutter/Release.xcconfig delete mode 100644 packages/espresso/example/ios/Runner.xcodeproj/project.pbxproj delete mode 100644 packages/espresso/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme delete mode 100644 packages/espresso/example/ios/Runner/AppDelegate.swift delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png delete mode 100644 packages/espresso/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md delete mode 100644 packages/espresso/example/ios/Runner/Base.lproj/LaunchScreen.storyboard delete mode 100644 packages/espresso/example/ios/Runner/Base.lproj/Main.storyboard delete mode 100644 packages/espresso/example/ios/Runner/Info.plist delete mode 100644 packages/espresso/example/ios/Runner/Runner-Bridging-Header.h delete mode 100644 packages/espresso/ios/.gitignore delete mode 100644 packages/espresso/ios/Assets/.gitkeep delete mode 100644 packages/espresso/ios/Classes/EspressoPlugin.h delete mode 100644 packages/espresso/ios/Classes/EspressoPlugin.m delete mode 100644 packages/espresso/ios/espresso.podspec delete mode 100644 packages/file_selector/file_selector_web/ios/file_selector_web.podspec delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/.gitignore delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Flutter/AppFrameworkInfo.plist delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Flutter/Debug.xcconfig delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Flutter/Release.xcconfig delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner.xcodeproj/project.pbxproj delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/AppDelegate.h delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/AppDelegate.m delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Base.lproj/LaunchScreen.storyboard delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Base.lproj/Main.storyboard delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/Info.plist delete mode 100644 packages/flutter_plugin_android_lifecycle/example/ios/Runner/main.m delete mode 100644 packages/flutter_plugin_android_lifecycle/ios/.gitignore delete mode 100644 packages/flutter_plugin_android_lifecycle/ios/Assets/.gitkeep delete mode 100644 packages/flutter_plugin_android_lifecycle/ios/Classes/FlutterAndroidLifecyclePlugin.h delete mode 100644 packages/flutter_plugin_android_lifecycle/ios/Classes/FlutterAndroidLifecyclePlugin.m delete mode 100644 packages/flutter_plugin_android_lifecycle/ios/flutter_plugin_android_lifecycle.podspec delete mode 100644 packages/google_maps_flutter/google_maps_flutter_web/ios/google_maps_flutter_web.podspec delete mode 100644 packages/google_sign_in/google_sign_in_web/ios/google_sign_in_web.podspec delete mode 100644 packages/image_picker/image_picker_for_web/ios/image_picker_for_web.podspec delete mode 100644 packages/integration_test/integration_test_macos/ios/integration_test_macos.podspec delete mode 100644 packages/path_provider/path_provider_linux/ios/.gitignore delete mode 100644 packages/path_provider/path_provider_linux/ios/path_provider_linux.podspec delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Flutter/AppFrameworkInfo.plist delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Flutter/Debug.xcconfig delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Flutter/Release.xcconfig delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/project.pbxproj delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner.xcworkspace/contents.xcworkspacedata delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/AppDelegate.h delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/AppDelegate.m delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Base.lproj/LaunchScreen.storyboard delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Base.lproj/Main.storyboard delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Info.plist delete mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/main.m delete mode 100644 packages/path_provider/path_provider_macos/ios/path_provider_macos.podspec delete mode 100644 packages/path_provider/path_provider_windows/ios/path_provider_windows.podspec delete mode 100644 packages/shared_preferences/shared_preferences_linux/ios/shared_preferences_linux.podspec delete mode 100644 packages/shared_preferences/shared_preferences_macos/ios/shared_preferences_macos.podspec delete mode 100644 packages/shared_preferences/shared_preferences_web/ios/shared_preferences_web.podspec delete mode 100644 packages/shared_preferences/shared_preferences_windows/ios/shared_preferences_windows.podspec delete mode 100644 packages/url_launcher/url_launcher_linux/ios/.gitignore delete mode 100644 packages/url_launcher/url_launcher_linux/ios/url_launcher_linux.podspec delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Flutter/AppFrameworkInfo.plist delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Flutter/Debug.xcconfig delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Flutter/Release.xcconfig delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner.xcodeproj/project.pbxproj delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/AppDelegate.h delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/AppDelegate.m delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/Base.lproj/LaunchScreen.storyboard delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/Base.lproj/Main.storyboard delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/Info.plist delete mode 100644 packages/url_launcher/url_launcher_macos/example/ios/Runner/main.m delete mode 100644 packages/url_launcher/url_launcher_macos/ios/url_launcher_macos.podspec delete mode 100644 packages/url_launcher/url_launcher_web/ios/url_launcher_web.podspec delete mode 100644 packages/url_launcher/url_launcher_windows/ios/url_launcher_windows.podspec delete mode 100644 packages/video_player/video_player_web/ios/video_player_web.podspec diff --git a/.cirrus.yml b/.cirrus.yml index c7323742e6e4..2b6ee2b7f969 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -201,7 +201,7 @@ task: - flutter channel $CHANNEL - flutter upgrade - ./script/incremental_build.sh build-examples --ipa - - ./script/incremental_build.sh drive-examples + - ./script/incremental_build.sh drive-examples --ios - ./script/incremental_build.sh xctest --target RunnerUITests --skip $PLUGINS_TO_SKIP_XCTESTS --ios-destination "platform=iOS Simulator,name=iPhone 11,OS=14.3" task: diff --git a/packages/android_alarm_manager/example/ios/Flutter/AppFrameworkInfo.plist b/packages/android_alarm_manager/example/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 6c2de8086bcd..000000000000 --- a/packages/android_alarm_manager/example/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - UIRequiredDeviceCapabilities - - arm64 - - MinimumOSVersion - 8.0 - - diff --git a/packages/android_alarm_manager/example/ios/Flutter/Debug.xcconfig b/packages/android_alarm_manager/example/ios/Flutter/Debug.xcconfig deleted file mode 100644 index e8efba114687..000000000000 --- a/packages/android_alarm_manager/example/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "Generated.xcconfig" diff --git a/packages/android_alarm_manager/example/ios/Flutter/Release.xcconfig b/packages/android_alarm_manager/example/ios/Flutter/Release.xcconfig deleted file mode 100644 index 399e9340e6f6..000000000000 --- a/packages/android_alarm_manager/example/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "Generated.xcconfig" diff --git a/packages/android_alarm_manager/example/ios/Runner.xcodeproj/project.pbxproj b/packages/android_alarm_manager/example/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index 10f77b41d130..000000000000 --- a/packages/android_alarm_manager/example/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,490 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; - 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - C952AD53387AE85A4AAC19D3 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 365DE79D3A08F3F6322AB7B4 /* libPods-Runner.a */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 192BD17BD81C291EF9467E75 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 365DE79D3A08F3F6322AB7B4 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 842A7CA20B55950D87F2A01A /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, - C952AD53387AE85A4AAC19D3 /* libPods-Runner.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 1B44A04DB1D7DBDE7E239095 /* Pods */ = { - isa = PBXGroup; - children = ( - 192BD17BD81C291EF9467E75 /* Pods-Runner.debug.xcconfig */, - 842A7CA20B55950D87F2A01A /* Pods-Runner.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 3B80C3931E831B6300D905FE /* App.framework */, - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEBA1CF902C7004384FC /* Flutter.framework */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - 1B44A04DB1D7DBDE7E239095 /* Pods */, - B10ADDD1244B5A67F70F5F08 /* Frameworks */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 97C146F11CF9000F007C117D /* Supporting Files */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - ); - path = Runner; - sourceTree = ""; - }; - 97C146F11CF9000F007C117D /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 97C146F21CF9000F007C117D /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - B10ADDD1244B5A67F70F5F08 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 365DE79D3A08F3F6322AB7B4 /* libPods-Runner.a */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 9AC722C5D70651C49D7ECF80 /* [CP] Check Pods Manifest.lock */, - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - E95CF7E4BD7CAFC3E0F4E1E2 /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; - TargetAttributes = { - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; - 9AC722C5D70651C49D7ECF80 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - E95CF7E4BD7CAFC3E0F4E1E2 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, - 97C146F31CF9000F007C117D /* main.m in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = io.flutter.androidAlarmManagerExample; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = io.flutter.androidAlarmManagerExample; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/packages/android_alarm_manager/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/android_alarm_manager/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a16ed0f..000000000000 --- a/packages/android_alarm_manager/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/packages/android_alarm_manager/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/android_alarm_manager/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index 3bb3697ef41c..000000000000 --- a/packages/android_alarm_manager/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/android_alarm_manager/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/android_alarm_manager/example/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 21a3cc14c74e..000000000000 --- a/packages/android_alarm_manager/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/packages/android_alarm_manager/example/ios/Runner/AppDelegate.h b/packages/android_alarm_manager/example/ios/Runner/AppDelegate.h deleted file mode 100644 index 36e21bbf9cf4..000000000000 --- a/packages/android_alarm_manager/example/ios/Runner/AppDelegate.h +++ /dev/null @@ -1,6 +0,0 @@ -#import -#import - -@interface AppDelegate : FlutterAppDelegate - -@end diff --git a/packages/android_alarm_manager/example/ios/Runner/AppDelegate.m b/packages/android_alarm_manager/example/ios/Runner/AppDelegate.m deleted file mode 100644 index 59a72e90be12..000000000000 --- a/packages/android_alarm_manager/example/ios/Runner/AppDelegate.m +++ /dev/null @@ -1,13 +0,0 @@ -#include "AppDelegate.h" -#include "GeneratedPluginRegistrant.h" - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application - didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [GeneratedPluginRegistrant registerWithRegistry:self]; - // Override point for customization after application launch. - return [super application:application didFinishLaunchingWithOptions:launchOptions]; -} - -@end diff --git a/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d22f10b2ab63..000000000000 --- a/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 28c6bf03016f6c994b70f38d1b7346e5831b531f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 564 zcmV-40?Yl0P)Px$?ny*JR5%f>l)FnDQ543{x%ZCiu33$Wg!pQFfT_}?5Q|_VSlIbLC`dpoMXL}9 zHfd9&47Mo(7D231gb+kjFxZHS4-m~7WurTH&doVX2KI5sU4v(sJ1@T9eCIKPjsqSr z)C01LsCxk=72-vXmX}CQD#BD;Cthymh&~=f$Q8nn0J<}ZrusBy4PvRNE}+1ceuj8u z0mW5k8fmgeLnTbWHGwfKA3@PdZxhn|PypR&^p?weGftrtCbjF#+zk_5BJh7;0`#Wr zgDpM_;Ax{jO##IrT`Oz;MvfwGfV$zD#c2xckpcXC6oou4ML~ezCc2EtnsQTB4tWNg z?4bkf;hG7IMfhgNI(FV5Gs4|*GyMTIY0$B=_*mso9Ityq$m^S>15>-?0(zQ<8Qy<_TjHE33(?_M8oaM zyc;NxzRVK@DL6RJnX%U^xW0Gpg(lXp(!uK1v0YgHjs^ZXSQ|m#lV7ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 diff --git a/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index f091b6b0bca859a3f474b03065bef75ba58a9e4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ diff --git a/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index d0ef06e7edb86cdfe0d15b4b0d98334a86163658..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1716 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 diff --git a/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index c8f9ed8f5cee1c98386d13b17e89f719e83555b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 diff --git a/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index 75b2d164a5a98e212cca15ea7bf2ab5de5108680..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3831 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 diff --git a/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index c4df70d39da7941ef3f6dcb7f06a192d8dcb308d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 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 iW8Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md deleted file mode 100644 index 89c2725b70f1..000000000000 --- a/packages/android_alarm_manager/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Launch Screen Assets - -You can customize the launch screen with your own desired assets by replacing the image files in this directory. - -You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/packages/android_alarm_manager/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/android_alarm_manager/example/ios/Runner/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index f2e259c7c939..000000000000 --- a/packages/android_alarm_manager/example/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/android_alarm_manager/example/ios/Runner/Base.lproj/Main.storyboard b/packages/android_alarm_manager/example/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c28516fb38..000000000000 --- a/packages/android_alarm_manager/example/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/android_alarm_manager/example/ios/Runner/Info.plist b/packages/android_alarm_manager/example/ios/Runner/Info.plist deleted file mode 100644 index 1d076337d6f4..000000000000 --- a/packages/android_alarm_manager/example/ios/Runner/Info.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - android_alarm_manager_example - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - arm64 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - - diff --git a/packages/android_alarm_manager/example/ios/Runner/main.m b/packages/android_alarm_manager/example/ios/Runner/main.m deleted file mode 100644 index dff6597e4513..000000000000 --- a/packages/android_alarm_manager/example/ios/Runner/main.m +++ /dev/null @@ -1,9 +0,0 @@ -#import -#import -#import "AppDelegate.h" - -int main(int argc, char* argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/packages/android_alarm_manager/ios/Assets/.gitkeep b/packages/android_alarm_manager/ios/Assets/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/packages/android_alarm_manager/ios/Classes/AndroidAlarmManagerPlugin.h b/packages/android_alarm_manager/ios/Classes/AndroidAlarmManagerPlugin.h deleted file mode 100644 index 595fcf60fee1..000000000000 --- a/packages/android_alarm_manager/ios/Classes/AndroidAlarmManagerPlugin.h +++ /dev/null @@ -1,8 +0,0 @@ -// 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. - -#import - -@interface FLTAndroidAlarmManagerPlugin : NSObject -@end diff --git a/packages/android_alarm_manager/ios/Classes/AndroidAlarmManagerPlugin.m b/packages/android_alarm_manager/ios/Classes/AndroidAlarmManagerPlugin.m deleted file mode 100644 index 0aa4f2b2122d..000000000000 --- a/packages/android_alarm_manager/ios/Classes/AndroidAlarmManagerPlugin.m +++ /dev/null @@ -1,21 +0,0 @@ -// 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. - -#import "AndroidAlarmManagerPlugin.h" - -@implementation FLTAndroidAlarmManagerPlugin -+ (void)registerWithRegistrar:(NSObject*)registrar { - FlutterMethodChannel* channel = - [FlutterMethodChannel methodChannelWithName:@"plugins.flutter.io/android_alarm_manager" - binaryMessenger:[registrar messenger] - codec:[FlutterJSONMethodCodec sharedInstance]]; - FLTAndroidAlarmManagerPlugin* instance = [[FLTAndroidAlarmManagerPlugin alloc] init]; - [registrar addMethodCallDelegate:instance channel:channel]; -} - -- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { - result(FlutterMethodNotImplemented); -} - -@end diff --git a/packages/android_alarm_manager/ios/android_alarm_manager.podspec b/packages/android_alarm_manager/ios/android_alarm_manager.podspec deleted file mode 100644 index 2b253878c1ea..000000000000 --- a/packages/android_alarm_manager/ios/android_alarm_manager.podspec +++ /dev/null @@ -1,23 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'android_alarm_manager' - s.version = '0.0.1' - s.summary = 'Flutter Android Alarm Manager' - s.description = <<-DESC -A Flutter plugin for accessing the Android AlarmManager service, and running Dart code in the background when alarms fire. -This plugin a no-op on iOS. -Downloaded by pub (not CocoaPods). - DESC - s.homepage = 'https://github.com/flutter/plugins' - s.license = { :type => 'BSD', :file => '../LICENSE' } - s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } - s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/android_alarm_manager' } - s.documentation_url = 'https://pub.dev/packages/android_alarm_manager' - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - s.platform = :ios, '8.0' - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } -end diff --git a/packages/android_intent/example/ios/Flutter/AppFrameworkInfo.plist b/packages/android_intent/example/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 6c2de8086bcd..000000000000 --- a/packages/android_intent/example/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - UIRequiredDeviceCapabilities - - arm64 - - MinimumOSVersion - 8.0 - - diff --git a/packages/android_intent/example/ios/Flutter/Debug.xcconfig b/packages/android_intent/example/ios/Flutter/Debug.xcconfig deleted file mode 100644 index e8efba114687..000000000000 --- a/packages/android_intent/example/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "Generated.xcconfig" diff --git a/packages/android_intent/example/ios/Flutter/Release.xcconfig b/packages/android_intent/example/ios/Flutter/Release.xcconfig deleted file mode 100644 index 399e9340e6f6..000000000000 --- a/packages/android_intent/example/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "Generated.xcconfig" diff --git a/packages/android_intent/example/ios/Runner.xcodeproj/project.pbxproj b/packages/android_intent/example/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index 430cec7ef2b5..000000000000 --- a/packages/android_intent/example/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,490 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 3FC5CBD67A867C34C8CFD7E1 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7ABB9ACA70E30025F77BB759 /* libPods-Runner.a */; }; - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; - 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; - 7ABB9ACA70E30025F77BB759 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 9B21C620C27B8C2AF08BFA21 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - EFC3461395B2546568135556 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, - 3FC5CBD67A867C34C8CFD7E1 /* libPods-Runner.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 2C36A917BF8B34817D5A406D /* Pods */ = { - isa = PBXGroup; - children = ( - EFC3461395B2546568135556 /* Pods-Runner.debug.xcconfig */, - 9B21C620C27B8C2AF08BFA21 /* Pods-Runner.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; - 7423FCEB8AD9C632FAF625A3 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 7ABB9ACA70E30025F77BB759 /* libPods-Runner.a */, - ); - name = Frameworks; - sourceTree = ""; - }; - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 3B80C3931E831B6300D905FE /* App.framework */, - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEBA1CF902C7004384FC /* Flutter.framework */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - 2C36A917BF8B34817D5A406D /* Pods */, - 7423FCEB8AD9C632FAF625A3 /* Frameworks */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 97C146F11CF9000F007C117D /* Supporting Files */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - ); - path = Runner; - sourceTree = ""; - }; - 97C146F11CF9000F007C117D /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 97C146F21CF9000F007C117D /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - ECD6A6833016AB689F7B8471 /* [CP] Check Pods Manifest.lock */, - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 4B2738B48C3E53795176CD79 /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; - TargetAttributes = { - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; - }; - 4B2738B48C3E53795176CD79 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; - ECD6A6833016AB689F7B8471 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, - 97C146F31CF9000F007C117D /* main.m in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.androidIntentExample; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.androidIntentExample; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/packages/android_intent/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/android_intent/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a16ed0f..000000000000 --- a/packages/android_intent/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/packages/android_intent/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/android_intent/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index 3bb3697ef41c..000000000000 --- a/packages/android_intent/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/android_intent/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/android_intent/example/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 21a3cc14c74e..000000000000 --- a/packages/android_intent/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/packages/android_intent/example/ios/Runner/AppDelegate.h b/packages/android_intent/example/ios/Runner/AppDelegate.h deleted file mode 100644 index d9e18e990f2e..000000000000 --- a/packages/android_intent/example/ios/Runner/AppDelegate.h +++ /dev/null @@ -1,10 +0,0 @@ -// 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. - -#import -#import - -@interface AppDelegate : FlutterAppDelegate - -@end diff --git a/packages/android_intent/example/ios/Runner/AppDelegate.m b/packages/android_intent/example/ios/Runner/AppDelegate.m deleted file mode 100644 index f08675707182..000000000000 --- a/packages/android_intent/example/ios/Runner/AppDelegate.m +++ /dev/null @@ -1,17 +0,0 @@ -// 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. - -#include "AppDelegate.h" -#include "GeneratedPluginRegistrant.h" - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application - didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [GeneratedPluginRegistrant registerWithRegistry:self]; - // Override point for customization after application launch. - return [super application:application didFinishLaunchingWithOptions:launchOptions]; -} - -@end diff --git a/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d22f10b2ab63..000000000000 --- a/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 28c6bf03016f6c994b70f38d1b7346e5831b531f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 564 zcmV-40?Yl0P)Px$?ny*JR5%f>l)FnDQ543{x%ZCiu33$Wg!pQFfT_}?5Q|_VSlIbLC`dpoMXL}9 zHfd9&47Mo(7D231gb+kjFxZHS4-m~7WurTH&doVX2KI5sU4v(sJ1@T9eCIKPjsqSr z)C01LsCxk=72-vXmX}CQD#BD;Cthymh&~=f$Q8nn0J<}ZrusBy4PvRNE}+1ceuj8u z0mW5k8fmgeLnTbWHGwfKA3@PdZxhn|PypR&^p?weGftrtCbjF#+zk_5BJh7;0`#Wr zgDpM_;Ax{jO##IrT`Oz;MvfwGfV$zD#c2xckpcXC6oou4ML~ezCc2EtnsQTB4tWNg z?4bkf;hG7IMfhgNI(FV5Gs4|*GyMTIY0$B=_*mso9Ityq$m^S>15>-?0(zQ<8Qy<_TjHE33(?_M8oaM zyc;NxzRVK@DL6RJnX%U^xW0Gpg(lXp(!uK1v0YgHjs^ZXSQ|m#lV7ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 diff --git a/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index f091b6b0bca859a3f474b03065bef75ba58a9e4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ diff --git a/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index d0ef06e7edb86cdfe0d15b4b0d98334a86163658..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1716 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 diff --git a/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index c8f9ed8f5cee1c98386d13b17e89f719e83555b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 diff --git a/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index 75b2d164a5a98e212cca15ea7bf2ab5de5108680..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3831 zcmVjJBgitF5mAp-i>4+KS_oR{|13AP->1TD4=w)g|)JHOx|a2Wk1Va z!k)vP$UcQ#mdj%wNQoaJ!w>jv_6&JPyutpQps?s5dmDQ>`%?Bvj>o<%kYG!YW6H-z zu`g$@mp`;qDR!51QaS}|ZToSuAGcJ7$2HF0z`ln4t!#Yg46>;vGG9N9{V@9z#}6v* zfP?}r6b{*-C*)(S>NECI_E~{QYzN5SXRmVnP<=gzP+_Sp(Aza_hKlZ{C1D&l*(7IKXxQC1Z9#6wx}YrGcn~g%;icdw>T0Rf^w0{ z$_wn1J+C0@!jCV<%Go5LA45e{5gY9PvZp8uM$=1}XDI+9m7!A95L>q>>oe0$nC->i zeexUIvq%Uk<-$>DiDb?!In)lAmtuMWxvWlk`2>4lNuhSsjAf2*2tjT`y;@d}($o)S zn(+W&hJ1p0xy@oxP%AM15->wPLp{H!k)BdBD$toBpJh+crWdsNV)qsHaqLg2_s|Ih z`8E9z{E3sA!}5aKu?T!#enD(wLw?IT?k-yWVHZ8Akz4k5(TZJN^zZgm&zM28sfTD2BYJ|Fde3Xzh;;S` z=GXTnY4Xc)8nYoz6&vF;P7{xRF-{|2Xs5>a5)@BrnQ}I(_x7Cgpx#5&Td^4Q9_FnQ zX5so*;#8-J8#c$OlA&JyPp$LKUhC~-e~Ij!L%uSMu!-VZG7Hx-L{m2DVR2i=GR(_% zCVD!4N`I)&Q5S`?P&fQZ=4#Dgt_v2-DzkT}K(9gF0L(owe-Id$Rc2qZVLqI_M_DyO z9@LC#U28_LU{;wGZ&))}0R2P4MhajKCd^K#D+JJ&JIXZ_p#@+7J9A&P<0kdRujtQ_ zOy>3=C$kgi6$0pW06KaLz!21oOryKM3ZUOWqppndxfH}QpgjEJ`j7Tzn5bk6K&@RA?vl##y z$?V~1E(!wB5rH`>3nc&@)|#<1dN2cMzzm=PGhQ|Yppne(C-Vlt450IXc`J4R0W@I7 zd1e5uW6juvO%ni(WX7BsKx3MLngO7rHO;^R5I~0^nE^9^E_eYLgiR9&KnJ)pBbfno zSVnW$0R+&6jOOsZ82}nJ126+c|%svPo;TeUku<2G7%?$oft zyaO;tVo}(W)VsTUhq^XmFi#2z%-W9a{7mXn{uzivYQ_d6b7VJG{77naW(vHt-uhnY zVN#d!JTqVh(7r-lhtXVU6o})aZbDt_;&wJVGl2FKYFBFpU-#9U)z#(A%=IVnqytR$SY-sO( z($oNE09{D^@OuYPz&w~?9>Fl5`g9u&ecFGhqX=^#fmR=we0CJw+5xna*@oHnkahk+ z9aWeE3v|An+O5%?4fA&$Fgu~H_YmqR!yIU!bFCk4!#pAj%(lI(A5n)n@Id#M)O9Yx zJU9oKy{sRAIV3=5>(s8n{8ryJ!;ho}%pn6hZKTKbqk=&m=f*UnK$zW3YQP*)pw$O* zIfLA^!-bmBl6%d_n$#tP8Zd_(XdA*z*WH|E_yILwjtI~;jK#v-6jMl^?<%Y%`gvpwv&cFb$||^v4D&V=aNy?NGo620jL3VZnA%s zH~I|qPzB~e(;p;b^gJr7Ure#7?8%F0m4vzzPy^^(q4q1OdthF}Fi*RmVZN1OwTsAP zn9CZP`FazX3^kG(KodIZ=Kty8DLTy--UKfa1$6XugS zk%6v$Kmxt6U!YMx0JQ)0qX*{CXwZZk$vEROidEc7=J-1;peNat!vS<3P-FT5po>iE z!l3R+<`#x|+_hw!HjQGV=8!q|76y8L7N8gP3$%0kfush|u0uU^?dKBaeRSBUpOZ0c z62;D&Mdn2}N}xHRFTRI?zRv=>=AjHgH}`2k4WK=#AHB)UFrR-J87GgX*x5fL^W2#d z=(%K8-oZfMO=i{aWRDg=FX}UubM4eotRDcn;OR#{3q=*?3mE3_oJ-~prjhxh%PgQT zyn)Qozaq0@o&|LEgS{Ind4Swsr;b`u185hZPOBLL<`d2%^Yp1?oL)=jnLi;Zo0ZDliTtQ^b5SmfIMe{T==zZkbvn$KTQGlbG8w}s@M3TZnde;1Am46P3juKb zl9GU&3F=q`>j!`?SyH#r@O59%@aMX^rx}Nxe<>NqpUp5=lX1ojGDIR*-D^SDuvCKF z?3$xG(gVUsBERef_YjPFl^rU9EtD{pt z0CXwpN7BN3!8>hajGaTVk-wl=9rxmfWtIhC{mheHgStLi^+Nz12a?4r(fz)?3A%at zMlvQmL<2-R)-@G1wJ0^zQK%mR=r4d{Y3fHp){nWXUL#|CqXl(+v+qDh>FkF9`eWrW zfr^D%LNfOcTNvtx0JXR35J0~Jpi2#P3Q&80w+nqNfc}&G0A~*)lGHKv=^FE+b(37|)zL;KLF>oiGfb(?&1 zV3XRu!Sw>@quKiab%g6jun#oZ%!>V#A%+lNc?q>6+VvyAn=kf_6z^(TZUa4Eelh{{ zqFX-#dY(EV@7l$NE&kv9u9BR8&Ojd#ZGJ6l8_BW}^r?DIS_rU2(XaGOK z225E@kH5Opf+CgD^{y29jD4gHbGf{1MD6ggQ&%>UG4WyPh5q_tb`{@_34B?xfSO*| zZv8!)q;^o-bz`MuxXk*G^}(6)ACb@=Lfs`Hxoh>`Y0NE8QRQ!*p|SH@{r8=%RKd4p z+#Ty^-0kb=-H-O`nAA3_6>2z(D=~Tbs(n8LHxD0`R0_ATFqp-SdY3(bZ3;VUM?J=O zKCNsxsgt@|&nKMC=*+ZqmLHhX1KHbAJs{nGVMs6~TiF%Q)P@>!koa$%oS zjXa=!5>P`vC-a}ln!uH1ooeI&v?=?v7?1n~P(wZ~0>xWxd_Aw;+}9#eULM7M8&E?Y zC-ZLhi3RoM92SXUb-5i-Lmt5_rfjE{6y^+24`y$1lywLyHO!)Boa7438K4#iLe?rh z2O~YGSgFUBH?og*6=r9rme=peP~ah`(8Zt7V)j5!V0KPFf_mebo3z95U8(up$-+EA^9dTRLq>Yl)YMBuch9%=e5B`Vnb>o zt03=kq;k2TgGe4|lGne&zJa~h(UGutjP_zr?a7~#b)@15XNA>Dj(m=gg2Q5V4-$)D|Q9}R#002ovPDHLkV1o7DH3k3x diff --git a/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/android_intent/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index c4df70d39da7941ef3f6dcb7f06a192d8dcb308d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 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 iW8 - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/android_intent/example/ios/Runner/Base.lproj/Main.storyboard b/packages/android_intent/example/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c28516fb38..000000000000 --- a/packages/android_intent/example/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/android_intent/example/ios/Runner/Info.plist b/packages/android_intent/example/ios/Runner/Info.plist deleted file mode 100644 index 61ad692e0180..000000000000 --- a/packages/android_intent/example/ios/Runner/Info.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - android_intent_example - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - arm64 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - - diff --git a/packages/android_intent/example/ios/Runner/main.m b/packages/android_intent/example/ios/Runner/main.m deleted file mode 100644 index bec320c0bee0..000000000000 --- a/packages/android_intent/example/ios/Runner/main.m +++ /dev/null @@ -1,13 +0,0 @@ -// 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. - -#import -#import -#import "AppDelegate.h" - -int main(int argc, char* argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/packages/android_intent/ios/Assets/.gitkeep b/packages/android_intent/ios/Assets/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/packages/android_intent/ios/Classes/AndroidIntentPlugin.h b/packages/android_intent/ios/Classes/AndroidIntentPlugin.h deleted file mode 100644 index 8810c13f61cf..000000000000 --- a/packages/android_intent/ios/Classes/AndroidIntentPlugin.h +++ /dev/null @@ -1,8 +0,0 @@ -// 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. - -#import - -@interface FLTAndroidIntentPlugin : NSObject -@end diff --git a/packages/android_intent/ios/Classes/AndroidIntentPlugin.m b/packages/android_intent/ios/Classes/AndroidIntentPlugin.m deleted file mode 100644 index d708adf8c1d0..000000000000 --- a/packages/android_intent/ios/Classes/AndroidIntentPlugin.m +++ /dev/null @@ -1,20 +0,0 @@ -// 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. - -#import "AndroidIntentPlugin.h" - -@implementation FLTAndroidIntentPlugin -+ (void)registerWithRegistrar:(NSObject*)registrar { - FlutterMethodChannel* channel = - [FlutterMethodChannel methodChannelWithName:@"plugins.flutter.io/android_intent" - binaryMessenger:[registrar messenger]]; - FLTAndroidIntentPlugin* instance = [[FLTAndroidIntentPlugin alloc] init]; - [registrar addMethodCallDelegate:instance channel:channel]; -} - -- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { - result(FlutterMethodNotImplemented); -} - -@end diff --git a/packages/android_intent/ios/android_intent.podspec b/packages/android_intent/ios/android_intent.podspec deleted file mode 100644 index b3f9b6eb334f..000000000000 --- a/packages/android_intent/ios/android_intent.podspec +++ /dev/null @@ -1,24 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'android_intent' - s.version = '0.0.1' - s.summary = 'Android Intent Plugin for Flutter' - s.description = <<-DESC -This plugin allows Flutter apps to launch arbitrary intents when the platform is Android. -If the plugin is invoked on iOS, it will crash your app. -Downloaded by pub (not CocoaPods). - DESC - s.homepage = 'https://github.com/flutter/plugins' - s.license = { :type => 'BSD', :file => '../LICENSE' } - s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } - s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/android_intent' } - s.documentation_url = 'https://pub.dev/packages/android_intent' - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - s.platform = :ios, '8.0' - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } -end - diff --git a/packages/connectivity/connectivity_for_web/ios/connectivity_for_web.podspec b/packages/connectivity/connectivity_for_web/ios/connectivity_for_web.podspec deleted file mode 100644 index 75b891c56533..000000000000 --- a/packages/connectivity/connectivity_for_web/ios/connectivity_for_web.podspec +++ /dev/null @@ -1,23 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. -# Run `pod lib lint connectivity_web.podspec' to validate before publishing. -# -Pod::Spec.new do |s| - s.name = 'connectivity_for_web' - s.version = '0.1.0' - s.summary = 'No-op implementation of connectivity web plugin to avoid build issues on iOS' - s.description = <<-DESC -temp fake connectivity_web plugin - DESC - s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_for_web' - s.license = { :file => '../LICENSE' } - s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.dependency 'Flutter' - s.platform = :ios, '8.0' - - # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } - s.swift_version = '5.0' -end diff --git a/packages/connectivity/connectivity_macos/example/ios/Flutter/AppFrameworkInfo.plist b/packages/connectivity/connectivity_macos/example/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 6c2de8086bcd..000000000000 --- a/packages/connectivity/connectivity_macos/example/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - UIRequiredDeviceCapabilities - - arm64 - - MinimumOSVersion - 8.0 - - diff --git a/packages/connectivity/connectivity_macos/example/ios/Flutter/Debug.xcconfig b/packages/connectivity/connectivity_macos/example/ios/Flutter/Debug.xcconfig deleted file mode 100644 index e8efba114687..000000000000 --- a/packages/connectivity/connectivity_macos/example/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "Generated.xcconfig" diff --git a/packages/connectivity/connectivity_macos/example/ios/Flutter/Release.xcconfig b/packages/connectivity/connectivity_macos/example/ios/Flutter/Release.xcconfig deleted file mode 100644 index 399e9340e6f6..000000000000 --- a/packages/connectivity/connectivity_macos/example/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "Generated.xcconfig" diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner.xcodeproj/project.pbxproj b/packages/connectivity/connectivity_macos/example/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index e497d093be56..000000000000 --- a/packages/connectivity/connectivity_macos/example/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,490 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; - 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - EB0BA966000B5C35B13186D7 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C80D49AFD183103034E444C2 /* libPods-Runner.a */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 3173C764DD180BE02EB51E47 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; - 69D903F0A9A7C636EE803AF8 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - C80D49AFD183103034E444C2 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, - EB0BA966000B5C35B13186D7 /* libPods-Runner.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 89F516DEFCBF79E39D2885C2 /* Frameworks */ = { - isa = PBXGroup; - children = ( - C80D49AFD183103034E444C2 /* libPods-Runner.a */, - ); - name = Frameworks; - sourceTree = ""; - }; - 8ECC1C323F60D5498EEC2315 /* Pods */ = { - isa = PBXGroup; - children = ( - 69D903F0A9A7C636EE803AF8 /* Pods-Runner.debug.xcconfig */, - 3173C764DD180BE02EB51E47 /* Pods-Runner.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 3B80C3931E831B6300D905FE /* App.framework */, - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEBA1CF902C7004384FC /* Flutter.framework */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - 8ECC1C323F60D5498EEC2315 /* Pods */, - 89F516DEFCBF79E39D2885C2 /* Frameworks */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 97C146F11CF9000F007C117D /* Supporting Files */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - ); - path = Runner; - sourceTree = ""; - }; - 97C146F11CF9000F007C117D /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 97C146F21CF9000F007C117D /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 3BAF367E8BACBC7576CEE653 /* [CP] Check Pods Manifest.lock */, - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 6A2F146AD353BE7A0C3E797E /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; - TargetAttributes = { - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; - }; - 3BAF367E8BACBC7576CEE653 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 6A2F146AD353BE7A0C3E797E /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, - 97C146F31CF9000F007C117D /* main.m in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.connectivityExample; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.connectivityExample; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/connectivity/connectivity_macos/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a16ed0f..000000000000 --- a/packages/connectivity/connectivity_macos/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/connectivity/connectivity_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index 3bb3697ef41c..000000000000 --- a/packages/connectivity/connectivity_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/connectivity/connectivity_macos/example/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 21a3cc14c74e..000000000000 --- a/packages/connectivity/connectivity_macos/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner/AppDelegate.h b/packages/connectivity/connectivity_macos/example/ios/Runner/AppDelegate.h deleted file mode 100644 index d9e18e990f2e..000000000000 --- a/packages/connectivity/connectivity_macos/example/ios/Runner/AppDelegate.h +++ /dev/null @@ -1,10 +0,0 @@ -// 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. - -#import -#import - -@interface AppDelegate : FlutterAppDelegate - -@end diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner/AppDelegate.m b/packages/connectivity/connectivity_macos/example/ios/Runner/AppDelegate.m deleted file mode 100644 index f08675707182..000000000000 --- a/packages/connectivity/connectivity_macos/example/ios/Runner/AppDelegate.m +++ /dev/null @@ -1,17 +0,0 @@ -// 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. - -#include "AppDelegate.h" -#include "GeneratedPluginRegistrant.h" - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application - didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [GeneratedPluginRegistrant registerWithRegistry:self]; - // Override point for customization after application launch. - return [super application:application didFinishLaunchingWithOptions:launchOptions]; -} - -@end diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d22f10b2ab63..000000000000 --- a/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 28c6bf03016f6c994b70f38d1b7346e5831b531f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 564 zcmV-40?Yl0P)Px$?ny*JR5%f>l)FnDQ543{x%ZCiu33$Wg!pQFfT_}?5Q|_VSlIbLC`dpoMXL}9 zHfd9&47Mo(7D231gb+kjFxZHS4-m~7WurTH&doVX2KI5sU4v(sJ1@T9eCIKPjsqSr z)C01LsCxk=72-vXmX}CQD#BD;Cthymh&~=f$Q8nn0J<}ZrusBy4PvRNE}+1ceuj8u z0mW5k8fmgeLnTbWHGwfKA3@PdZxhn|PypR&^p?weGftrtCbjF#+zk_5BJh7;0`#Wr zgDpM_;Ax{jO##IrT`Oz;MvfwGfV$zD#c2xckpcXC6oou4ML~ezCc2EtnsQTB4tWNg z?4bkf;hG7IMfhgNI(FV5Gs4|*GyMTIY0$B=_*mso9Ityq$m^S>15>-?0(zQ<8Qy<_TjHE33(?_M8oaM zyc;NxzRVK@DL6RJnX%U^xW0Gpg(lXp(!uK1v0YgHjs^ZXSQ|m#lV7ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index f091b6b0bca859a3f474b03065bef75ba58a9e4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index d0ef06e7edb86cdfe0d15b4b0d98334a86163658..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1716 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 diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index c8f9ed8f5cee1c98386d13b17e89f719e83555b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index 75b2d164a5a98e212cca15ea7bf2ab5de5108680..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3831 zcmVjJBgitF5mAp-i>4+KS_oR{|13AP->1TD4=w)g|)JHOx|a2Wk1Va z!k)vP$UcQ#mdj%wNQoaJ!w>jv_6&JPyutpQps?s5dmDQ>`%?Bvj>o<%kYG!YW6H-z zu`g$@mp`;qDR!51QaS}|ZToSuAGcJ7$2HF0z`ln4t!#Yg46>;vGG9N9{V@9z#}6v* zfP?}r6b{*-C*)(S>NECI_E~{QYzN5SXRmVnP<=gzP+_Sp(Aza_hKlZ{C1D&l*(7IKXxQC1Z9#6wx}YrGcn~g%;icdw>T0Rf^w0{ z$_wn1J+C0@!jCV<%Go5LA45e{5gY9PvZp8uM$=1}XDI+9m7!A95L>q>>oe0$nC->i zeexUIvq%Uk<-$>DiDb?!In)lAmtuMWxvWlk`2>4lNuhSsjAf2*2tjT`y;@d}($o)S zn(+W&hJ1p0xy@oxP%AM15->wPLp{H!k)BdBD$toBpJh+crWdsNV)qsHaqLg2_s|Ih z`8E9z{E3sA!}5aKu?T!#enD(wLw?IT?k-yWVHZ8Akz4k5(TZJN^zZgm&zM28sfTD2BYJ|Fde3Xzh;;S` z=GXTnY4Xc)8nYoz6&vF;P7{xRF-{|2Xs5>a5)@BrnQ}I(_x7Cgpx#5&Td^4Q9_FnQ zX5so*;#8-J8#c$OlA&JyPp$LKUhC~-e~Ij!L%uSMu!-VZG7Hx-L{m2DVR2i=GR(_% zCVD!4N`I)&Q5S`?P&fQZ=4#Dgt_v2-DzkT}K(9gF0L(owe-Id$Rc2qZVLqI_M_DyO z9@LC#U28_LU{;wGZ&))}0R2P4MhajKCd^K#D+JJ&JIXZ_p#@+7J9A&P<0kdRujtQ_ zOy>3=C$kgi6$0pW06KaLz!21oOryKM3ZUOWqppndxfH}QpgjEJ`j7Tzn5bk6K&@RA?vl##y z$?V~1E(!wB5rH`>3nc&@)|#<1dN2cMzzm=PGhQ|Yppne(C-Vlt450IXc`J4R0W@I7 zd1e5uW6juvO%ni(WX7BsKx3MLngO7rHO;^R5I~0^nE^9^E_eYLgiR9&KnJ)pBbfno zSVnW$0R+&6jOOsZ82}nJ126+c|%svPo;TeUku<2G7%?$oft zyaO;tVo}(W)VsTUhq^XmFi#2z%-W9a{7mXn{uzivYQ_d6b7VJG{77naW(vHt-uhnY zVN#d!JTqVh(7r-lhtXVU6o})aZbDt_;&wJVGl2FKYFBFpU-#9U)z#(A%=IVnqytR$SY-sO( z($oNE09{D^@OuYPz&w~?9>Fl5`g9u&ecFGhqX=^#fmR=we0CJw+5xna*@oHnkahk+ z9aWeE3v|An+O5%?4fA&$Fgu~H_YmqR!yIU!bFCk4!#pAj%(lI(A5n)n@Id#M)O9Yx zJU9oKy{sRAIV3=5>(s8n{8ryJ!;ho}%pn6hZKTKbqk=&m=f*UnK$zW3YQP*)pw$O* zIfLA^!-bmBl6%d_n$#tP8Zd_(XdA*z*WH|E_yILwjtI~;jK#v-6jMl^?<%Y%`gvpwv&cFb$||^v4D&V=aNy?NGo620jL3VZnA%s zH~I|qPzB~e(;p;b^gJr7Ure#7?8%F0m4vzzPy^^(q4q1OdthF}Fi*RmVZN1OwTsAP zn9CZP`FazX3^kG(KodIZ=Kty8DLTy--UKfa1$6XugS zk%6v$Kmxt6U!YMx0JQ)0qX*{CXwZZk$vEROidEc7=J-1;peNat!vS<3P-FT5po>iE z!l3R+<`#x|+_hw!HjQGV=8!q|76y8L7N8gP3$%0kfush|u0uU^?dKBaeRSBUpOZ0c z62;D&Mdn2}N}xHRFTRI?zRv=>=AjHgH}`2k4WK=#AHB)UFrR-J87GgX*x5fL^W2#d z=(%K8-oZfMO=i{aWRDg=FX}UubM4eotRDcn;OR#{3q=*?3mE3_oJ-~prjhxh%PgQT zyn)Qozaq0@o&|LEgS{Ind4Swsr;b`u185hZPOBLL<`d2%^Yp1?oL)=jnLi;Zo0ZDliTtQ^b5SmfIMe{T==zZkbvn$KTQGlbG8w}s@M3TZnde;1Am46P3juKb zl9GU&3F=q`>j!`?SyH#r@O59%@aMX^rx}Nxe<>NqpUp5=lX1ojGDIR*-D^SDuvCKF z?3$xG(gVUsBERef_YjPFl^rU9EtD{pt z0CXwpN7BN3!8>hajGaTVk-wl=9rxmfWtIhC{mheHgStLi^+Nz12a?4r(fz)?3A%at zMlvQmL<2-R)-@G1wJ0^zQK%mR=r4d{Y3fHp){nWXUL#|CqXl(+v+qDh>FkF9`eWrW zfr^D%LNfOcTNvtx0JXR35J0~Jpi2#P3Q&80w+nqNfc}&G0A~*)lGHKv=^FE+b(37|)zL;KLF>oiGfb(?&1 zV3XRu!Sw>@quKiab%g6jun#oZ%!>V#A%+lNc?q>6+VvyAn=kf_6z^(TZUa4Eelh{{ zqFX-#dY(EV@7l$NE&kv9u9BR8&Ojd#ZGJ6l8_BW}^r?DIS_rU2(XaGOK z225E@kH5Opf+CgD^{y29jD4gHbGf{1MD6ggQ&%>UG4WyPh5q_tb`{@_34B?xfSO*| zZv8!)q;^o-bz`MuxXk*G^}(6)ACb@=Lfs`Hxoh>`Y0NE8QRQ!*p|SH@{r8=%RKd4p z+#Ty^-0kb=-H-O`nAA3_6>2z(D=~Tbs(n8LHxD0`R0_ATFqp-SdY3(bZ3;VUM?J=O zKCNsxsgt@|&nKMC=*+ZqmLHhX1KHbAJs{nGVMs6~TiF%Q)P@>!koa$%oS zjXa=!5>P`vC-a}ln!uH1ooeI&v?=?v7?1n~P(wZ~0>xWxd_Aw;+}9#eULM7M8&E?Y zC-ZLhi3RoM92SXUb-5i-Lmt5_rfjE{6y^+24`y$1lywLyHO!)Boa7438K4#iLe?rh z2O~YGSgFUBH?og*6=r9rme=peP~ah`(8Zt7V)j5!V0KPFf_mebo3z95U8(up$-+EA^9dTRLq>Yl)YMBuch9%=e5B`Vnb>o zt03=kq;k2TgGe4|lGne&zJa~h(UGutjP_zr?a7~#b)@15XNA>Dj(m=gg2Q5V4-$)D|Q9}R#002ovPDHLkV1o7DH3k3x diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/connectivity/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index c4df70d39da7941ef3f6dcb7f06a192d8dcb308d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 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 iW8 - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner/Base.lproj/Main.storyboard b/packages/connectivity/connectivity_macos/example/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c28516fb38..000000000000 --- a/packages/connectivity/connectivity_macos/example/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner/Info.plist b/packages/connectivity/connectivity_macos/example/ios/Runner/Info.plist deleted file mode 100644 index babbd80f1619..000000000000 --- a/packages/connectivity/connectivity_macos/example/ios/Runner/Info.plist +++ /dev/null @@ -1,53 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - connectivity_example - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - NSLocationAlwaysAndWhenInUseUsageDescription - This app requires accessing your location information all the time to get wi-fi information. - NSLocationWhenInUseUsageDescription - This app requires accessing your location information when the app is in foreground to get wi-fi information. - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - arm64 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - - diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner/Runner.entitlements b/packages/connectivity/connectivity_macos/example/ios/Runner/Runner.entitlements deleted file mode 100644 index ba21fbdaf290..000000000000 --- a/packages/connectivity/connectivity_macos/example/ios/Runner/Runner.entitlements +++ /dev/null @@ -1,8 +0,0 @@ - - - - - com.apple.developer.networking.wifi-info - - - diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner/main.m b/packages/connectivity/connectivity_macos/example/ios/Runner/main.m deleted file mode 100644 index bec320c0bee0..000000000000 --- a/packages/connectivity/connectivity_macos/example/ios/Runner/main.m +++ /dev/null @@ -1,13 +0,0 @@ -// 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. - -#import -#import -#import "AppDelegate.h" - -int main(int argc, char* argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/packages/connectivity/connectivity_macos/ios/connectivity_macos.podspec b/packages/connectivity/connectivity_macos/ios/connectivity_macos.podspec deleted file mode 100644 index a941a16327f3..000000000000 --- a/packages/connectivity/connectivity_macos/ios/connectivity_macos.podspec +++ /dev/null @@ -1,21 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'connectivity_macos' - s.version = '0.0.1' - s.summary = 'No-op implementation of the connectivity desktop plugin to avoid build issues on iOS' - s.description = <<-DESC - No-op implementation of connectivity_macos to avoid build issues on iOS. - See https://github.com/flutter/flutter/issues/39659 - DESC - s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_macos' - s.license = { :file => '../LICENSE' } - s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - - s.ios.deployment_target = '8.0' -end \ No newline at end of file diff --git a/packages/espresso/example/ios/.gitignore b/packages/espresso/example/ios/.gitignore deleted file mode 100644 index e96ef602b8d1..000000000000 --- a/packages/espresso/example/ios/.gitignore +++ /dev/null @@ -1,32 +0,0 @@ -*.mode1v3 -*.mode2v3 -*.moved-aside -*.pbxuser -*.perspectivev3 -**/*sync/ -.sconsign.dblite -.tags* -**/.vagrant/ -**/DerivedData/ -Icon? -**/Pods/ -**/.symlinks/ -profile -xcuserdata -**/.generated/ -Flutter/App.framework -Flutter/Flutter.framework -Flutter/Flutter.podspec -Flutter/Generated.xcconfig -Flutter/app.flx -Flutter/app.zip -Flutter/flutter_assets/ -Flutter/flutter_export_environment.sh -ServiceDefinitions.json -Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!default.mode1v3 -!default.mode2v3 -!default.pbxuser -!default.perspectivev3 diff --git a/packages/espresso/example/ios/Flutter/AppFrameworkInfo.plist b/packages/espresso/example/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 6b4c0f78a785..000000000000 --- a/packages/espresso/example/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - MinimumOSVersion - 8.0 - - diff --git a/packages/espresso/example/ios/Flutter/Debug.xcconfig b/packages/espresso/example/ios/Flutter/Debug.xcconfig deleted file mode 100644 index e8efba114687..000000000000 --- a/packages/espresso/example/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "Generated.xcconfig" diff --git a/packages/espresso/example/ios/Flutter/Release.xcconfig b/packages/espresso/example/ios/Flutter/Release.xcconfig deleted file mode 100644 index 399e9340e6f6..000000000000 --- a/packages/espresso/example/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "Generated.xcconfig" diff --git a/packages/espresso/example/ios/Runner.xcodeproj/project.pbxproj b/packages/espresso/example/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index 2209e01dfcd6..000000000000 --- a/packages/espresso/example/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,584 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - B4A70C1E3465B7A2E7ECD8F8 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AE5F32230E1B4F4C17EDB557 /* Pods_Runner.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 02691CEFCB33C0B1CABE7A23 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 09442C04D3DC0049E7725D93 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; - 3EF237100A0BFC444DE6BC97 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - AE5F32230E1B4F4C17EDB557 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, - B4A70C1E3465B7A2E7ECD8F8 /* Pods_Runner.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 301432828879F7BDE0943C41 /* Frameworks */ = { - isa = PBXGroup; - children = ( - AE5F32230E1B4F4C17EDB557 /* Pods_Runner.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 3B80C3931E831B6300D905FE /* App.framework */, - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEBA1CF902C7004384FC /* Flutter.framework */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - E9E5CC94EC52B9D261A44A5E /* Pods */, - 301432828879F7BDE0943C41 /* Frameworks */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 97C146F11CF9000F007C117D /* Supporting Files */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, - ); - path = Runner; - sourceTree = ""; - }; - 97C146F11CF9000F007C117D /* Supporting Files */ = { - isa = PBXGroup; - children = ( - ); - name = "Supporting Files"; - sourceTree = ""; - }; - E9E5CC94EC52B9D261A44A5E /* Pods */ = { - isa = PBXGroup; - children = ( - 02691CEFCB33C0B1CABE7A23 /* Pods-Runner.debug.xcconfig */, - 3EF237100A0BFC444DE6BC97 /* Pods-Runner.release.xcconfig */, - 09442C04D3DC0049E7725D93 /* Pods-Runner.profile.xcconfig */, - ); - name = Pods; - path = Pods; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 5D7E711796DC6F61E7F1A6AE /* [CP] Check Pods Manifest.lock */, - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - DC7821945A6EDE472DDF686F /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1020; - ORGANIZATIONNAME = "The Chromium Authors"; - TargetAttributes = { - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 1100; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; - }; - 5D7E711796DC6F61E7F1A6AE /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; - DC7821945A6EDE472DDF686F /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 249021D3217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Profile; - }; - 249021D4217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.espressoExample; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Profile; - }; - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.espressoExample; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.espressoExample; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - 249021D3217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - 249021D4217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/packages/espresso/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/espresso/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index a28140cfdb3f..000000000000 --- a/packages/espresso/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/espresso/example/ios/Runner/AppDelegate.swift b/packages/espresso/example/ios/Runner/AppDelegate.swift deleted file mode 100644 index 70693e4a8c12..000000000000 --- a/packages/espresso/example/ios/Runner/AppDelegate.swift +++ /dev/null @@ -1,13 +0,0 @@ -import UIKit -import Flutter - -@UIApplicationMain -@objc class AppDelegate: FlutterAppDelegate { - override func application( - _ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? - ) -> Bool { - GeneratedPluginRegistrant.register(with: self) - return super.application(application, didFinishLaunchingWithOptions: launchOptions) - } -} diff --git a/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d36b1fab2d9d..000000000000 --- a/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon-App-1024x1024@1x.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png deleted file mode 100644 index dc9ada4725e9b0ddb1deab583e5b5102493aa332..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10932 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 diff --git a/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index f091b6b0bca859a3f474b03065bef75ba58a9e4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ diff --git a/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index d0ef06e7edb86cdfe0d15b4b0d98334a86163658..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1716 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 diff --git a/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index c8f9ed8f5cee1c98386d13b17e89f719e83555b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 diff --git a/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index 75b2d164a5a98e212cca15ea7bf2ab5de5108680..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3831 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 diff --git a/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/espresso/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index c4df70d39da7941ef3f6dcb7f06a192d8dcb308d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 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 iW8Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/packages/espresso/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/packages/espresso/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/packages/espresso/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/packages/espresso/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/packages/espresso/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/packages/espresso/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md deleted file mode 100644 index 89c2725b70f1..000000000000 --- a/packages/espresso/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Launch Screen Assets - -You can customize the launch screen with your own desired assets by replacing the image files in this directory. - -You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/packages/espresso/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/espresso/example/ios/Runner/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index f2e259c7c939..000000000000 --- a/packages/espresso/example/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/espresso/example/ios/Runner/Base.lproj/Main.storyboard b/packages/espresso/example/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c28516fb38..000000000000 --- a/packages/espresso/example/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/espresso/example/ios/Runner/Info.plist b/packages/espresso/example/ios/Runner/Info.plist deleted file mode 100644 index 96cc992ec974..000000000000 --- a/packages/espresso/example/ios/Runner/Info.plist +++ /dev/null @@ -1,45 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - espresso_example - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - - diff --git a/packages/espresso/example/ios/Runner/Runner-Bridging-Header.h b/packages/espresso/example/ios/Runner/Runner-Bridging-Header.h deleted file mode 100644 index 7335fdf9000c..000000000000 --- a/packages/espresso/example/ios/Runner/Runner-Bridging-Header.h +++ /dev/null @@ -1 +0,0 @@ -#import "GeneratedPluginRegistrant.h" \ No newline at end of file diff --git a/packages/espresso/ios/.gitignore b/packages/espresso/ios/.gitignore deleted file mode 100644 index aa479fd3ce8a..000000000000 --- a/packages/espresso/ios/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -.idea/ -.vagrant/ -.sconsign.dblite -.svn/ - -.DS_Store -*.swp -profile - -DerivedData/ -build/ -GeneratedPluginRegistrant.h -GeneratedPluginRegistrant.m - -.generated/ - -*.pbxuser -*.mode1v3 -*.mode2v3 -*.perspectivev3 - -!default.pbxuser -!default.mode1v3 -!default.mode2v3 -!default.perspectivev3 - -xcuserdata - -*.moved-aside - -*.pyc -*sync/ -Icon? -.tags* - -/Flutter/Generated.xcconfig -/Flutter/flutter_export_environment.sh \ No newline at end of file diff --git a/packages/espresso/ios/Assets/.gitkeep b/packages/espresso/ios/Assets/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/packages/espresso/ios/Classes/EspressoPlugin.h b/packages/espresso/ios/Classes/EspressoPlugin.h deleted file mode 100644 index 5f9761591f72..000000000000 --- a/packages/espresso/ios/Classes/EspressoPlugin.h +++ /dev/null @@ -1,4 +0,0 @@ -#import - -@interface EspressoPlugin : NSObject -@end diff --git a/packages/espresso/ios/Classes/EspressoPlugin.m b/packages/espresso/ios/Classes/EspressoPlugin.m deleted file mode 100644 index cb4ef8072cae..000000000000 --- a/packages/espresso/ios/Classes/EspressoPlugin.m +++ /dev/null @@ -1,15 +0,0 @@ -#import "EspressoPlugin.h" - -@implementation EspressoPlugin -+ (void)registerWithRegistrar:(NSObject*)registrar { - FlutterMethodChannel* channel = - [FlutterMethodChannel methodChannelWithName:@"espresso" - binaryMessenger:[registrar messenger]]; - EspressoPlugin* instance = [[EspressoPlugin alloc] init]; - [registrar addMethodCallDelegate:instance channel:channel]; -} - -- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { - result(FlutterMethodNotImplemented); -} -@end diff --git a/packages/espresso/ios/espresso.podspec b/packages/espresso/ios/espresso.podspec deleted file mode 100644 index c9b2d106fd92..000000000000 --- a/packages/espresso/ios/espresso.podspec +++ /dev/null @@ -1,25 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. -# Run `pod lib lint espresso.podspec' to validate before publishing. -# -Pod::Spec.new do |s| - s.name = 'espresso' - s.version = '0.0.1' - s.summary = 'Flutter Espresso' - s.description = <<-DESC -Provides bindings for Espresso tests of Flutter apps. -Downloaded by pub (not CocoaPods). - DESC - s.homepage = 'https://github.com/flutter/plugins' - s.license = { :type => 'BSD', :file => '../LICENSE' } - s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } - s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/espresso' } - s.documentation_url = 'https://pub.dev/packages/espresso' - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - s.platform = :ios, '8.0' - - # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } -end diff --git a/packages/espresso/pubspec.yaml b/packages/espresso/pubspec.yaml index e7e1f6691ed3..e79c46e73e40 100644 --- a/packages/espresso/pubspec.yaml +++ b/packages/espresso/pubspec.yaml @@ -23,5 +23,3 @@ flutter: android: package: com.example.espresso pluginClass: EspressoPlugin - ios: - pluginClass: EspressoPlugin diff --git a/packages/file_selector/file_selector_web/ios/file_selector_web.podspec b/packages/file_selector/file_selector_web/ios/file_selector_web.podspec deleted file mode 100644 index 20656121029d..000000000000 --- a/packages/file_selector/file_selector_web/ios/file_selector_web.podspec +++ /dev/null @@ -1,21 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'file_selector_web' - s.version = '0.0.1' - s.summary = 'No-op implementation of file_selector_web web plugin to avoid build issues on iOS' - s.description = <<-DESC - temp fake file_selector_web plugin - DESC - s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/file_selector/file_selector_web' - s.license = { :file => '../LICENSE' } - s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - - s.ios.deployment_target = '8.0' - end - \ No newline at end of file diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/.gitignore b/packages/flutter_plugin_android_lifecycle/example/ios/.gitignore deleted file mode 100644 index f78c1480b6dd..000000000000 --- a/packages/flutter_plugin_android_lifecycle/example/ios/.gitignore +++ /dev/null @@ -1,31 +0,0 @@ -*.mode1v3 -*.mode2v3 -*.moved-aside -*.pbxuser -*.perspectivev3 -**/*sync/ -.sconsign.dblite -.tags* -**/.vagrant/ -**/DerivedData/ -Icon? -**/Pods/ -**/.symlinks/ -profile -xcuserdata -**/.generated/ -Flutter/App.framework -Flutter/Flutter.framework -Flutter/Generated.xcconfig -Flutter/app.flx -Flutter/app.zip -Flutter/flutter_assets/ -Flutter/flutter_export_environment.sh -ServiceDefinitions.json -Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!default.mode1v3 -!default.mode2v3 -!default.pbxuser -!default.perspectivev3 diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Flutter/AppFrameworkInfo.plist b/packages/flutter_plugin_android_lifecycle/example/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 6b4c0f78a785..000000000000 --- a/packages/flutter_plugin_android_lifecycle/example/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - MinimumOSVersion - 8.0 - - diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Flutter/Debug.xcconfig b/packages/flutter_plugin_android_lifecycle/example/ios/Flutter/Debug.xcconfig deleted file mode 100644 index e8efba114687..000000000000 --- a/packages/flutter_plugin_android_lifecycle/example/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "Generated.xcconfig" diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Flutter/Release.xcconfig b/packages/flutter_plugin_android_lifecycle/example/ios/Flutter/Release.xcconfig deleted file mode 100644 index 399e9340e6f6..000000000000 --- a/packages/flutter_plugin_android_lifecycle/example/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "Generated.xcconfig" diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner.xcodeproj/project.pbxproj b/packages/flutter_plugin_android_lifecycle/example/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index f42fc07b1c19..000000000000 --- a/packages/flutter_plugin_android_lifecycle/example/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,576 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 68BFFC9A2252F6377926CCB6 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D97B2D435F77384E1832544A /* libPods-Runner.a */; }; - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; - 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; - 48B2B2D61E102CB7FCA66327 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 8A495AA36DFBF39C3BD5D917 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 9E27BB0D8AE008E9718C1EC3 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - D97B2D435F77384E1832544A /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, - 68BFFC9A2252F6377926CCB6 /* libPods-Runner.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 29946A38AEAEDCD95716766D /* Pods */ = { - isa = PBXGroup; - children = ( - 8A495AA36DFBF39C3BD5D917 /* Pods-Runner.debug.xcconfig */, - 9E27BB0D8AE008E9718C1EC3 /* Pods-Runner.release.xcconfig */, - 48B2B2D61E102CB7FCA66327 /* Pods-Runner.profile.xcconfig */, - ); - name = Pods; - path = Pods; - sourceTree = ""; - }; - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 3B80C3931E831B6300D905FE /* App.framework */, - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEBA1CF902C7004384FC /* Flutter.framework */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - 29946A38AEAEDCD95716766D /* Pods */, - C6B60E52AC0C0C398A9D6E3E /* Frameworks */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 97C146F11CF9000F007C117D /* Supporting Files */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - ); - path = Runner; - sourceTree = ""; - }; - 97C146F11CF9000F007C117D /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 97C146F21CF9000F007C117D /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - C6B60E52AC0C0C398A9D6E3E /* Frameworks */ = { - isa = PBXGroup; - children = ( - D97B2D435F77384E1832544A /* libPods-Runner.a */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - B0349D7BFB658C43C3407041 /* [CP] Check Pods Manifest.lock */, - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 2D345E120F865FCD8BCE231E /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1020; - ORGANIZATIONNAME = "The Chromium Authors"; - TargetAttributes = { - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 2D345E120F865FCD8BCE231E /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; - B0349D7BFB658C43C3407041 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, - 97C146F31CF9000F007C117D /* main.m in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 249021D3217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Profile; - }; - 249021D4217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.flutterAndroidLifecycleExample; - PRODUCT_NAME = "$(TARGET_NAME)"; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Profile; - }; - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.flutterAndroidLifecycleExample; - PRODUCT_NAME = "$(TARGET_NAME)"; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.flutterAndroidLifecycleExample; - PRODUCT_NAME = "$(TARGET_NAME)"; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - 249021D3217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - 249021D4217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/flutter_plugin_android_lifecycle/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index a28140cfdb3f..000000000000 --- a/packages/flutter_plugin_android_lifecycle/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/AppDelegate.h b/packages/flutter_plugin_android_lifecycle/example/ios/Runner/AppDelegate.h deleted file mode 100644 index 36e21bbf9cf4..000000000000 --- a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/AppDelegate.h +++ /dev/null @@ -1,6 +0,0 @@ -#import -#import - -@interface AppDelegate : FlutterAppDelegate - -@end diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/AppDelegate.m b/packages/flutter_plugin_android_lifecycle/example/ios/Runner/AppDelegate.m deleted file mode 100644 index 59a72e90be12..000000000000 --- a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/AppDelegate.m +++ /dev/null @@ -1,13 +0,0 @@ -#include "AppDelegate.h" -#include "GeneratedPluginRegistrant.h" - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application - didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [GeneratedPluginRegistrant registerWithRegistry:self]; - // Override point for customization after application launch. - return [super application:application didFinishLaunchingWithOptions:launchOptions]; -} - -@end diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d36b1fab2d9d..000000000000 --- a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon-App-1024x1024@1x.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png deleted file mode 100644 index dc9ada4725e9b0ddb1deab583e5b5102493aa332..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10932 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 diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index f091b6b0bca859a3f474b03065bef75ba58a9e4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index d0ef06e7edb86cdfe0d15b4b0d98334a86163658..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1716 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 diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index c8f9ed8f5cee1c98386d13b17e89f719e83555b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index 75b2d164a5a98e212cca15ea7bf2ab5de5108680..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3831 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 diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index c4df70d39da7941ef3f6dcb7f06a192d8dcb308d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 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 iW8Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md deleted file mode 100644 index 89c2725b70f1..000000000000 --- a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Launch Screen Assets - -You can customize the launch screen with your own desired assets by replacing the image files in this directory. - -You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index f2e259c7c939..000000000000 --- a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Base.lproj/Main.storyboard b/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c28516fb38..000000000000 --- a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Info.plist b/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Info.plist deleted file mode 100644 index 8526e1f7226c..000000000000 --- a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/Info.plist +++ /dev/null @@ -1,45 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - flutter_plugin_android_lifecycle_example - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - - diff --git a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/main.m b/packages/flutter_plugin_android_lifecycle/example/ios/Runner/main.m deleted file mode 100644 index dff6597e4513..000000000000 --- a/packages/flutter_plugin_android_lifecycle/example/ios/Runner/main.m +++ /dev/null @@ -1,9 +0,0 @@ -#import -#import -#import "AppDelegate.h" - -int main(int argc, char* argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/packages/flutter_plugin_android_lifecycle/ios/.gitignore b/packages/flutter_plugin_android_lifecycle/ios/.gitignore deleted file mode 100644 index aa479fd3ce8a..000000000000 --- a/packages/flutter_plugin_android_lifecycle/ios/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -.idea/ -.vagrant/ -.sconsign.dblite -.svn/ - -.DS_Store -*.swp -profile - -DerivedData/ -build/ -GeneratedPluginRegistrant.h -GeneratedPluginRegistrant.m - -.generated/ - -*.pbxuser -*.mode1v3 -*.mode2v3 -*.perspectivev3 - -!default.pbxuser -!default.mode1v3 -!default.mode2v3 -!default.perspectivev3 - -xcuserdata - -*.moved-aside - -*.pyc -*sync/ -Icon? -.tags* - -/Flutter/Generated.xcconfig -/Flutter/flutter_export_environment.sh \ No newline at end of file diff --git a/packages/flutter_plugin_android_lifecycle/ios/Assets/.gitkeep b/packages/flutter_plugin_android_lifecycle/ios/Assets/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/packages/flutter_plugin_android_lifecycle/ios/Classes/FlutterAndroidLifecyclePlugin.h b/packages/flutter_plugin_android_lifecycle/ios/Classes/FlutterAndroidLifecyclePlugin.h deleted file mode 100644 index a554ce0500c6..000000000000 --- a/packages/flutter_plugin_android_lifecycle/ios/Classes/FlutterAndroidLifecyclePlugin.h +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2019 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. - -#import - -@interface FlutterAndroidLifecyclePlugin : NSObject -@end diff --git a/packages/flutter_plugin_android_lifecycle/ios/Classes/FlutterAndroidLifecyclePlugin.m b/packages/flutter_plugin_android_lifecycle/ios/Classes/FlutterAndroidLifecyclePlugin.m deleted file mode 100644 index 38cffd362da7..000000000000 --- a/packages/flutter_plugin_android_lifecycle/ios/Classes/FlutterAndroidLifecyclePlugin.m +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2019 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. - -#import "FlutterAndroidLifecyclePlugin.h" - -@implementation FlutterAndroidLifecyclePlugin -+ (void)registerWithRegistrar:(NSObject*)registrar { -} -@end diff --git a/packages/flutter_plugin_android_lifecycle/ios/flutter_plugin_android_lifecycle.podspec b/packages/flutter_plugin_android_lifecycle/ios/flutter_plugin_android_lifecycle.podspec deleted file mode 100644 index 0c802a3101ba..000000000000 --- a/packages/flutter_plugin_android_lifecycle/ios/flutter_plugin_android_lifecycle.podspec +++ /dev/null @@ -1,26 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. -# Run `pod lib lint flutter_plugin_android_lifecycle.podspec' to validate before publishing. -# -Pod::Spec.new do |s| - s.name = 'flutter_plugin_android_lifecycle' - s.version = '0.0.1' - s.summary = 'Flutter Android Lifecycle Plugin' - s.description = <<-DESC -A Flutter plugin for Android to allow other Flutter plugins to access Android Lifecycle objects in the plugin's binding. -This plugin a no-op on iOS. -Downloaded by pub (not CocoaPods). - DESC - s.homepage = 'https://github.com/flutter/plugins' - s.license = { :type => 'BSD', :file => '../LICENSE' } - s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } - s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/flutter_plugin_android_lifecycle' } - s.documentation_url = 'https://pub.dev/packages/flutter_plugin_android_lifecycle' - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - s.platform = :ios, '8.0' - - # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } -end diff --git a/packages/google_maps_flutter/google_maps_flutter_web/ios/google_maps_flutter_web.podspec b/packages/google_maps_flutter/google_maps_flutter_web/ios/google_maps_flutter_web.podspec deleted file mode 100644 index 18db6ced01b6..000000000000 --- a/packages/google_maps_flutter/google_maps_flutter_web/ios/google_maps_flutter_web.podspec +++ /dev/null @@ -1,23 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. -# Run `pod lib lint google_maps_flutter_web.podspec' to validate before publishing. -# -Pod::Spec.new do |s| - s.name = 'google_maps_flutter_web' - s.version = '0.1.0' - s.summary = 'No-op implementation of google maps flutter web plugin to avoid build issues on iOS' - s.description = <<-DESC -temp fake google_maps_flutter_web plugin - DESC - s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter_web' - s.license = { :file => '../LICENSE' } - s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.dependency 'Flutter' - s.platform = :ios, '8.0' - - # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } - s.swift_version = '5.0' -end diff --git a/packages/google_sign_in/google_sign_in_web/ios/google_sign_in_web.podspec b/packages/google_sign_in/google_sign_in_web/ios/google_sign_in_web.podspec deleted file mode 100644 index 5e192172eb4b..000000000000 --- a/packages/google_sign_in/google_sign_in_web/ios/google_sign_in_web.podspec +++ /dev/null @@ -1,21 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'google_sign_in_web' - s.version = '0.8.1' - s.summary = 'No-op implementation of google_sign_in_web web plugin to avoid build issues on iOS' - s.description = <<-DESC - temp fake google_sign_in_web plugin - DESC - s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in_web' - s.license = { :file => '../LICENSE' } - s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - - s.ios.deployment_target = '8.0' - end - \ No newline at end of file diff --git a/packages/image_picker/image_picker_for_web/ios/image_picker_for_web.podspec b/packages/image_picker/image_picker_for_web/ios/image_picker_for_web.podspec deleted file mode 100644 index 23fb795d1cc2..000000000000 --- a/packages/image_picker/image_picker_for_web/ios/image_picker_for_web.podspec +++ /dev/null @@ -1,20 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'image_picker_for_web' - s.version = '0.0.1' - s.summary = 'No-op implementation of image_picker_for_web plugin to avoid build issues on iOS' - s.description = <<-DESC -temp fake image_picker_for_web plugin - DESC - s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker_for_web' - s.license = { :file => '../LICENSE' } - s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - - s.ios.deployment_target = '8.0' -end diff --git a/packages/integration_test/integration_test_macos/ios/integration_test_macos.podspec b/packages/integration_test/integration_test_macos/ios/integration_test_macos.podspec deleted file mode 100644 index 7294590a6479..000000000000 --- a/packages/integration_test/integration_test_macos/ios/integration_test_macos.podspec +++ /dev/null @@ -1,21 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'IntegrationTestMacOS' - s.version = '0.0.1' - s.summary = 'No-op implementation of the integration_test desktop plugin to avoid build issues on iOS' - s.description = <<-DESC - No-op implementation of integration to avoid build issues on iOS. - See https://github.com/flutter/flutter/issues/39659 - DESC - s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/integration_test/integration_test_macos' - s.license = { :file => '../LICENSE' } - s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - - s.ios.deployment_target = '8.0' -end \ No newline at end of file diff --git a/packages/path_provider/path_provider_linux/ios/.gitignore b/packages/path_provider/path_provider_linux/ios/.gitignore deleted file mode 100644 index aa479fd3ce8a..000000000000 --- a/packages/path_provider/path_provider_linux/ios/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -.idea/ -.vagrant/ -.sconsign.dblite -.svn/ - -.DS_Store -*.swp -profile - -DerivedData/ -build/ -GeneratedPluginRegistrant.h -GeneratedPluginRegistrant.m - -.generated/ - -*.pbxuser -*.mode1v3 -*.mode2v3 -*.perspectivev3 - -!default.pbxuser -!default.mode1v3 -!default.mode2v3 -!default.perspectivev3 - -xcuserdata - -*.moved-aside - -*.pyc -*sync/ -Icon? -.tags* - -/Flutter/Generated.xcconfig -/Flutter/flutter_export_environment.sh \ No newline at end of file diff --git a/packages/path_provider/path_provider_linux/ios/path_provider_linux.podspec b/packages/path_provider/path_provider_linux/ios/path_provider_linux.podspec deleted file mode 100644 index 3649a30e67ef..000000000000 --- a/packages/path_provider/path_provider_linux/ios/path_provider_linux.podspec +++ /dev/null @@ -1,19 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'path_provider_linux' - s.version = '0.0.1' - s.summary = 'No-op implementation of path_provider linux plugin to avoid build issues on iOS' - s.description = <<-DESC - No-op implementation of path_provider linux plugin - See https://github.com/flutter/flutter/issues/39659 - DESC - s.homepage = 'https://github.com/flutter/plugins' - s.license = { :type => 'BSD', :file => '../LICENSE' } - s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } - s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_linux' } - s.documentation_url = 'https://pub.dev/packages/path_provider' - s.dependency 'Flutter' - s.platform = :ios, '8.0' -end \ No newline at end of file diff --git a/packages/path_provider/path_provider_macos/example/ios/Flutter/AppFrameworkInfo.plist b/packages/path_provider/path_provider_macos/example/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 6c2de8086bcd..000000000000 --- a/packages/path_provider/path_provider_macos/example/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - UIRequiredDeviceCapabilities - - arm64 - - MinimumOSVersion - 8.0 - - diff --git a/packages/path_provider/path_provider_macos/example/ios/Flutter/Debug.xcconfig b/packages/path_provider/path_provider_macos/example/ios/Flutter/Debug.xcconfig deleted file mode 100644 index 9803018ca79d..000000000000 --- a/packages/path_provider/path_provider_macos/example/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Generated.xcconfig" -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" diff --git a/packages/path_provider/path_provider_macos/example/ios/Flutter/Release.xcconfig b/packages/path_provider/path_provider_macos/example/ios/Flutter/Release.xcconfig deleted file mode 100644 index a4a8c604e13d..000000000000 --- a/packages/path_provider/path_provider_macos/example/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Generated.xcconfig" -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/project.pbxproj b/packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index eb0222a7c9c5..000000000000 --- a/packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,490 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 2D9222481EC32A19007564B0 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9222471EC32A19007564B0 /* GeneratedPluginRegistrant.m */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 85DDFCF6BBDEE02B9D9F8138 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C0EE60090AA5F3AAAF2175B6 /* libPods-Runner.a */; }; - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; - 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 2D9222461EC32A19007564B0 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - 2D9222471EC32A19007564B0 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; - 694A199F61914F41AAFD0B7F /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - C0EE60090AA5F3AAAF2175B6 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - D317CA1E83064E01753D8BB5 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, - 85DDFCF6BBDEE02B9D9F8138 /* libPods-Runner.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 840012C8B5EDBCF56B0E4AC1 /* Pods */ = { - isa = PBXGroup; - children = ( - 694A199F61914F41AAFD0B7F /* Pods-Runner.debug.xcconfig */, - D317CA1E83064E01753D8BB5 /* Pods-Runner.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 3B80C3931E831B6300D905FE /* App.framework */, - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEBA1CF902C7004384FC /* Flutter.framework */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - 840012C8B5EDBCF56B0E4AC1 /* Pods */, - CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 2D9222461EC32A19007564B0 /* GeneratedPluginRegistrant.h */, - 2D9222471EC32A19007564B0 /* GeneratedPluginRegistrant.m */, - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 97C146F11CF9000F007C117D /* Supporting Files */, - ); - path = Runner; - sourceTree = ""; - }; - 97C146F11CF9000F007C117D /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 97C146F21CF9000F007C117D /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - CF3B75C9A7D2FA2A4C99F110 /* Frameworks */ = { - isa = PBXGroup; - children = ( - C0EE60090AA5F3AAAF2175B6 /* libPods-Runner.a */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - AB1344B0443C71CD721E1BB7 /* [CP] Check Pods Manifest.lock */, - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 95BB15E9E1769C0D146AA592 /* [CP] Embed Pods Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; - TargetAttributes = { - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; - }; - 95BB15E9E1769C0D146AA592 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; - AB1344B0443C71CD721E1BB7 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, - 97C146F31CF9000F007C117D /* main.m in Sources */, - 2D9222481EC32A19007564B0 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.pathProviderExample; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.pathProviderExample; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 21a3cc14c74e..000000000000 --- a/packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index 3bb3697ef41c..000000000000 --- a/packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/path_provider/path_provider_macos/example/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 21a3cc14c74e..000000000000 --- a/packages/path_provider/path_provider_macos/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/AppDelegate.h b/packages/path_provider/path_provider_macos/example/ios/Runner/AppDelegate.h deleted file mode 100644 index d9e18e990f2e..000000000000 --- a/packages/path_provider/path_provider_macos/example/ios/Runner/AppDelegate.h +++ /dev/null @@ -1,10 +0,0 @@ -// 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. - -#import -#import - -@interface AppDelegate : FlutterAppDelegate - -@end diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/AppDelegate.m b/packages/path_provider/path_provider_macos/example/ios/Runner/AppDelegate.m deleted file mode 100644 index a4b51c88eb60..000000000000 --- a/packages/path_provider/path_provider_macos/example/ios/Runner/AppDelegate.m +++ /dev/null @@ -1,16 +0,0 @@ -// 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. - -#include "AppDelegate.h" -#include "GeneratedPluginRegistrant.h" - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application - didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [GeneratedPluginRegistrant registerWithRegistry:self]; - return [super application:application didFinishLaunchingWithOptions:launchOptions]; -} - -@end diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d22f10b2ab63..000000000000 --- a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 28c6bf03016f6c994b70f38d1b7346e5831b531f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 564 zcmV-40?Yl0P)Px$?ny*JR5%f>l)FnDQ543{x%ZCiu33$Wg!pQFfT_}?5Q|_VSlIbLC`dpoMXL}9 zHfd9&47Mo(7D231gb+kjFxZHS4-m~7WurTH&doVX2KI5sU4v(sJ1@T9eCIKPjsqSr z)C01LsCxk=72-vXmX}CQD#BD;Cthymh&~=f$Q8nn0J<}ZrusBy4PvRNE}+1ceuj8u z0mW5k8fmgeLnTbWHGwfKA3@PdZxhn|PypR&^p?weGftrtCbjF#+zk_5BJh7;0`#Wr zgDpM_;Ax{jO##IrT`Oz;MvfwGfV$zD#c2xckpcXC6oou4ML~ezCc2EtnsQTB4tWNg z?4bkf;hG7IMfhgNI(FV5Gs4|*GyMTIY0$B=_*mso9Ityq$m^S>15>-?0(zQ<8Qy<_TjHE33(?_M8oaM zyc;NxzRVK@DL6RJnX%U^xW0Gpg(lXp(!uK1v0YgHjs^ZXSQ|m#lV7ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index f091b6b0bca859a3f474b03065bef75ba58a9e4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index d0ef06e7edb86cdfe0d15b4b0d98334a86163658..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1716 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 diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index c8f9ed8f5cee1c98386d13b17e89f719e83555b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index 75b2d164a5a98e212cca15ea7bf2ab5de5108680..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3831 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 diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index c4df70d39da7941ef3f6dcb7f06a192d8dcb308d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 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 iW8 - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Base.lproj/Main.storyboard b/packages/path_provider/path_provider_macos/example/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c28516fb38..000000000000 --- a/packages/path_provider/path_provider_macos/example/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Info.plist b/packages/path_provider/path_provider_macos/example/ios/Runner/Info.plist deleted file mode 100644 index 342db6a5dcaf..000000000000 --- a/packages/path_provider/path_provider_macos/example/ios/Runner/Info.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - path_provider_example - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - arm64 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - - diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/main.m b/packages/path_provider/path_provider_macos/example/ios/Runner/main.m deleted file mode 100644 index bec320c0bee0..000000000000 --- a/packages/path_provider/path_provider_macos/example/ios/Runner/main.m +++ /dev/null @@ -1,13 +0,0 @@ -// 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. - -#import -#import -#import "AppDelegate.h" - -int main(int argc, char* argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/packages/path_provider/path_provider_macos/ios/path_provider_macos.podspec b/packages/path_provider/path_provider_macos/ios/path_provider_macos.podspec deleted file mode 100644 index 9f822c58c45c..000000000000 --- a/packages/path_provider/path_provider_macos/ios/path_provider_macos.podspec +++ /dev/null @@ -1,22 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'path_provider_macos' - s.version = '0.0.1' - s.summary = 'No-op implementation of path_provider macOS plugin to avoid build issues on iOS' - s.description = <<-DESC - No-op implementation of path_provider macOS plugin - See https://github.com/flutter/flutter/issues/39659 - DESC - s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_macos' - s.license = { :file => '../LICENSE' } - s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - - s.ios.deployment_target = '8.0' -end - diff --git a/packages/path_provider/path_provider_windows/ios/path_provider_windows.podspec b/packages/path_provider/path_provider_windows/ios/path_provider_windows.podspec deleted file mode 100644 index 941a36c1c794..000000000000 --- a/packages/path_provider/path_provider_windows/ios/path_provider_windows.podspec +++ /dev/null @@ -1,22 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# Run `pod lib lint path_provider_windows.podspec' to validate before publishing. -# -Pod::Spec.new do |s| - s.name = 'path_provider_windows' - s.version = '0.0.1' - s.summary = 'path_provider_windows iOS stub' - s.description = <<-DESC - No-op implementation of the windows path_provider plugin to avoid build issues on iOS - DESC - s.homepage = 'https://github.com/flutter/plugins' - s.license = { :type => 'BSD', :file => '../LICENSE' } - s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } - s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_windows' } - s.dependency 'Flutter' - s.platform = :ios, '8.0' - - # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } - s.swift_version = '5.0' -end diff --git a/packages/shared_preferences/shared_preferences_linux/ios/shared_preferences_linux.podspec b/packages/shared_preferences/shared_preferences_linux/ios/shared_preferences_linux.podspec deleted file mode 100644 index 8f4d3cdddcd5..000000000000 --- a/packages/shared_preferences/shared_preferences_linux/ios/shared_preferences_linux.podspec +++ /dev/null @@ -1,22 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. -# Run `pod lib lint shared_preferences_launcher_linux.podspec' to validate before publishing. -# -Pod::Spec.new do |s| - s.name = 'shared_preferences_linux' - s.version = '0.0.1' - s.summary = 'shared_preferences_linux iOS stub' - s.description = <<-DESC - No-op implementation of the Linux shared_preferences plugin to avoid build issues on iOS - DESC - s.homepage = 'https://github.com/flutter/plugins' - s.license = { :type => 'BSD', :file => '../LICENSE' } - s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } - s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_linux' } - s.dependency 'Flutter' - s.platform = :ios, '8.0' - - # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } - s.swift_version = '5.0' -end diff --git a/packages/shared_preferences/shared_preferences_macos/ios/shared_preferences_macos.podspec b/packages/shared_preferences/shared_preferences_macos/ios/shared_preferences_macos.podspec deleted file mode 100644 index 8e2a2bd30dac..000000000000 --- a/packages/shared_preferences/shared_preferences_macos/ios/shared_preferences_macos.podspec +++ /dev/null @@ -1,21 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'shared_preferences_macos' - s.version = '0.0.1' - s.summary = 'No-op implementation of shared_preferences desktop plugin to avoid build issues on iOS' - s.description = <<-DESC - No-op implementation of shared_preferences to avoid build issues on iOS. - DESC - - s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_macos' - s.license = { :file => '../LICENSE' } - s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - - s.ios.deployment_target = '8.0' -end diff --git a/packages/shared_preferences/shared_preferences_web/ios/shared_preferences_web.podspec b/packages/shared_preferences/shared_preferences_web/ios/shared_preferences_web.podspec deleted file mode 100644 index 11f8b73e02d8..000000000000 --- a/packages/shared_preferences/shared_preferences_web/ios/shared_preferences_web.podspec +++ /dev/null @@ -1,20 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'shared_preferences_web' - s.version = '0.0.1' - s.summary = 'No-op implementation of shared_preferences web plugin to avoid build issues on iOS' - s.description = <<-DESC -temp fake shared_preferences_web plugin - DESC - s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_web' - s.license = { :file => '../LICENSE' } - s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - - s.ios.deployment_target = '8.0' -end diff --git a/packages/shared_preferences/shared_preferences_windows/ios/shared_preferences_windows.podspec b/packages/shared_preferences/shared_preferences_windows/ios/shared_preferences_windows.podspec deleted file mode 100644 index 2e239e607493..000000000000 --- a/packages/shared_preferences/shared_preferences_windows/ios/shared_preferences_windows.podspec +++ /dev/null @@ -1,22 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# Run `pod lib lint shared_preferences_windows.podspec' to validate before publishing. -# -Pod::Spec.new do |s| - s.name = 'shared_preferences_windows' - s.version = '0.0.1' - s.summary = 'shared_preferences_windows iOS stub' - s.description = <<-DESC - No-op implementation of the windows shared_preferences plugin to avoid build issues on iOS - DESC - s.homepage = 'https://github.com/flutter/plugins' - s.license = { :type => 'BSD', :file => '../LICENSE' } - s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } - s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_windows' } - s.dependency 'Flutter' - s.platform = :ios, '8.0' - - # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } - s.swift_version = '5.0' -end diff --git a/packages/url_launcher/url_launcher_linux/ios/.gitignore b/packages/url_launcher/url_launcher_linux/ios/.gitignore deleted file mode 100644 index aa479fd3ce8a..000000000000 --- a/packages/url_launcher/url_launcher_linux/ios/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -.idea/ -.vagrant/ -.sconsign.dblite -.svn/ - -.DS_Store -*.swp -profile - -DerivedData/ -build/ -GeneratedPluginRegistrant.h -GeneratedPluginRegistrant.m - -.generated/ - -*.pbxuser -*.mode1v3 -*.mode2v3 -*.perspectivev3 - -!default.pbxuser -!default.mode1v3 -!default.mode2v3 -!default.perspectivev3 - -xcuserdata - -*.moved-aside - -*.pyc -*sync/ -Icon? -.tags* - -/Flutter/Generated.xcconfig -/Flutter/flutter_export_environment.sh \ No newline at end of file diff --git a/packages/url_launcher/url_launcher_linux/ios/url_launcher_linux.podspec b/packages/url_launcher/url_launcher_linux/ios/url_launcher_linux.podspec deleted file mode 100644 index 1359fd403d8d..000000000000 --- a/packages/url_launcher/url_launcher_linux/ios/url_launcher_linux.podspec +++ /dev/null @@ -1,22 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. -# Run `pod lib lint url_launcher_linux.podspec' to validate before publishing. -# -Pod::Spec.new do |s| - s.name = 'url_launcher_linux' - s.version = '0.0.1' - s.summary = 'url_launcher_linux iOS stub' - s.description = <<-DESC - No-op implementation of the Linux url_launcher plugin to avoid build issues on iOS - DESC - s.homepage = 'https://github.com/flutter/plugins' - s.license = { :type => 'BSD', :file => '../LICENSE' } - s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } - s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_linux' } - s.dependency 'Flutter' - s.platform = :ios, '8.0' - - # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } - s.swift_version = '5.0' -end diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Flutter/AppFrameworkInfo.plist b/packages/url_launcher/url_launcher_macos/example/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 6c2de8086bcd..000000000000 --- a/packages/url_launcher/url_launcher_macos/example/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - UIRequiredDeviceCapabilities - - arm64 - - MinimumOSVersion - 8.0 - - diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Flutter/Debug.xcconfig b/packages/url_launcher/url_launcher_macos/example/ios/Flutter/Debug.xcconfig deleted file mode 100644 index 9803018ca79d..000000000000 --- a/packages/url_launcher/url_launcher_macos/example/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Generated.xcconfig" -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Flutter/Release.xcconfig b/packages/url_launcher/url_launcher_macos/example/ios/Flutter/Release.xcconfig deleted file mode 100644 index a4a8c604e13d..000000000000 --- a/packages/url_launcher/url_launcher_macos/example/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Generated.xcconfig" -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Runner.xcodeproj/project.pbxproj b/packages/url_launcher/url_launcher_macos/example/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index db72809a6169..000000000000 --- a/packages/url_launcher/url_launcher_macos/example/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,490 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 2D92223F1EC1DA93007564B0 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D92223E1EC1DA93007564B0 /* GeneratedPluginRegistrant.m */; }; - 2E37D9A274B2EACB147AC51B /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 856D0913184F79C678A42603 /* libPods-Runner.a */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; - 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 2D92223D1EC1DA93007564B0 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GeneratedPluginRegistrant.h; path = Runner/GeneratedPluginRegistrant.h; sourceTree = ""; }; - 2D92223E1EC1DA93007564B0 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GeneratedPluginRegistrant.m; path = Runner/GeneratedPluginRegistrant.m; sourceTree = ""; }; - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 836316F9AEA584411312E29F /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 856D0913184F79C678A42603 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - A84BFEE343F54B983D1B67EB /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, - 2E37D9A274B2EACB147AC51B /* libPods-Runner.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 840012C8B5EDBCF56B0E4AC1 /* Pods */ = { - isa = PBXGroup; - children = ( - 836316F9AEA584411312E29F /* Pods-Runner.debug.xcconfig */, - A84BFEE343F54B983D1B67EB /* Pods-Runner.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 3B80C3931E831B6300D905FE /* App.framework */, - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEBA1CF902C7004384FC /* Flutter.framework */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 2D92223D1EC1DA93007564B0 /* GeneratedPluginRegistrant.h */, - 2D92223E1EC1DA93007564B0 /* GeneratedPluginRegistrant.m */, - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - 840012C8B5EDBCF56B0E4AC1 /* Pods */, - CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 97C146F11CF9000F007C117D /* Supporting Files */, - ); - path = Runner; - sourceTree = ""; - }; - 97C146F11CF9000F007C117D /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 97C146F21CF9000F007C117D /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - CF3B75C9A7D2FA2A4C99F110 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 856D0913184F79C678A42603 /* libPods-Runner.a */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - AB1344B0443C71CD721E1BB7 /* [CP] Check Pods Manifest.lock */, - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 95BB15E9E1769C0D146AA592 /* [CP] Embed Pods Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; - TargetAttributes = { - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; - }; - 95BB15E9E1769C0D146AA592 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; - AB1344B0443C71CD721E1BB7 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, - 97C146F31CF9000F007C117D /* main.m in Sources */, - 2D92223F1EC1DA93007564B0 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.urlLauncher; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.urlLauncher; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/url_launcher/url_launcher_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index 3bb3697ef41c..000000000000 --- a/packages/url_launcher/url_launcher_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Runner/AppDelegate.h b/packages/url_launcher/url_launcher_macos/example/ios/Runner/AppDelegate.h deleted file mode 100644 index d9e18e990f2e..000000000000 --- a/packages/url_launcher/url_launcher_macos/example/ios/Runner/AppDelegate.h +++ /dev/null @@ -1,10 +0,0 @@ -// 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. - -#import -#import - -@interface AppDelegate : FlutterAppDelegate - -@end diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Runner/AppDelegate.m b/packages/url_launcher/url_launcher_macos/example/ios/Runner/AppDelegate.m deleted file mode 100644 index 9cf1c7796c6a..000000000000 --- a/packages/url_launcher/url_launcher_macos/example/ios/Runner/AppDelegate.m +++ /dev/null @@ -1,17 +0,0 @@ -// 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. - -#include "AppDelegate.h" -#include "GeneratedPluginRegistrant.h" - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application - didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [GeneratedPluginRegistrant registerWithRegistry:self]; - [super application:application didFinishLaunchingWithOptions:launchOptions]; - return YES; -} - -@end diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d22f10b2ab63..000000000000 --- a/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 28c6bf03016f6c994b70f38d1b7346e5831b531f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 564 zcmV-40?Yl0P)Px$?ny*JR5%f>l)FnDQ543{x%ZCiu33$Wg!pQFfT_}?5Q|_VSlIbLC`dpoMXL}9 zHfd9&47Mo(7D231gb+kjFxZHS4-m~7WurTH&doVX2KI5sU4v(sJ1@T9eCIKPjsqSr z)C01LsCxk=72-vXmX}CQD#BD;Cthymh&~=f$Q8nn0J<}ZrusBy4PvRNE}+1ceuj8u z0mW5k8fmgeLnTbWHGwfKA3@PdZxhn|PypR&^p?weGftrtCbjF#+zk_5BJh7;0`#Wr zgDpM_;Ax{jO##IrT`Oz;MvfwGfV$zD#c2xckpcXC6oou4ML~ezCc2EtnsQTB4tWNg z?4bkf;hG7IMfhgNI(FV5Gs4|*GyMTIY0$B=_*mso9Ityq$m^S>15>-?0(zQ<8Qy<_TjHE33(?_M8oaM zyc;NxzRVK@DL6RJnX%U^xW0Gpg(lXp(!uK1v0YgHjs^ZXSQ|m#lV7ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index f091b6b0bca859a3f474b03065bef75ba58a9e4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index d0ef06e7edb86cdfe0d15b4b0d98334a86163658..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1716 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 diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index c8f9ed8f5cee1c98386d13b17e89f719e83555b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index 75b2d164a5a98e212cca15ea7bf2ab5de5108680..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3831 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 diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/url_launcher/url_launcher_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index c4df70d39da7941ef3f6dcb7f06a192d8dcb308d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 zcmV-m2cP(fP)x~L`~4d)Rspd&<9kFh{hn*KP1LP0~$;u(LfAu zp%fx&qLBcRHx$G|3q(bv@+b;o0*D|jwD-Q9uQR(l*ST}s+uPgQ-MeFwZ#GS?b332? z&Tk$&_miXn3IGq)AmQ)3sisq{raD4(k*bHvpCe-TdWq^NRTEVM)i9xbgQ&ccnUVx* zEY%vS%gDcSg=!tuIK8$Th2_((_h^+7;R|G{n06&O2#6%LK`a}n?h_fL18btz<@lFG za}xS}u?#DBMB> zw^b($1Z)`9G?eP95EKi&$eOy@K%h;ryrR3la%;>|o*>CgB(s>dDcNOXg}CK9SPmD? zmr-s{0wRmxUnbDrYfRvnZ@d z6johZ2sMX{YkGSKWd}m|@V7`Degt-43=2M?+jR%8{(H$&MLLmS;-|JxnX2pnz;el1jsvqQz}pGSF<`mqEXRQ5sC4#BbwnB_4` zc5bFE-Gb#JV3tox9fp-vVEN{(tOCpRse`S+@)?%pz+zVJXSooTrNCUg`R6`hxwb{) zC@{O6MKY8tfZ5@!yy=p5Y|#+myRL=^{tc(6YgAnkg3I(Cd!r5l;|;l-MQ8B`;*SCE z{u)uP^C$lOPM z5d~UhKhRRmvv{LIa^|oavk1$QiEApSrP@~Jjbg`<*dW4TO?4qG%a%sTPUFz(QtW5( zM)lA+5)0TvH~aBaOAs|}?u2FO;yc-CZ1gNM1dAxJ?%m?YsGR`}-xk2*dxC}r5j$d* zE!#Vtbo69h>V4V`BL%_&$} z+oJAo@jQ^Tk`;%xw-4G>hhb&)B?##U+(6Fi7nno`C<|#PVA%$Y{}N-?(Gc$1%tr4Pc}}hm~yY#fTOe!@v9s-ik$dX~|ygArPhByaXn8 zpI^FUjNWMsTFKTP3X7m?UK)3m zp6rI^_zxRYrx6_QmhoWoDR`fp4R7gu6;gdO)!KexaoO2D88F9x#TM1(9Bn7g;|?|o z)~$n&Lh#hCP6_LOPD>a)NmhW})LADx2kq=X7}7wYRj-0?dXr&bHaRWCfSqvzFa=sn z-8^gSyn-RmH=BZ{AJZ~!8n5621GbUJV7Qvs%JNv&$%Q17s_X%s-41vAPfIR>;x0Wlqr5?09S>x#%Qkt>?(&XjFRY}*L6BeQ3 z<6XEBh^S7>AbwGm@XP{RkeEKj6@_o%oV?hDuUpUJ+r#JZO?!IUc;r0R?>mi)*ZpQ) z#((dn=A#i_&EQn|hd)N$#A*fjBFuiHcYvo?@y1 z5|fV=a^a~d!c-%ZbMNqkMKiSzM{Yq=7_c&1H!mXk60Uv32dV;vMg&-kQ)Q{+PFtwc zj|-uQ;b^gts??J*9VxxOro}W~Q9j4Em|zSRv)(WSO9$F$s=Ydu%Q+5DOid~lwk&we zY%W(Z@ofdwPHncEZzZgmqS|!gTj3wQq9rxQy+^eNYKr1mj&?tm@wkO*9@UtnRMG>c aR{jt9+;fr}hV%pg00001^@s67{VYS000c7NklQEG_j zup^)eW&WUIApqy$=APz8jE@awGp)!bsTjDbrJO`$x^ZR^dr;>)LW>{ zs70vpsD38v)19rI=GNk1b(0?Js9~rjsQsu*K;@SD40RB-3^gKU-MYC7G!Bw{fZsqp zih4iIi;Hr_xZ033Iu{sQxLS=}yBXgLMn40d++>aQ0#%8D1EbGZp7+ z5=mK?t31BkVYbGOxE9`i748x`YgCMwL$qMsChbSGSE1`p{nSmadR zcQ#R)(?!~dmtD0+D2!K zR9%!Xp1oOJzm(vbLvT^$IKp@+W2=-}qTzTgVtQ!#Y7Gxz}stUIm<1;oBQ^Sh2X{F4ibaOOx;5ZGSNK z0maF^@(UtV$=p6DXLgRURwF95C=|U8?osGhgOED*b z7woJ_PWXBD>V-NjQAm{~T%sjyJ{5tn2f{G%?J!KRSrrGvQ1(^`YLA5B!~eycY(e5_ z*%aa{at13SxC(=7JT7$IQF~R3sy`Nn%EMv!$-8ZEAryB*yB1k&stni)=)8-ODo41g zkJu~roIgAih94tb=YsL%iH5@^b~kU9M-=aqgXIrbtxMpFy5mekFm#edF9z7RQ6V}R zBIhbXs~pMzt0VWy1Fi$^fh+1xxLDoK09&5&MJl(q#THjPm(0=z2H2Yfm^a&E)V+a5 zbi>08u;bJsDRUKR9(INSc7XyuWv(JsD+BB*0hS)FO&l&7MdViuur@-<-EHw>kHRGY zqoT}3fDv2-m{NhBG8X}+rgOEZ;amh*DqN?jEfQdqxdj08`Sr=C-KmT)qU1 z+9Cl)a1mgXxhQiHVB}l`m;-RpmKy?0*|yl?FXvJkFxuu!fKlcmz$kN(a}i*saM3nr z0!;a~_%Xqy24IxA2rz<+08=B-Q|2PT)O4;EaxP^6qixOv7-cRh?*T?zZU`{nIM-at zTKYWr9rJ=tppQ9I#Z#mLgINVB!pO-^FOcvFw6NhV0gztuO?g ztoA*C-52Q-Z-P#xB4HAY3KQVd%dz1S4PA3vHp0aa=zAO?FCt zC_GaTyVBg2F!bBr3U@Zy2iJgIAt>1sf$JWA9kh{;L+P*HfUBX1Zy{4MgNbDfBV_ly z!y#+753arsZUt@366jIC0klaC@ckuk!qu=pAyf7&QmiBUT^L1&tOHzsK)4n|pmrVT zs2($4=?s~VejTFHbFdDOwG;_58LkIj1Fh@{glkO#F1>a==ymJS$z;gdedT1zPx4Kj ztjS`y_C}%af-RtpehdQDt3a<=W5C4$)9W@QAse;WUry$WYmr51ml9lkeunUrE`-3e zmq1SgSOPNEE-Mf+AGJ$g0M;3@w!$Ej;hMh=v=I+Lpz^n%Pg^MgwyqOkNyu2c^of)C z1~ALor3}}+RiF*K4+4{(1%1j3pif1>sv0r^mTZ?5Jd-It!tfPfiG_p$AY*Vfak%FG z4z#;wLtw&E&?}w+eKG^=#jF7HQzr8rV0mY<1YAJ_uGz~$E13p?F^fPSzXSn$8UcI$ z8er9{5w5iv0qf8%70zV71T1IBB1N}R5Kp%NO0=5wJalZt8;xYp;b{1K) zHY>2wW-`Sl{=NpR%iu3(u6l&)rc%%cSA#aV7WCowfbFR4wcc{LQZv~o1u_`}EJA3>ki`?9CKYTA!rhO)if*zRdd}Kn zEPfYbhoVE~!FI_2YbC5qAj1kq;xP6%J8+?2PAs?`V3}nyFVD#sV3+uP`pi}{$l9U^ zSz}_M9f7RgnnRhaoIJgT8us!1aB&4!*vYF07Hp&}L zCRlop0oK4DL@ISz{2_BPlezc;xj2|I z23RlDNpi9LgTG_#(w%cMaS)%N`e>~1&a3<{Xy}>?WbF>OOLuO+j&hc^YohQ$4F&ze z+hwnro1puQjnKm;vFG~o>`kCeUIlkA-2tI?WBKCFLMBY=J{hpSsQ=PDtU$=duS_hq zHpymHt^uuV1q@uc4bFb{MdG*|VoW@15Osrqt2@8ll0qO=j*uOXn{M0UJX#SUztui9FN4)K3{9!y8PC-AHHvpVTU;x|-7P+taAtyglk#rjlH2 z5Gq8ik}BPaGiM{#Woyg;*&N9R2{J0V+WGB69cEtH7F?U~Kbi6ksi*`CFXsi931q7Y zGO82?whBhN%w1iDetv%~wM*Y;E^)@Vl?VDj-f*RX>{;o_=$fU!&KAXbuadYZ46Zbg z&6jMF=49$uL^73y;;N5jaHYv)BTyfh&`qVLYn?`o6BCA_z-0niZz=qPG!vonK3MW_ zo$V96zM!+kJRs{P-5-rQVse0VBH*n6A58)4uc&gfHMa{gIhV2fGf{st>E8sKyP-$8zp~wJX^A*@DI&-;8>gANXZj zU)R+Y)PB?=)a|Kj>8NXEu^S_h^7R`~Q&7*Kn!xyvzVv&^>?^iu;S~R2e-2fJx-oUb cX)(b1KSk$MOV07*qoM6N<$f&6$jw%VRuvdN2+38CZWny1cRtlsl+0_KtW)EU14Ei(F!UtWuj4IK+3{sK@>rh zs1Z;=(DD&U6+tlyL?UnHVN^&g6QhFi2#HS+*qz;(>63G(`|jRtW|nz$Pv7qTovP!^ zP_jES{mr@O-02w%!^a?^1ZP!_KmQiz0L~jZ=W@Qt`8wzOoclQsAS<5YdH;a(4bGLE zk8s}1If(PSIgVi!XE!5kA?~z*sobvNyohr;=Q_@h2@$6Flyej3J)D-6YfheRGl`HEcPk|~huT_2-U?PfL=4BPV)f1o!%rQ!NMt_MYw-5bUSwQ9Z&zC>u zOrl~UJglJNa%f50Ok}?WB{on`Ci`p^Y!xBA?m@rcJXLxtrE0FhRF3d*ir>yzO|BD$ z3V}HpFcCh6bTzY}Nt_(W%QYd3NG)jJ4<`F<1Od) zfQblTdC&h2lCz`>y?>|9o2CdvC8qZeIZt%jN;B7Hdn2l*k4M4MFEtq`q_#5?}c$b$pf_3y{Y!cRDafZBEj-*OD|gz#PBDeu3QoueOesLzB+O zxjf2wvf6Wwz>@AiOo2mO4=TkAV+g~%_n&R;)l#!cBxjuoD$aS-`IIJv7cdX%2{WT7 zOm%5rs(wqyPE^k5SIpUZ!&Lq4<~%{*>_Hu$2|~Xa;iX*tz8~G6O3uFOS?+)tWtdi| zV2b#;zRN!m@H&jd=!$7YY6_}|=!IU@=SjvGDFtL;aCtw06U;-v^0%k0FOyESt z1Wv$={b_H&8FiRV?MrzoHWd>%v6KTRU;-v^Miiz+@q`(BoT!+<37CKhoKb)|8!+RG z6BQFU^@fRW;s8!mOf2QViKQGk0TVER6EG1`#;Nm39Do^PoT!+<37AD!%oJe86(=et zZ~|sLzU>V-qYiU6V8$0GmU7_K8|Fd0B?+9Un1BhKAz#V~Fk^`mJtlCX#{^8^M8!me z8Yg;8-~>!e<-iG;h*0B1kBKm}hItVGY6WnjVpgnTTAC$rqQ^v)4KvOtpY|sIj@WYg zyw##ZZ5AC2IKNC;^hwg9BPk0wLStlmBr;E|$5GoAo$&Ui_;S9WY62n3)i49|T%C#i017z3J=$RF|KyZWnci*@lW4 z=AKhNN6+m`Q!V3Ye68|8y@%=am>YD0nG99M)NWc20%)gwO!96j7muR}Fr&54SxKP2 zP30S~lt=a*qDlbu3+Av57=9v&vr<6g0&`!8E2fq>I|EJGKs}t|{h7+KT@)LfIV-3K zK)r_fr2?}FFyn*MYoLC>oV-J~eavL2ho4a4^r{E-8m2hi>~hA?_vIG4a*KT;2eyl1 zh_hUvUJpNCFwBvRq5BI*srSle>c6%n`#VNsyC|MGa{(P&08p=C9+WUw9Hl<1o9T4M zdD=_C0F7#o8A_bRR?sFNmU0R6tW`ElnF8p53IdHo#S9(JoZCz}fHwJ6F<&?qrpVqE zte|m%89JQD+XwaPU#%#lVs-@-OL);|MdfINd6!XwP2h(eyafTUsoRkA%&@fe?9m@jw-v(yTTiV2(*fthQH9}SqmsRPVnwwbV$1E(_lkmo&S zF-truCU914_$jpqjr(>Ha4HkM4YMT>m~NosUu&UZ>zirfHo%N6PPs9^_o$WqPA0#5 z%tG>qFCL+b*0s?sZ;Sht0nE7Kl>OVXy=gjWxxK;OJ3yGd7-pZf7JYNcZo2*1SF`u6 zHJyRRxGw9mDlOiXqVMsNe#WX`fC`vrtjSQ%KmLcl(lC>ZOQzG^%iql2w-f_K@r?OE zwCICifM#L-HJyc7Gm>Ern?+Sk3&|Khmu4(~3qa$(m6Ub^U0E5RHq49za|XklN#?kP zl;EstdW?(_4D>kwjWy2f!LM)y?F94kyU3`W!6+AyId-89v}sXJpuic^NLL7GJItl~ zsiuB98AI-(#Mnm|=A-R6&2fwJ0JVSY#Q>&3$zFh|@;#%0qeF=j5Ajq@4i0tIIW z&}sk$&fGwoJpe&u-JeGLi^r?dO`m=y(QO{@h zQqAC7$rvz&5+mo3IqE?h=a~6m>%r5Quapvzq;{y~p zJpyXOBgD9VrW7@#p6l7O?o3feml(DtSL>D^R) zZUY%T2b0-vBAFN7VB;M88!~HuOXi4KcI6aRQ&h|XQ0A?m%j2=l1f0cGP}h(oVfJ`N zz#PpmFC*ieab)zJK<4?^k=g%OjPnkANzbAbmGZHoVRk*mTfm75s_cWVa`l*f$B@xu z5E*?&@seIo#*Y~1rBm!7sF9~~u6Wrj5oICUOuz}CS)jdNIznfzCA(stJ(7$c^e5wN z?lt>eYgbA!kvAR7zYSD&*r1$b|(@;9dcZ^67R0 zXAXJKa|5Sdmj!g578Nwt6d$sXuc&MWezA0Whd`94$h{{?1IwXP4)Tx4obDK%xoFZ_Z zjjHJ_P@R_e5blG@yEjnaJb`l;s%Lb2&=8$&Ct-fV`E^4CUs)=jTk!I}2d&n!f@)bm z@ z_4Dc86+3l2*p|~;o-Sb~oXb_RuLmoifDU^&Te$*FevycC0*nE3Xws8gsWp|Rj2>SM zns)qcYj?^2sd8?N!_w~4v+f-HCF|a$TNZDoNl$I1Uq87euoNgKb6&r26TNrfkUa@o zfdiFA@p{K&mH3b8i!lcoz)V{n8Q@g(vR4ns4r6w;K z>1~ecQR0-<^J|Ndg5fvVUM9g;lbu-){#ghGw(fg>L zh)T5Ljb%lWE;V9L!;Cqk>AV1(rULYF07ZBJbGb9qbSoLAd;in9{)95YqX$J43-dY7YU*k~vrM25 zxh5_IqO0LYZW%oxQ5HOzmk4x{atE*vipUk}sh88$b2tn?!ujEHn`tQLe&vo}nMb&{ zio`xzZ&GG6&ZyN3jnaQy#iVqXE9VT(3tWY$n-)uWDQ|tc{`?fq2F`oQ{;d3aWPg4Hp-(iE{ry>MIPWL> iW8 - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Runner/Base.lproj/Main.storyboard b/packages/url_launcher/url_launcher_macos/example/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c28516fb38..000000000000 --- a/packages/url_launcher/url_launcher_macos/example/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Runner/Info.plist b/packages/url_launcher/url_launcher_macos/example/ios/Runner/Info.plist deleted file mode 100644 index 80aec052fa79..000000000000 --- a/packages/url_launcher/url_launcher_macos/example/ios/Runner/Info.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - url_launcher_example - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - arm64 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - - diff --git a/packages/url_launcher/url_launcher_macos/example/ios/Runner/main.m b/packages/url_launcher/url_launcher_macos/example/ios/Runner/main.m deleted file mode 100644 index bec320c0bee0..000000000000 --- a/packages/url_launcher/url_launcher_macos/example/ios/Runner/main.m +++ /dev/null @@ -1,13 +0,0 @@ -// 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. - -#import -#import -#import "AppDelegate.h" - -int main(int argc, char* argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/packages/url_launcher/url_launcher_macos/ios/url_launcher_macos.podspec b/packages/url_launcher/url_launcher_macos/ios/url_launcher_macos.podspec deleted file mode 100644 index 2bfe79708555..000000000000 --- a/packages/url_launcher/url_launcher_macos/ios/url_launcher_macos.podspec +++ /dev/null @@ -1,21 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'url_launcher_macos' - s.version = '0.0.1' - s.summary = 'No-op implementation of the macos url_launcher plugin to avoid build issues on iOS' - s.description = <<-DESC - No-op implementation of the macos url_launcher plugin to avoid build issues on iOS - DESC - s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_macos' - s.license = { :file => '../LICENSE' } - s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - - s.ios.deployment_target = '8.0' -end - diff --git a/packages/url_launcher/url_launcher_web/ios/url_launcher_web.podspec b/packages/url_launcher/url_launcher_web/ios/url_launcher_web.podspec deleted file mode 100644 index 161156ef020d..000000000000 --- a/packages/url_launcher/url_launcher_web/ios/url_launcher_web.podspec +++ /dev/null @@ -1,20 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'url_launcher_web' - s.version = '0.0.1' - s.summary = 'No-op implementation of url_launcher_web web plugin to avoid build issues on iOS' - s.description = <<-DESC -temp fake url_launcher_web plugin - DESC - s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_web' - s.license = { :file => '../LICENSE' } - s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - - s.ios.deployment_target = '8.0' -end diff --git a/packages/url_launcher/url_launcher_windows/ios/url_launcher_windows.podspec b/packages/url_launcher/url_launcher_windows/ios/url_launcher_windows.podspec deleted file mode 100644 index 1c700d49f4b5..000000000000 --- a/packages/url_launcher/url_launcher_windows/ios/url_launcher_windows.podspec +++ /dev/null @@ -1,22 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# Run `pod lib lint url_launcher_windows.podspec' to validate before publishing. -# -Pod::Spec.new do |s| - s.name = 'url_launcher_windows' - s.version = '0.0.1' - s.summary = 'url_launcher_windows iOS stub' - s.description = <<-DESC - No-op implementation of the windows url_launcher plugin to avoid build issues on iOS - DESC - s.homepage = 'https://github.com/flutter/plugins' - s.license = { :type => 'BSD', :file => '../LICENSE' } - s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } - s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_windows' } - s.dependency 'Flutter' - s.platform = :ios, '8.0' - - # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } - s.swift_version = '5.0' -end diff --git a/packages/video_player/video_player_web/ios/video_player_web.podspec b/packages/video_player/video_player_web/ios/video_player_web.podspec deleted file mode 100644 index 5129b7c69032..000000000000 --- a/packages/video_player/video_player_web/ios/video_player_web.podspec +++ /dev/null @@ -1,20 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'video_player_web' - s.version = '0.0.1' - s.summary = 'No-op implementation of video_player_web web plugin to avoid build issues on iOS' - s.description = <<-DESC -temp fake video_player_web plugin - DESC - s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/video_player/video_player_web' - s.license = { :file => '../LICENSE' } - s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - - s.ios.deployment_target = '8.0' -end \ No newline at end of file diff --git a/script/tool/lib/src/drive_examples_command.dart b/script/tool/lib/src/drive_examples_command.dart index 59c642265bae..0bd531a20f8a 100644 --- a/script/tool/lib/src/drive_examples_command.dart +++ b/script/tool/lib/src/drive_examples_command.dart @@ -200,11 +200,10 @@ Tried searching for the following: if (isAndroid) { return (isAndroidPlugin(plugin, fileSystem)); } - // When we are here, no flags are specified. Only return true if the plugin supports mobile for legacy command support. - // TODO(cyanglaz): Make mobile platforms flags also required like other platforms (breaking change). + // When we are here, no flags are specified. Only return true if the plugin + // supports Android for legacy command support. TODO(cyanglaz): Make Android + // flag also required like other platforms (breaking change). // https://github.com/flutter/flutter/issues/58285 - final bool isMobilePlugin = - isIosPlugin(plugin, fileSystem) || isAndroidPlugin(plugin, fileSystem); - return isMobilePlugin; + return isAndroidPlugin(plugin, fileSystem); } } From 6d8ea78c5da1217c60ab9fe6021a896ec90d6a7a Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Tue, 16 Feb 2021 17:13:52 -0800 Subject: [PATCH 0142/1565] [url_launcher] Re-endorse web implementation. (#3557) This change re-endorses url_launcher_web, now that it's been migrated to null-safety. --- packages/url_launcher/url_launcher/CHANGELOG.md | 4 ++++ packages/url_launcher/url_launcher/pubspec.yaml | 10 ++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index 9f2719fd6662..f467ec4d1830 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.0.0-nullsafety.7 + +* Re-endorse `url_launcher_web` in the `nullsafety` prerelease. + ## 6.0.0-nullsafety.6 * Correct statement in description about which platforms url_launcher supports. diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index 2fdfd8caf217..d058e2fa1409 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -2,7 +2,7 @@ name: url_launcher description: Flutter plugin for launching a URL. Supports web, phone, SMS, and email schemes. homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher -version: 6.0.0-nullsafety.6 +version: 6.0.0-nullsafety.7 flutter: plugin: @@ -12,9 +12,8 @@ flutter: pluginClass: UrlLauncherPlugin ios: pluginClass: FLTURLLauncherPlugin - # TODO(mvanbeusekom): Temporary disabled until web is migrated to nnbd (advised by @blasten). - #web: - # default_package: url_launcher_web + web: + default_package: url_launcher_web linux: default_package: url_laucher_linux macos: @@ -34,8 +33,7 @@ dependencies: url_launcher_linux: ^0.1.0-nullsafety url_launcher_macos: ^0.1.0-nullsafety url_launcher_windows: ^0.1.0-nullsafety - # TODO(mvanbeusekom): Temporary disabled until web is migrated to nnbd (advised by @blasten). - #url_launcher_web: ^0.1.3 + url_launcher_web: ^2.0.0-nullsafety dev_dependencies: flutter_test: From cbee8561c07495d542ccca6dc8572bd0b4c92cd9 Mon Sep 17 00:00:00 2001 From: Ian Hickson Date: Tue, 16 Feb 2021 20:46:04 -0800 Subject: [PATCH 0143/1565] Document how to use pigeon and update to the latest version. (#3281) --- .../video_player/video_player/CHANGELOG.md | 4 + .../video_player/video_player/CONTRIBUTING.md | 82 +++++++++++++++++++ .../flutter/plugins/videoplayer/Messages.java | 2 +- .../video_player/ios/Classes/messages.h | 2 +- .../video_player/ios/Classes/messages.m | 2 +- .../video_player/pigeons/messages.dart | 1 + .../video_player/video_player/pubspec.yaml | 15 ++-- .../video_player/test/video_player_test.dart | 1 + script/incremental_build.sh | 2 +- 9 files changed, 100 insertions(+), 11 deletions(-) create mode 100644 packages/video_player/video_player/CONTRIBUTING.md diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index 2e8f7396c618..0cabfc48226d 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.10 + +* Updated to video_player_platform_interface 4.0. + ## 2.0.0-nullsafety.9 * Fixed an issue where a crash can occur after a closing a video player view on iOS. diff --git a/packages/video_player/video_player/CONTRIBUTING.md b/packages/video_player/video_player/CONTRIBUTING.md new file mode 100644 index 000000000000..32c9d1b791d1 --- /dev/null +++ b/packages/video_player/video_player/CONTRIBUTING.md @@ -0,0 +1,82 @@ +## Updating pigeon-generated files + +If you update files in the pigeons/ directory, run the following +command in this directory (ignore the errors you get about +dependencies in the examples directory): + +```bash +flutter pub upgrade +flutter pub run pigeon --dart_null_safety --input pigeons/messages.dart +# git commit your changes so that your working environment is clean +(cd ../../../; ./script/incremental_build.sh format --travis --clang-format=clang-format-7) +``` + +If you update pigeon itself and want to test the changes here, +temporarily update the pubspec.yaml by adding the following to the +`dependency_overrides` section, assuming you have checked out the +`flutter/packages` repo in a sibling directory to the `plugins` repo: + +```yaml + pigeon: + path: + ../../../../packages/packages/pigeon/ +``` + +Then, run the commands above. When you run `pub get` it should warn +you that you're using an override. If you do this, you will need to +publish pigeon before you can land the updates to this package, since +the CI tests run the analysis using latest published version of +pigeon, not your version or the version on master. + +In either case, the configuration will be obtained automatically from +the `pigeons/messages.dart` file (see `configurePigeon` at the bottom +of that file). + +While contributing, you may also want to set the following dependency +overrides: + +```yaml +dependency_overrides: + video_player_platform_interface: + path: + ../video_player_platform_interface + video_player_web: + path: + ../video_player_web +``` + +## Publishing plugin updates that span multiple plugin packages + +If your change affects both the interface package and the +implementation packages, then you will need to publish a version of +the plugin in between landing the interface changes and the +implementation changes, since the implementations depend on the +interface via pub. + +To do this, follow these steps: + +1. Create a PR that has all the changes, and update the +`pubspec.yaml`s to have path-based dependency overrides as described +in the "Updating pigeon-generated files" section above. + +2. Upload that PR and get it reviewed and into a state where the only +test failure is the one complaining that you can't publish a package +that has dependency overrides. + +3. Create a PR that's a subset of the one in the previous step that +only includes the interface changes, with no dependency overrides, and +submit that. + +4. Once you have had that reviewed and landed, publish the interface +parts of the plugin to pub. + +5. Now, update the original full PR to not use dependency overrides +but to instead refer to the new version of the plugin, and sync it to +master (so that the interface changes are gone from the PR). Submit +that PR. + +6. Once you have had _that_ PR reviewed and landed, publish the +implementation parts of the plugin to pub. + +You may need to publish each implementation package independently of +the main package also, depending on exactly what your change entails. diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java index 98cf6dbaacea..053e3faa9694 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v0.1.12), do not edit directly. +// Autogenerated from Pigeon (v0.1.19), do not edit directly. // See also: https://pub.dev/packages/pigeon package io.flutter.plugins.videoplayer; diff --git a/packages/video_player/video_player/ios/Classes/messages.h b/packages/video_player/video_player/ios/Classes/messages.h index 84e8fc5e5cff..80137c9d61f5 100644 --- a/packages/video_player/video_player/ios/Classes/messages.h +++ b/packages/video_player/video_player/ios/Classes/messages.h @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v0.1.12), do not edit directly. +// Autogenerated from Pigeon (v0.1.19), do not edit directly. // See also: https://pub.dev/packages/pigeon #import @protocol FlutterBinaryMessenger; diff --git a/packages/video_player/video_player/ios/Classes/messages.m b/packages/video_player/video_player/ios/Classes/messages.m index 58ff7292d2b2..3f787fcdf92d 100644 --- a/packages/video_player/video_player/ios/Classes/messages.m +++ b/packages/video_player/video_player/ios/Classes/messages.m @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v0.1.12), do not edit directly. +// Autogenerated from Pigeon (v0.1.19), do not edit directly. // See also: https://pub.dev/packages/pigeon #import "messages.h" #import diff --git a/packages/video_player/video_player/pigeons/messages.dart b/packages/video_player/video_player/pigeons/messages.dart index f1771afecb45..ebef9e526b6a 100644 --- a/packages/video_player/video_player/pigeons/messages.dart +++ b/packages/video_player/video_player/pigeons/messages.dart @@ -54,6 +54,7 @@ abstract class VideoPlayerApi { void configurePigeon(PigeonOptions opts) { opts.dartOut = '../video_player_platform_interface/lib/messages.dart'; + opts.dartTestOut = '../video_player_platform_interface/lib/test.dart'; opts.objcHeaderOut = 'ios/Classes/messages.h'; opts.objcSourceOut = 'ios/Classes/messages.m'; opts.objcOptions.prefix = 'FLT'; diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index 47b8f601e711..e21315025005 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -1,7 +1,7 @@ name: video_player description: Flutter plugin for displaying inline video with other Flutter widgets on Android, iOS, and web. -version: 2.0.0-nullsafety.9 +version: 2.0.0-nullsafety.10 homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player flutter: @@ -17,23 +17,24 @@ flutter: dependencies: meta: ^1.3.0-nullsafety.3 - video_player_platform_interface: ^3.0.0-nullsafety.3 + video_player_platform_interface: ^4.0.0-nullsafety.0 # The design on https://flutter.dev/go/federated-plugins was to leave # this constraint as "any". We cannot do it right now as it fails pub publish - # validation, so we set a ^ constraint. - # TODO(amirh): Revisit this (either update this part in the design or the pub tool). + # validation, so we set a ^ constraint. The exact value doesn't matter since + # the constraints on the interface pins it. + # TODO(amirh): Revisit this (either update this part in the design or the pub tool). # https://github.com/flutter/flutter/issues/46264 video_player_web: ^2.0.0-nullsafety.1 flutter: sdk: flutter - -dev_dependencies: flutter_test: sdk: flutter + +dev_dependencies: pedantic: ^1.10.0-nullsafety.1 - pigeon: 0.1.7 + pigeon: ^0.1.19 environment: sdk: ">=2.12.0-0 <3.0.0" diff --git a/packages/video_player/video_player/test/video_player_test.dart b/packages/video_player/video_player/test/video_player_test.dart index eb276a8d72e7..582012097b71 100644 --- a/packages/video_player/video_player/test/video_player_test.dart +++ b/packages/video_player/video_player/test/video_player_test.dart @@ -12,6 +12,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:video_player/video_player.dart'; import 'package:video_player_platform_interface/messages.dart'; +import 'package:video_player_platform_interface/test.dart'; import 'package:video_player_platform_interface/video_player_platform_interface.dart'; class FakeController extends ValueNotifier diff --git a/script/incremental_build.sh b/script/incremental_build.sh index d98e7aac6e30..bc41ebd3c70d 100755 --- a/script/incremental_build.sh +++ b/script/incremental_build.sh @@ -12,7 +12,7 @@ ALL_EXCLUDED=("") # Exclude nnbd plugins from stable. if [ "$CHANNEL" == "stable" ]; then ALL_EXCLUDED=($EXCLUDED_PLUGINS_FROM_STABLE) - echo "Excluding the following plugins: $ALL_EXCLUDED" + echo "Excluding the following plugins because stable does not yet support NNBD: $ALL_EXCLUDED" fi # Plugins that deliberately use their own analysis_options.yaml. From cb309bca15379d3c09ad56e4564e69b8635d77b3 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Wed, 17 Feb 2021 09:17:44 -0800 Subject: [PATCH 0144/1565] Publish check (#3556) --- script/check_publish.sh | 26 +----- script/tool/lib/src/main.dart | 2 + .../tool/lib/src/publish_check_command.dart | 92 +++++++++++++++++++ 3 files changed, 95 insertions(+), 25 deletions(-) create mode 100644 script/tool/lib/src/publish_check_command.dart diff --git a/script/check_publish.sh b/script/check_publish.sh index 5584fc601916..c92de4be2e08 100755 --- a/script/check_publish.sh +++ b/script/check_publish.sh @@ -10,33 +10,9 @@ readonly REPO_DIR="$(dirname "$SCRIPT_DIR")" source "$SCRIPT_DIR/common.sh" -function check_publish() { - local failures=() - for dir in $(plugin_tools list --plugins="$1"); do - local package_name=$(basename "$dir") - - echo "Checking that $package_name can be published." - if [[ $(cd "$dir" && cat pubspec.yaml | grep -E "^publish_to: none") ]]; then - echo "Package $package_name is marked as unpublishable. Skipping." - elif (cd "$dir" && flutter pub publish -- --dry-run > /dev/null); then - echo "Package $package_name is able to be published." - else - error "Unable to publish $package_name" - failures=("${failures[@]}" "$package_name") - fi - done - if [[ "${#failures[@]}" != 0 ]]; then - error "FAIL: The following ${#failures[@]} package(s) failed the publishing check:" - for failure in "${failures[@]}"; do - error "$failure" - done - fi - return "${#failures[@]}" -} - # Sets CHANGED_PACKAGE_LIST and CHANGED_PACKAGES check_changed_packages if [[ "${#CHANGED_PACKAGE_LIST[@]}" != 0 ]]; then - check_publish "${CHANGED_PACKAGES}" + plugin_tools publish-check --plugins="${CHANGED_PACKAGES}" fi diff --git a/script/tool/lib/src/main.dart b/script/tool/lib/src/main.dart index bb3f67c0a9e1..fa81597237d7 100644 --- a/script/tool/lib/src/main.dart +++ b/script/tool/lib/src/main.dart @@ -7,6 +7,7 @@ import 'dart:io' as io; import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:file/local.dart'; +import 'package:flutter_plugin_tools/src/publish_check_command.dart'; import 'package:flutter_plugin_tools/src/publish_plugin_command.dart'; import 'package:path/path.dart' as p; @@ -51,6 +52,7 @@ void main(List args) { ..addCommand(JavaTestCommand(packagesDir, fileSystem)) ..addCommand(LintPodspecsCommand(packagesDir, fileSystem)) ..addCommand(ListCommand(packagesDir, fileSystem)) + ..addCommand(PublishCheckCommand(packagesDir, fileSystem)) ..addCommand(PublishPluginCommand(packagesDir, fileSystem)) ..addCommand(TestCommand(packagesDir, fileSystem)) ..addCommand(VersionCheckCommand(packagesDir, fileSystem)) diff --git a/script/tool/lib/src/publish_check_command.dart b/script/tool/lib/src/publish_check_command.dart new file mode 100644 index 000000000000..8d6f6bb9ab61 --- /dev/null +++ b/script/tool/lib/src/publish_check_command.dart @@ -0,0 +1,92 @@ +// 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. + +import 'dart:async'; + +import 'package:colorize/colorize.dart'; +import 'package:file/file.dart'; +import 'package:pubspec_parse/pubspec_parse.dart'; + +import 'common.dart'; + +class PublishCheckCommand extends PluginCommand { + PublishCheckCommand( + Directory packagesDir, + FileSystem fileSystem, { + ProcessRunner processRunner = const ProcessRunner(), + }) : super(packagesDir, fileSystem, processRunner: processRunner); + + @override + final String name = 'publish-check'; + + @override + final String description = + 'Checks to make sure that a plugin *could* be published.'; + + @override + Future run() async { + checkSharding(); + final List failedPackages = []; + + await for (Directory plugin in getPlugins()) { + if (!(await passesPublishCheck(plugin))) failedPackages.add(plugin); + } + + if (failedPackages.isNotEmpty) { + final String error = + 'FAIL: The following ${failedPackages.length} package(s) failed the ' + 'publishing check:'; + final String joinedFailedPackages = failedPackages.join('\n'); + + final Colorize colorizedError = Colorize('$error\n$joinedFailedPackages') + ..red(); + print(colorizedError); + throw ToolExit(1); + } + + final Colorize passedMessage = + Colorize('All packages passed publish check!')..green(); + print(passedMessage); + } + + Pubspec tryParsePubspec(Directory package) { + final File pubspecFile = package.childFile('pubspec.yaml'); + + try { + return Pubspec.parse(pubspecFile.readAsStringSync()); + } on Exception catch (exception) { + print( + 'Failed to parse `pubspec.yaml` at ${pubspecFile.path}: $exception}', + ); + return null; + } + } + + Future passesPublishCheck(Directory package) async { + final String packageName = package.basename; + print('Checking that $packageName can be published.'); + + final Pubspec pubspec = tryParsePubspec(package); + if (pubspec == null) { + return false; + } else if (pubspec.publishTo == 'none') { + print('Package $packageName is marked as unpublishable. Skipping.'); + return true; + } + + final int exitCode = await processRunner.runAndStream( + 'flutter', + ['pub', 'publish', '--', '--dry-run'], + workingDir: package, + ); + + if (exitCode == 0) { + print("Package $packageName is able to be published."); + return true; + } else { + print('Unable to publish $packageName'); + return false; + } + } +} From bf571074fa87baca188a1de6ebc937ed08e7e7d7 Mon Sep 17 00:00:00 2001 From: Jeremiah Parrack Date: Thu, 18 Feb 2021 10:33:13 -0500 Subject: [PATCH 0145/1565] Update video_player readme to change sample video to https (#3546) --- packages/video_player/video_player/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/video_player/video_player/README.md b/packages/video_player/video_player/README.md index e64ce152f85b..d66dfcdfbd98 100644 --- a/packages/video_player/video_player/README.md +++ b/packages/video_player/video_player/README.md @@ -77,7 +77,7 @@ class _VideoAppState extends State { void initState() { super.initState(); _controller = VideoPlayerController.network( - 'http://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4') + 'https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4') ..initialize().then((_) { // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed. setState(() {}); From 361567b9189c92ccefbc322e88244cfb31bfa00e Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 18 Feb 2021 16:33:41 +0100 Subject: [PATCH 0146/1565] [camera] Added timeout to Android pre-capture sequence (#3558) * Added timeout for waiting pre-capture state Android * Fix analysis warning and bumped version --- packages/camera/camera/CHANGELOG.md | 4 ++++ .../io/flutter/plugins/camera/Camera.java | 24 +++++++++++++++++++ packages/camera/camera/pubspec.yaml | 2 +- packages/camera/camera/test/camera_test.dart | 2 +- 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index aee3774087ba..7391f3090565 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.8.0-nullsafety.1 + +* Added a timeout to the pre-capture sequence on Android to prevent crashes when the camera cannot get a focus. + ## 0.8.0-nullsafety * Migrated to null safety. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index a5f8647afb0b..5169a3babb74 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -36,6 +36,7 @@ import android.os.Build.VERSION_CODES; import android.os.Handler; import android.os.Looper; +import android.os.SystemClock; import android.util.Log; import android.util.Range; import android.util.Rational; @@ -73,6 +74,9 @@ interface ErrorCallback { public class Camera { private static final String TAG = "Camera"; + /** Timeout for the pre-capture sequence. */ + private static final long PRECAPTURE_TIMEOUT_MS = 1000; + private final SurfaceTextureEntry flutterTexture; private final CameraManager cameraManager; private final DeviceOrientationManager deviceOrientationListener; @@ -105,6 +109,7 @@ public class Camera { private boolean useAutoFocus = true; private Range fpsRange; private PlatformChannel.DeviceOrientation lockedCaptureOrientation; + private long preCaptureStartTime; private static final HashMap supportedImageFormats; // Current supported outputs @@ -503,11 +508,16 @@ private void processCapture(CaptureResult result) { || aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED || aeState == CaptureRequest.CONTROL_AE_STATE_CONVERGED) { pictureCaptureRequest.setState(State.waitingPreCaptureReady); + setPreCaptureStartTime(); } break; case waitingPreCaptureReady: if (aeState == null || aeState != CaptureRequest.CONTROL_AE_STATE_PRECAPTURE) { runPictureCapture(); + } else { + if (hitPreCaptureTimeout()) { + unlockAutoFocus(); + } } } } @@ -1142,6 +1152,20 @@ public void stopImageStream() throws CameraAccessException { startPreview(); } + /** Sets the time the pre-capture sequence started. */ + private void setPreCaptureStartTime() { + preCaptureStartTime = SystemClock.elapsedRealtime(); + } + + /** + * Check if the timeout for the pre-capture sequence has been reached. + * + * @return true if the timeout is reached; otherwise false is returned. + */ + private boolean hitPreCaptureTimeout() { + return (SystemClock.elapsedRealtime() - preCaptureStartTime) > PRECAPTURE_TIMEOUT_MS; + } + private void closeCaptureSession() { if (cameraCaptureSession != null) { cameraCaptureSession.close(); diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 7ed08d892de8..5b98c39acd99 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.8.0-nullsafety +version: 0.8.0-nullsafety.1 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index b37b7701a14f..40ce29e363b1 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -1268,7 +1268,7 @@ class MockCameraPlatform extends Mock Future createCamera( CameraDescription description, ResolutionPreset? resolutionPreset, { - bool enableAudio = true, + bool enableAudio = false, }) => mockPlatformException ? throw PlatformException(code: 'foo', message: 'bar') From f784207d09b7e695b925bcaf8ba744a26e5b2309 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Thu, 18 Feb 2021 09:47:08 -0800 Subject: [PATCH 0147/1565] Publish check ignores prerelease sdk (#3560) --- .../tool/lib/src/publish_check_command.dart | 47 ++++++++++++++++--- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/script/tool/lib/src/publish_check_command.dart b/script/tool/lib/src/publish_check_command.dart index 8d6f6bb9ab61..af009952856e 100644 --- a/script/tool/lib/src/publish_check_command.dart +++ b/script/tool/lib/src/publish_check_command.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:io' as io; import 'package:colorize/colorize.dart'; import 'package:file/file.dart'; @@ -63,6 +64,44 @@ class PublishCheckCommand extends PluginCommand { } } + Future hasValidPublishCheckRun(Directory package) async { + final io.Process process = await io.Process.start( + 'flutter', + ['pub', 'publish', '--', '--dry-run'], + workingDirectory: package.path, + ); + + final StringBuffer outputBuffer = StringBuffer(); + + final Completer stdOutCompleter = Completer(); + process.stdout.listen( + (List event) { + io.stdout.add(event); + outputBuffer.write(String.fromCharCodes(event)); + }, + onDone: () => stdOutCompleter.complete(), + ); + + final Completer stdInCompleter = Completer(); + process.stderr.listen( + (List event) { + io.stderr.add(event); + outputBuffer.write(String.fromCharCodes(event)); + }, + onDone: () => stdInCompleter.complete(), + ); + + if (await process.exitCode == 0) return true; + + await stdOutCompleter.future; + await stdInCompleter.future; + + final String output = outputBuffer.toString(); + return output.contains('Package has 1 warning.') && + output.contains( + 'Packages with an SDK constraint on a pre-release of the Dart SDK should themselves be published as a pre-release version.'); + } + Future passesPublishCheck(Directory package) async { final String packageName = package.basename; print('Checking that $packageName can be published.'); @@ -75,13 +114,7 @@ class PublishCheckCommand extends PluginCommand { return true; } - final int exitCode = await processRunner.runAndStream( - 'flutter', - ['pub', 'publish', '--', '--dry-run'], - workingDir: package, - ); - - if (exitCode == 0) { + if (await hasValidPublishCheckRun(package)) { print("Package $packageName is able to be published."); return true; } else { From 73a75b8a73492cea817662d0e496bd1a5d2187b8 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 18 Feb 2021 13:45:01 -0800 Subject: [PATCH 0148/1565] Migrate plugin_platform_interface to v2 stable, null-safe (#3543) --- packages/plugin_platform_interface/CHANGELOG.md | 10 +--------- packages/plugin_platform_interface/pubspec.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/packages/plugin_platform_interface/CHANGELOG.md b/packages/plugin_platform_interface/CHANGELOG.md index 96533f01c10f..cea8f2a76266 100644 --- a/packages/plugin_platform_interface/CHANGELOG.md +++ b/packages/plugin_platform_interface/CHANGELOG.md @@ -1,12 +1,4 @@ -## 1.1.0-nullsafety.2 - -* Use Mockito null safe. - -## 1.1.0-nullsafety.1 - -* Bump Dart SDK to support null safety. - -## 1.1.0-nullsafety +## 2.0.0 * Migrate to null safety. diff --git a/packages/plugin_platform_interface/pubspec.yaml b/packages/plugin_platform_interface/pubspec.yaml index 084e577dbf99..12a5b066bc61 100644 --- a/packages/plugin_platform_interface/pubspec.yaml +++ b/packages/plugin_platform_interface/pubspec.yaml @@ -12,7 +12,7 @@ description: Reusable base class for Flutter plugin platform interfaces. # be done when absolutely necessary and after the ecosystem has already migrated to 1.X.Y version # that is forward compatible with 2.0.0 (ideally the ecosystem have migrated to depend on: # `plugin_platform_interface: >=1.X.Y <3.0.0`). -version: 1.1.0-nullsafety.2 +version: 2.0.0 repository: https://github.com/flutter/plugins/tree/master/packages/plugin_platform_interface @@ -20,9 +20,9 @@ environment: sdk: ">=2.12.0-0 <3.0.0" dependencies: - meta: ^1.3.0-nullsafety.3 + meta: ^1.3.0 dev_dependencies: - mockito: ^5.0.0-nullsafety.2 - test: ^1.10.0-nullsafety.1 - pedantic: ^1.10.0-nullsafety.1 + mockito: ^5.0.0-nullsafety.7 + test: ^1.16.0 + pedantic: ^1.10.0 From f1253313425e24ffc2e75814a79e99593d9ad4a4 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Thu, 18 Feb 2021 15:01:39 -0800 Subject: [PATCH 0149/1565] [shared_preferences] fix crash when list type is dynaimc (#3565) --- .../shared_preferences/shared_preferences/CHANGELOG.md | 4 ++++ .../shared_preferences/lib/shared_preferences.dart | 2 +- .../shared_preferences/shared_preferences/pubspec.yaml | 2 +- .../test/shared_preferences_test.dart | 10 ++++++++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/shared_preferences/shared_preferences/CHANGELOG.md b/packages/shared_preferences/shared_preferences/CHANGELOG.md index 1f003ef5b133..a14ebf547659 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.1 + +* Fix crash when list string's type is dynamic. + ## 2.0.0-nullsafety * Migrate to null-safety. diff --git a/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart b/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart index 03619fd14b4f..2f4ebe730351 100644 --- a/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart +++ b/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart @@ -107,7 +107,7 @@ class SharedPreferences { /// Reads a set of string values from persistent storage, throwing an /// exception if it's not a string set. List? getStringList(String key) { - List? list = _preferenceCache[key] as List?; + List? list = _preferenceCache[key] as List?; if (list != null && list is! List) { list = list.cast().toList(); _preferenceCache[key] = list; diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index 1bf314cadcfa..fc556972a847 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -2,7 +2,7 @@ name: shared_preferences description: Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences -version: 2.0.0-nullsafety +version: 2.0.0-nullsafety.1 flutter: plugin: diff --git a/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart index 9f6e7203fa85..7866b2e38fac 100755 --- a/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart @@ -39,6 +39,7 @@ void main() { tearDown(() async { await preferences.clear(); + await store.clear(); }); test('reading', () async { @@ -156,6 +157,15 @@ void main() { expect(await first, await second); }); + test('string list type is dynamic (usually from method channel)', () async { + SharedPreferences.setMockInitialValues({ + 'dynamic_list': ['1', '2'] + }); + final SharedPreferences prefs = await SharedPreferences.getInstance(); + final List? value = prefs.getStringList('dynamic_list'); + expect(value, ['1', '2']); + }); + group('mocking', () { const String _key = 'dummy'; const String _prefixedKey = 'flutter.' + _key; From 4290d18f0e43288087b3754c41d4739872d9a152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Vincke?= Date: Fri, 19 Feb 2021 00:48:21 +0100 Subject: [PATCH 0150/1565] [webview_flutter] Support for loading progress tracking (#2151) --- packages/webview_flutter/CHANGELOG.md | 4 ++ .../webviewflutter/FlutterWebView.java | 8 +++ .../webviewflutter/FlutterWebViewClient.java | 9 +++ .../webview_flutter/example/lib/main.dart | 3 + .../ios/Classes/FLTWKProgressionDelegate.h | 19 ++++++ .../ios/Classes/FLTWKProgressionDelegate.m | 42 ++++++++++++ .../ios/Classes/FlutterWebView.m | 15 ++++ .../lib/platform_interface.dart | 11 ++- .../lib/src/webview_method_channel.dart | 4 ++ .../webview_flutter/lib/webview_flutter.dart | 20 ++++++ .../test/webview_flutter_test.dart | 68 +++++++++++++++++++ 11 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.h create mode 100644 packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.m diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index b3218e296d98..0a060ef0cf2d 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.6 + +* Added support for progress tracking. + ## 2.0.0-nullsafety.5 * Add section to the wiki explaining how to use Material components. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index ef9f006f6e5b..4578c7e0d1fe 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -72,6 +72,11 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) { return true; } + + @Override + public void onProgressChanged(WebView view, int progress) { + flutterWebViewClient.onLoadingProgress(progress); + } } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) @@ -367,6 +372,9 @@ private void applySettings(Map settings) { webView.setWebContentsDebuggingEnabled(debuggingEnabled); } break; + case "hasProgressTracking": + flutterWebViewClient.hasProgressTracking = (boolean) settings.get(key); + break; case "gestureNavigationEnabled": break; case "userAgent": diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java index 24926bfc4117..3590d67eb334 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java @@ -30,6 +30,7 @@ class FlutterWebViewClient { private static final String TAG = "FlutterWebViewClient"; private final MethodChannel methodChannel; private boolean hasNavigationDelegate; + boolean hasProgressTracking; FlutterWebViewClient(MethodChannel methodChannel) { this.methodChannel = methodChannel; @@ -125,6 +126,14 @@ private void onPageFinished(WebView view, String url) { methodChannel.invokeMethod("onPageFinished", args); } + void onLoadingProgress(int progress) { + if (hasProgressTracking) { + Map args = new HashMap<>(); + args.put("progress", progress); + methodChannel.invokeMethod("onProgress", args); + } + } + private void onWebResourceError( final int errorCode, final String description, final String failingUrl) { final Map args = new HashMap<>(); diff --git a/packages/webview_flutter/example/lib/main.dart b/packages/webview_flutter/example/lib/main.dart index c7f42ac2bf66..e7e7981150ca 100644 --- a/packages/webview_flutter/example/lib/main.dart +++ b/packages/webview_flutter/example/lib/main.dart @@ -62,6 +62,9 @@ class _WebViewExampleState extends State { onWebViewCreated: (WebViewController webViewController) { _controller.complete(webViewController); }, + onProgress: (int progress) { + print("WebView is loading (progress : $progress%)"); + }, javascriptChannels: { _toasterJavascriptChannel(context), }, diff --git a/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.h b/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.h new file mode 100644 index 000000000000..40139ead262c --- /dev/null +++ b/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.h @@ -0,0 +1,19 @@ +// Copyright 2019 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. + +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface FLTWKProgressionDelegate : NSObject + +- (instancetype)initWithWebView:(WKWebView *)webView channel:(FlutterMethodChannel *)channel; + +- (void)stopObservingProgress:(WKWebView *)webView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.m b/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.m new file mode 100644 index 000000000000..ad864e6e1fd1 --- /dev/null +++ b/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.m @@ -0,0 +1,42 @@ +// Copyright 2019 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. + +#import "FLTWKProgressionDelegate.h" + +NSString *const FLTWKEstimatedProgressKeyPath = @"estimatedProgress"; + +@implementation FLTWKProgressionDelegate { + FlutterMethodChannel *_methodChannel; +} + +- (instancetype)initWithWebView:(WKWebView *)webView channel:(FlutterMethodChannel *)channel { + self = [super init]; + if (self) { + _methodChannel = channel; + [webView addObserver:self + forKeyPath:FLTWKEstimatedProgressKeyPath + options:NSKeyValueObservingOptionNew + context:nil]; + } + return self; +} + +- (void)stopObservingProgress:(WKWebView *)webView { + [webView removeObserver:self forKeyPath:FLTWKEstimatedProgressKeyPath]; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath + ofObject:(id)object + change:(NSDictionary *)change + context:(void *)context { + if ([keyPath isEqualToString:FLTWKEstimatedProgressKeyPath]) { + NSNumber *newValue = + change[NSKeyValueChangeNewKey] ?: 0; // newValue is anywhere between 0.0 and 1.0 + int newValueAsInt = [newValue floatValue] * 100; // Anywhere between 0 and 100 + [_methodChannel invokeMethod:@"onProgress" + arguments:@{@"progress" : [NSNumber numberWithInt:newValueAsInt]}]; + } +} + +@end diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.m b/packages/webview_flutter/ios/Classes/FlutterWebView.m index ed3cf44424e8..5f2af3b8aae0 100644 --- a/packages/webview_flutter/ios/Classes/FlutterWebView.m +++ b/packages/webview_flutter/ios/Classes/FlutterWebView.m @@ -4,6 +4,7 @@ #import "FlutterWebView.h" #import "FLTWKNavigationDelegate.h" +#import "FLTWKProgressionDelegate.h" #import "JavaScriptChannelHandler.h" @implementation FLTWebViewFactory { @@ -64,6 +65,7 @@ @implementation FLTWebViewController { // The set of registered JavaScript channel names. NSMutableSet* _javaScriptChannelNames; FLTWKNavigationDelegate* _navigationDelegate; + FLTWKProgressionDelegate* _progressionDelegate; } - (instancetype)initWithFrame:(CGRect)frame @@ -119,6 +121,12 @@ - (instancetype)initWithFrame:(CGRect)frame return self; } +- (void)dealloc { + if (_progressionDelegate != nil) { + [_progressionDelegate stopObservingProgress:_webView]; + } +} + - (UIView*)view { return _webView; } @@ -323,6 +331,13 @@ - (NSString*)applySettings:(NSDictionary*)settings { } else if ([key isEqualToString:@"hasNavigationDelegate"]) { NSNumber* hasDartNavigationDelegate = settings[key]; _navigationDelegate.hasDartNavigationDelegate = [hasDartNavigationDelegate boolValue]; + } else if ([key isEqualToString:@"hasProgressTracking"]) { + NSNumber* hasProgressTrackingValue = settings[key]; + bool hasProgressTracking = [hasProgressTrackingValue boolValue]; + if (hasProgressTracking) { + _progressionDelegate = [[FLTWKProgressionDelegate alloc] initWithWebView:_webView + channel:_channel]; + } } else if ([key isEqualToString:@"debuggingEnabled"]) { // no-op debugging is always enabled on iOS. } else if ([key isEqualToString:@"gestureNavigationEnabled"]) { diff --git a/packages/webview_flutter/lib/platform_interface.dart b/packages/webview_flutter/lib/platform_interface.dart index a840c0036fb3..16b529d7090e 100644 --- a/packages/webview_flutter/lib/platform_interface.dart +++ b/packages/webview_flutter/lib/platform_interface.dart @@ -30,6 +30,10 @@ abstract class WebViewPlatformCallbacksHandler { /// Invoked by [WebViewPlatformController] when a page has finished loading. void onPageFinished(String url); + /// Invoked by [WebViewPlatformController] when a page is loading. + /// /// Only works when [WebSettings.hasProgressTracking] is set to `true`. + void onProgress(int progress); + /// Report web resource loading error to the host application. void onWebResourceError(WebResourceError error); } @@ -388,6 +392,7 @@ class WebSettings { WebSettings({ this.javascriptMode, this.hasNavigationDelegate, + this.hasProgressTracking, this.debuggingEnabled, this.gestureNavigationEnabled, this.allowsInlineMediaPlayback, @@ -400,6 +405,10 @@ class WebSettings { /// Whether the [WebView] has a [NavigationDelegate] set. final bool? hasNavigationDelegate; + /// Whether the [WebView] should track page loading progress. + /// See also: [WebViewPlatformCallbacksHandler.onProgress] to get the progress. + final bool? hasProgressTracking; + /// Whether to enable the platform's webview content debugging tools. /// /// See also: [WebView.debuggingEnabled]. @@ -427,7 +436,7 @@ class WebSettings { @override String toString() { - return 'WebSettings(javascriptMode: $javascriptMode, hasNavigationDelegate: $hasNavigationDelegate, debuggingEnabled: $debuggingEnabled, gestureNavigationEnabled: $gestureNavigationEnabled, userAgent: $userAgent, allowsInlineMediaPlayback: $allowsInlineMediaPlayback)'; + return 'WebSettings(javascriptMode: $javascriptMode, hasNavigationDelegate: $hasNavigationDelegate, hasProgressTracking: $hasProgressTracking, debuggingEnabled: $debuggingEnabled, gestureNavigationEnabled: $gestureNavigationEnabled, userAgent: $userAgent, allowsInlineMediaPlayback: $allowsInlineMediaPlayback)'; } } diff --git a/packages/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/lib/src/webview_method_channel.dart index 54ab647cdc04..ef1ed51835b8 100644 --- a/packages/webview_flutter/lib/src/webview_method_channel.dart +++ b/packages/webview_flutter/lib/src/webview_method_channel.dart @@ -40,6 +40,9 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { case 'onPageFinished': _platformCallbacksHandler.onPageFinished(call.arguments['url']!); return null; + case 'onProgress': + _platformCallbacksHandler.onProgress(call.arguments['progress']); + return null; case 'onPageStarted': _platformCallbacksHandler.onPageStarted(call.arguments['url']!); return null; @@ -183,6 +186,7 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { _addIfNonNull('jsMode', settings!.javascriptMode?.index); _addIfNonNull('hasNavigationDelegate', settings.hasNavigationDelegate); + _addIfNonNull('hasProgressTracking', settings.hasProgressTracking); _addIfNonNull('debuggingEnabled', settings.debuggingEnabled); _addIfNonNull( 'gestureNavigationEnabled', settings.gestureNavigationEnabled); diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart index 6853d39555c3..7e4f3d6ac079 100644 --- a/packages/webview_flutter/lib/webview_flutter.dart +++ b/packages/webview_flutter/lib/webview_flutter.dart @@ -142,6 +142,9 @@ typedef void PageStartedCallback(String url); /// Signature for when a [WebView] has finished loading a page. typedef void PageFinishedCallback(String url); +/// Signature for when a [WebView] is loading a page. +typedef void PageLoadingCallback(int progress); + /// Signature for when a [WebView] has failed to load a resource. typedef void WebResourceErrorCallback(WebResourceError error); @@ -217,6 +220,7 @@ class WebView extends StatefulWidget { this.gestureRecognizers, this.onPageStarted, this.onPageFinished, + this.onProgress, this.onWebResourceError, this.debuggingEnabled = false, this.gestureNavigationEnabled = false, @@ -357,6 +361,9 @@ class WebView extends StatefulWidget { /// [WebViewController.evaluateJavascript] can assume this. final PageFinishedCallback? onPageFinished; + /// Invoked when a page is loading. + final PageLoadingCallback? onProgress; + /// Invoked when a web resource has failed to load. /// /// This can be called for any resource (iframe, image, etc.), not just for @@ -476,6 +483,7 @@ WebSettings _webSettingsFromWidget(WebView widget) { return WebSettings( javascriptMode: widget.javascriptMode, hasNavigationDelegate: widget.navigationDelegate != null, + hasProgressTracking: widget.onProgress != null, debuggingEnabled: widget.debuggingEnabled, gestureNavigationEnabled: widget.gestureNavigationEnabled, allowsInlineMediaPlayback: widget.allowsInlineMediaPlayback, @@ -488,6 +496,7 @@ WebSettings _clearUnchangedWebSettings( WebSettings currentValue, WebSettings newValue) { assert(currentValue.javascriptMode != null); assert(currentValue.hasNavigationDelegate != null); + assert(currentValue.hasProgressTracking != null); assert(currentValue.debuggingEnabled != null); assert(currentValue.userAgent != null); assert(newValue.javascriptMode != null); @@ -497,6 +506,7 @@ WebSettings _clearUnchangedWebSettings( JavascriptMode? javascriptMode; bool? hasNavigationDelegate; + bool? hasProgressTracking; bool? debuggingEnabled; WebSetting userAgent = WebSetting.absent(); if (currentValue.javascriptMode != newValue.javascriptMode) { @@ -505,6 +515,9 @@ WebSettings _clearUnchangedWebSettings( if (currentValue.hasNavigationDelegate != newValue.hasNavigationDelegate) { hasNavigationDelegate = newValue.hasNavigationDelegate; } + if (currentValue.hasProgressTracking != newValue.hasProgressTracking) { + hasProgressTracking = newValue.hasProgressTracking; + } if (currentValue.debuggingEnabled != newValue.debuggingEnabled) { debuggingEnabled = newValue.debuggingEnabled; } @@ -515,6 +528,7 @@ WebSettings _clearUnchangedWebSettings( return WebSettings( javascriptMode: javascriptMode, hasNavigationDelegate: hasNavigationDelegate, + hasProgressTracking: hasProgressTracking, debuggingEnabled: debuggingEnabled, userAgent: userAgent, ); @@ -571,6 +585,12 @@ class _PlatformCallbacksHandler implements WebViewPlatformCallbacksHandler { } @override + void onProgress(int progress) { + if (_widget.onProgress != null) { + _widget.onProgress!(progress); + } + } + void onWebResourceError(WebResourceError error) { if (_widget.onWebResourceError != null) { _widget.onWebResourceError!(error); diff --git a/packages/webview_flutter/test/webview_flutter_test.dart b/packages/webview_flutter/test/webview_flutter_test.dart index 162b1932e49d..8ae6e625431d 100644 --- a/packages/webview_flutter/test/webview_flutter_test.dart +++ b/packages/webview_flutter/test/webview_flutter_test.dart @@ -692,6 +692,62 @@ void main() { }); }); + group('$PageLoadingCallback', () { + testWidgets('onLoadingProgress is not null', (WidgetTester tester) async { + int? loadingProgress; + + await tester.pumpWidget(WebView( + initialUrl: 'https://youtube.com', + onProgress: (int progress) { + loadingProgress = progress; + }, + )); + + final FakePlatformWebView? platformWebView = + fakePlatformViewsController.lastCreatedView; + + platformWebView?.fakeOnProgressCallback(50); + + expect(loadingProgress, 50); + }); + + testWidgets('onLoadingProgress is null', (WidgetTester tester) async { + await tester.pumpWidget(const WebView( + initialUrl: 'https://youtube.com', + onProgress: null, + )); + + final FakePlatformWebView platformWebView = + fakePlatformViewsController.lastCreatedView!; + + // This is to test that it does not crash on a null callback. + platformWebView.fakeOnProgressCallback(50); + }); + + testWidgets('onLoadingProgress changed', (WidgetTester tester) async { + int? loadingProgress; + + await tester.pumpWidget(WebView( + initialUrl: 'https://youtube.com', + onProgress: (int progress) {}, + )); + + await tester.pumpWidget(WebView( + initialUrl: 'https://youtube.com', + onProgress: (int progress) { + loadingProgress = progress; + }, + )); + + final FakePlatformWebView platformWebView = + fakePlatformViewsController.lastCreatedView!; + + platformWebView.fakeOnProgressCallback(50); + + expect(loadingProgress, 50); + }); + }); + group('navigationDelegate', () { testWidgets('hasNavigationDelegate', (WidgetTester tester) async { await tester.pumpWidget(const WebView( @@ -1021,6 +1077,18 @@ class FakePlatformWebView { ); } + void fakeOnProgressCallback(int progress) { + final StandardMethodCodec codec = const StandardMethodCodec(); + + final ByteData data = codec.encodeMethodCall(MethodCall( + 'onProgress', + {'progress': progress}, + )); + + ServicesBinding.instance!.defaultBinaryMessenger + .handlePlatformMessage(channel.name, data, (ByteData? data) {}); + } + void _loadUrl(String? url) { history = history.sublist(0, currentPosition + 1); history.add(url); From d2c011f80a0bbb2b40752c934566e5b8ad6c148f Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Thu, 18 Feb 2021 18:34:24 -0800 Subject: [PATCH 0151/1565] [shared_preferences] Migrate examples to NNBD (#3564) Migrate all examples to NNBD so that the example apps will run in strong mode. Converts macOS example to use the platform interface to remove circular dependencies (code is based on the Linux and Windows versions which already use essentially that approach). --- .../shared_preferences_test.dart | 6 + .../shared_preferences/example/lib/main.dart | 4 +- .../shared_preferences/example/pubspec.yaml | 3 +- .../example/test_driver/integration_test.dart | 2 + .../shared_preferences_test.dart | 6 + .../example/lib/main.dart | 10 +- .../example/pubspec.yaml | 2 +- .../example/test_driver/integration_test.dart | 2 + .../shared_preferences_test.dart | 110 +++++++++++------- .../example/lib/main.dart | 24 ++-- .../macos/Runner.xcodeproj/project.pbxproj | 21 +--- .../contents.xcworkspacedata | 3 + .../example/pubspec.yaml | 4 +- .../example/test_driver/integration_test.dart | 2 + .../shared_preferences_macos/pubspec.yaml | 1 + .../shared_preferences_test.dart | 6 +- .../example/lib/main.dart | 10 +- .../example/pubspec.yaml | 6 +- .../example/test_driver/integration_test.dart | 8 +- 19 files changed, 138 insertions(+), 92 deletions(-) diff --git a/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart index e43d4e3ae0c2..1caf695d9365 100644 --- a/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_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 'dart:async'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; diff --git a/packages/shared_preferences/shared_preferences/example/lib/main.dart b/packages/shared_preferences/shared_preferences/example/lib/main.dart index 46daeff6706f..26e6c8eb42f8 100644 --- a/packages/shared_preferences/shared_preferences/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences/example/lib/main.dart @@ -24,7 +24,7 @@ class MyApp extends StatelessWidget { } class SharedPreferencesDemo extends StatefulWidget { - SharedPreferencesDemo({Key key}) : super(key: key); + SharedPreferencesDemo({Key? key}) : super(key: key); @override SharedPreferencesDemoState createState() => SharedPreferencesDemoState(); @@ -32,7 +32,7 @@ class SharedPreferencesDemo extends StatefulWidget { class SharedPreferencesDemoState extends State { Future _prefs = SharedPreferences.getInstance(); - Future _counter; + late Future _counter; Future _incrementCounter() async { final SharedPreferences prefs = await _prefs; diff --git a/packages/shared_preferences/shared_preferences/example/pubspec.yaml b/packages/shared_preferences/shared_preferences/example/pubspec.yaml index 05f2528af2af..ab6c8fe11f7f 100644 --- a/packages/shared_preferences/shared_preferences/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/example/pubspec.yaml @@ -23,6 +23,5 @@ flutter: uses-material-design: true environment: - sdk: ">=2.0.0-dev.28.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.9.1+hotfix.2" - diff --git a/packages/shared_preferences/shared_preferences/example/test_driver/integration_test.dart b/packages/shared_preferences/shared_preferences/example/test_driver/integration_test.dart index 7a2c21338786..ac106b63b339 100644 --- a/packages/shared_preferences/shared_preferences/example/test_driver/integration_test.dart +++ b/packages/shared_preferences/shared_preferences/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/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart index 3aedccd0feba..019dc248a918 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_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 'dart:async'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/shared_preferences/shared_preferences_linux/example/lib/main.dart b/packages/shared_preferences/shared_preferences_linux/example/lib/main.dart index ceacf2f95f28..ab664cd652ff 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences_linux/example/lib/main.dart @@ -24,7 +24,7 @@ class MyApp extends StatelessWidget { } class SharedPreferencesDemo extends StatefulWidget { - SharedPreferencesDemo({Key key}) : super(key: key); + SharedPreferencesDemo({Key? key}) : super(key: key); @override SharedPreferencesDemoState createState() => SharedPreferencesDemoState(); @@ -32,14 +32,14 @@ class SharedPreferencesDemo extends StatefulWidget { class SharedPreferencesDemoState extends State { final prefs = SharedPreferencesLinux.instance; - Future _counter; + late Future _counter; Future _incrementCounter() async { final values = await prefs.getAll(); - final int counter = (values['counter'] as int ?? 0) + 1; + final int counter = (values['counter'] as int? ?? 0) + 1; setState(() { - _counter = prefs.setValue(null, "counter", counter).then((bool success) { + _counter = prefs.setValue('Int', 'counter', counter).then((bool success) { return counter; }); }); @@ -49,7 +49,7 @@ class SharedPreferencesDemoState extends State { void initState() { super.initState(); _counter = prefs.getAll().then((Map values) { - return (values['counter'] ?? 0); + return (values['counter'] as int? ?? 0); }); } diff --git a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml index 5fc8ae039812..12b78c37ea9c 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml @@ -23,5 +23,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.8" diff --git a/packages/shared_preferences/shared_preferences_linux/example/test_driver/integration_test.dart b/packages/shared_preferences/shared_preferences_linux/example/test_driver/integration_test.dart index 7a2c21338786..ac106b63b339 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/test_driver/integration_test.dart +++ b/packages/shared_preferences/shared_preferences_linux/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/shared_preferences/shared_preferences_macos/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_macos/example/integration_test/shared_preferences_test.dart index 0d49ed95dd2d..58b59463b352 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_macos/example/integration_test/shared_preferences_test.dart @@ -1,12 +1,18 @@ +// Copyright 2017, 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. + +// @dart=2.9 + import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; -import 'package:shared_preferences/shared_preferences.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; import 'package:integration_test/integration_test.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - group('$SharedPreferences', () { + group('SharedPreferencesMacOS', () { const Map kTestValues = { 'flutter.String': 'hello world', 'flutter.bool': true, @@ -23,67 +29,81 @@ void main() { 'flutter.List': ['baz', 'quox'], }; - SharedPreferences preferences; + SharedPreferencesStorePlatform preferences; setUp(() async { - preferences = await SharedPreferences.getInstance(); + preferences = SharedPreferencesStorePlatform.instance; }); tearDown(() { preferences.clear(); }); - test('reading', () async { - expect(preferences.get('String'), isNull); - expect(preferences.get('bool'), isNull); - expect(preferences.get('int'), isNull); - expect(preferences.get('double'), isNull); - expect(preferences.get('List'), isNull); - expect(preferences.getString('String'), isNull); - expect(preferences.getBool('bool'), isNull); - expect(preferences.getInt('int'), isNull); - expect(preferences.getDouble('double'), isNull); - expect(preferences.getStringList('List'), isNull); + // Normally the app-facing package adds the prefix, but since this test + // bypasses the app-facing package it needs to be manually added. + String _prefixedKey(String key) { + return 'flutter.$key'; + } + + testWidgets('reading', (WidgetTester _) async { + final Map values = await preferences.getAll(); + expect(values[_prefixedKey('String')], isNull); + expect(values[_prefixedKey('bool')], isNull); + expect(values[_prefixedKey('int')], isNull); + expect(values[_prefixedKey('double')], isNull); + expect(values[_prefixedKey('List')], isNull); }); - test('writing', () async { + testWidgets('writing', (WidgetTester _) async { await Future.wait(>[ - preferences.setString('String', kTestValues2['flutter.String']), - preferences.setBool('bool', kTestValues2['flutter.bool']), - preferences.setInt('int', kTestValues2['flutter.int']), - preferences.setDouble('double', kTestValues2['flutter.double']), - preferences.setStringList('List', kTestValues2['flutter.List']) + preferences.setValue( + 'String', _prefixedKey('String'), kTestValues2['flutter.String']), + preferences.setValue( + 'Bool', _prefixedKey('bool'), kTestValues2['flutter.bool']), + preferences.setValue( + 'Int', _prefixedKey('int'), kTestValues2['flutter.int']), + preferences.setValue( + 'Double', _prefixedKey('double'), kTestValues2['flutter.double']), + preferences.setValue( + 'StringList', _prefixedKey('List'), kTestValues2['flutter.List']) ]); - expect(preferences.getString('String'), kTestValues2['flutter.String']); - expect(preferences.getBool('bool'), kTestValues2['flutter.bool']); - expect(preferences.getInt('int'), kTestValues2['flutter.int']); - expect(preferences.getDouble('double'), kTestValues2['flutter.double']); - expect(preferences.getStringList('List'), kTestValues2['flutter.List']); + final Map values = await preferences.getAll(); + expect(values[_prefixedKey('String')], kTestValues2['flutter.String']); + expect(values[_prefixedKey('bool')], kTestValues2['flutter.bool']); + expect(values[_prefixedKey('int')], kTestValues2['flutter.int']); + expect(values[_prefixedKey('double')], kTestValues2['flutter.double']); + expect(values[_prefixedKey('List')], kTestValues2['flutter.List']); }); - test('removing', () async { - const String key = 'testKey'; - await preferences.setString(key, kTestValues['flutter.String']); - await preferences.setBool(key, kTestValues['flutter.bool']); - await preferences.setInt(key, kTestValues['flutter.int']); - await preferences.setDouble(key, kTestValues['flutter.double']); - await preferences.setStringList(key, kTestValues['flutter.List']); + testWidgets('removing', (WidgetTester _) async { + final String key = _prefixedKey('testKey'); + await preferences.setValue('String', key, kTestValues['flutter.String']); + await preferences.setValue('Bool', key, kTestValues['flutter.bool']); + await preferences.setValue('Int', key, kTestValues['flutter.int']); + await preferences.setValue('Double', key, kTestValues['flutter.double']); + await preferences.setValue( + 'StringList', key, kTestValues['flutter.List']); await preferences.remove(key); - expect(preferences.get('testKey'), isNull); + final Map values = await preferences.getAll(); + expect(values[key], isNull); }); - test('clearing', () async { - await preferences.setString('String', kTestValues['flutter.String']); - await preferences.setBool('bool', kTestValues['flutter.bool']); - await preferences.setInt('int', kTestValues['flutter.int']); - await preferences.setDouble('double', kTestValues['flutter.double']); - await preferences.setStringList('List', kTestValues['flutter.List']); + testWidgets('clearing', (WidgetTester _) async { + await preferences.setValue( + 'String', 'String', kTestValues['flutter.String']); + await preferences.setValue('Bool', 'bool', kTestValues['flutter.bool']); + await preferences.setValue('Int', 'int', kTestValues['flutter.int']); + await preferences.setValue( + 'Double', 'double', kTestValues['flutter.double']); + await preferences.setValue( + 'StringList', 'List', kTestValues['flutter.List']); await preferences.clear(); - expect(preferences.getString('String'), null); - expect(preferences.getBool('bool'), null); - expect(preferences.getInt('int'), null); - expect(preferences.getDouble('double'), null); - expect(preferences.getStringList('List'), null); + final Map values = await preferences.getAll(); + expect(values['String'], null); + expect(values['bool'], null); + expect(values['int'], null); + expect(values['double'], null); + expect(values['List'], null); }); }); } diff --git a/packages/shared_preferences/shared_preferences_macos/example/lib/main.dart b/packages/shared_preferences/shared_preferences_macos/example/lib/main.dart index 46daeff6706f..f1058cddd63b 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences_macos/example/lib/main.dart @@ -7,7 +7,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:shared_preferences/shared_preferences.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; void main() { runApp(MyApp()); @@ -24,22 +24,28 @@ class MyApp extends StatelessWidget { } class SharedPreferencesDemo extends StatefulWidget { - SharedPreferencesDemo({Key key}) : super(key: key); + SharedPreferencesDemo({Key? key}) : super(key: key); @override SharedPreferencesDemoState createState() => SharedPreferencesDemoState(); } class SharedPreferencesDemoState extends State { - Future _prefs = SharedPreferences.getInstance(); - Future _counter; + SharedPreferencesStorePlatform _prefs = + SharedPreferencesStorePlatform.instance; + late Future _counter; + + // Includes the prefix because this is using the platform interface directly, + // but the prefix (which the native code assumes is present) is added by the + // app-facing package. + static const String _prefKey = 'flutter.counter'; Future _incrementCounter() async { - final SharedPreferences prefs = await _prefs; - final int counter = (prefs.getInt('counter') ?? 0) + 1; + final Map values = await _prefs.getAll(); + final int counter = ((values[_prefKey] as int?) ?? 0) + 1; setState(() { - _counter = prefs.setInt("counter", counter).then((bool success) { + _counter = _prefs.setValue('Int', _prefKey, counter).then((bool success) { return counter; }); }); @@ -48,8 +54,8 @@ class SharedPreferencesDemoState extends State { @override void initState() { super.initState(); - _counter = _prefs.then((SharedPreferences prefs) { - return (prefs.getInt('counter') ?? 0); + _counter = _prefs.getAll().then((Map values) { + return (values[_prefKey] as int?) ?? 0; }); } diff --git a/packages/shared_preferences/shared_preferences_macos/example/macos/Runner.xcodeproj/project.pbxproj b/packages/shared_preferences/shared_preferences_macos/example/macos/Runner.xcodeproj/project.pbxproj index a95e62daada1..20c47b4f601f 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/macos/Runner.xcodeproj/project.pbxproj +++ b/packages/shared_preferences/shared_preferences_macos/example/macos/Runner.xcodeproj/project.pbxproj @@ -26,10 +26,6 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; - 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; }; - 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; }; - D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; DD4A1B9DEDBB72C87CD7AE27 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5067D74CB28D28AE3B3DD05B /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ @@ -50,8 +46,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */, - 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */, ); name = "Bundle Framework"; runOnlyForDeploymentPostprocessing = 0; @@ -70,7 +64,6 @@ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; - 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; }; 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; @@ -80,7 +73,6 @@ 899489AD6AA35AECA4E2BEA6 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; B36FDC1D769C9045B8821207 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -88,8 +80,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D73912F022F37F9E000D13A0 /* App.framework in Frameworks */, - 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */, DD4A1B9DEDBB72C87CD7AE27 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -145,8 +135,6 @@ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, - D73912EF22F37F9E000D13A0 /* App.framework */, - 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */, ); path = Flutter; sourceTree = ""; @@ -281,7 +269,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n"; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; }; 33CC111E2044C6BF0003C045 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; @@ -308,10 +296,13 @@ buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/shared_preferences_macos/shared_preferences_macos.framework", ); name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_macos.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; diff --git a/packages/shared_preferences/shared_preferences_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/packages/shared_preferences/shared_preferences_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata index 1d526a16ed0f..21a3cc14c74e 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata +++ b/packages/shared_preferences/shared_preferences_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml index 5543b4a3b8c2..6a8e7e4b470a 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml @@ -4,7 +4,7 @@ description: Demonstrates how to use the shared_preferences plugin. dependencies: flutter: sdk: flutter - shared_preferences: any + shared_preferences_platform_interface: ^2.0.0-nullsafety shared_preferences_macos: # When depending on this package from a real application you should use: # shared_preferences_macos: ^x.y.z @@ -24,5 +24,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.8" diff --git a/packages/shared_preferences/shared_preferences_macos/example/test_driver/integration_test.dart b/packages/shared_preferences/shared_preferences_macos/example/test_driver/integration_test.dart index 7a2c21338786..ac106b63b339 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/test_driver/integration_test.dart +++ b/packages/shared_preferences/shared_preferences_macos/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/shared_preferences/shared_preferences_macos/pubspec.yaml b/packages/shared_preferences/shared_preferences_macos/pubspec.yaml index 754cf14f18f0..4f014ecb8929 100644 --- a/packages/shared_preferences/shared_preferences_macos/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_macos/pubspec.yaml @@ -17,5 +17,6 @@ dependencies: shared_preferences_platform_interface: ^2.0.0-nullsafety flutter: sdk: flutter + dev_dependencies: pedantic: ^1.8.0 diff --git a/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart index 016a21f70fe3..027daa6eaeb1 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart @@ -2,13 +2,15 @@ // 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 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences_windows/shared_preferences_windows.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('SharedPreferencesWindows', () { const Map kTestValues = { diff --git a/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart b/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart index 140851c90504..f0dc155aee4a 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart @@ -24,7 +24,7 @@ class MyApp extends StatelessWidget { } class SharedPreferencesDemo extends StatefulWidget { - SharedPreferencesDemo({Key key}) : super(key: key); + SharedPreferencesDemo({Key? key}) : super(key: key); @override SharedPreferencesDemoState createState() => SharedPreferencesDemoState(); @@ -32,14 +32,14 @@ class SharedPreferencesDemo extends StatefulWidget { class SharedPreferencesDemoState extends State { final prefs = SharedPreferencesWindows.instance; - Future _counter; + late Future _counter; Future _incrementCounter() async { final values = await prefs.getAll(); - final int counter = (values['counter'] as int ?? 0) + 1; + final int counter = (values['counter'] as int? ?? 0) + 1; setState(() { - _counter = prefs.setValue(null, "counter", counter).then((bool success) { + _counter = prefs.setValue('Int', 'counter', counter).then((bool success) { return counter; }); }); @@ -49,7 +49,7 @@ class SharedPreferencesDemoState extends State { void initState() { super.initState(); _counter = prefs.getAll().then((Map values) { - return (values['counter'] ?? 0); + return (values['counter'] as int? ?? 0); }); } diff --git a/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml index 1af679b4ede3..575e3f8409c6 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml @@ -2,7 +2,8 @@ name: shared_preferences_windows_example description: Demonstrates how to use the shared_preferences_windows plugin. environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" + flutter: ">=1.12.8" dependencies: flutter: @@ -21,7 +22,8 @@ dependency_overrides: dev_dependencies: flutter_driver: sdk: flutter - e2e: ^0.2.0 + integration_test: + path: ../../../integration_test pedantic: ^1.8.0 flutter: diff --git a/packages/shared_preferences/shared_preferences_windows/example/test_driver/integration_test.dart b/packages/shared_preferences/shared_preferences_windows/example/test_driver/integration_test.dart index 102dfdfef708..353548ee0e8c 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/test_driver/integration_test.dart +++ b/packages/shared_preferences/shared_preferences_windows/example/test_driver/integration_test.dart @@ -2,14 +2,18 @@ // 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'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } From fa95cde0781289ef6918ecc287bfa63d4736bf1f Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Fri, 19 Feb 2021 09:13:19 +0100 Subject: [PATCH 0152/1565] [video_player_web] Ignore mixWithOthers option (#3561) The documentation is updated to note this option will be silently ignored in web. Signed-off-by: Leandro Lucarella --- packages/video_player/video_player/CHANGELOG.md | 4 ++++ packages/video_player/video_player/README.md | 2 ++ packages/video_player/video_player/pubspec.yaml | 2 +- .../video_player_platform_interface/CHANGELOG.md | 4 ++++ .../lib/video_player_platform_interface.dart | 3 +++ .../video_player_platform_interface/pubspec.yaml | 2 +- packages/video_player/video_player_web/CHANGELOG.md | 4 ++++ packages/video_player/video_player_web/README.md | 4 ++++ .../video_player/video_player_web/lib/video_player_web.dart | 4 ++++ packages/video_player/video_player_web/pubspec.yaml | 2 +- .../video_player_web/test/video_player_web_test.dart | 5 +++++ 11 files changed, 33 insertions(+), 3 deletions(-) diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index 0cabfc48226d..f79a05f0e036 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.11 + +* Setting the `mixWithOthers` `VideoPlayerOptions` in web now is silently ignored instead of throwing an exception. + ## 2.0.0-nullsafety.10 * Updated to video_player_platform_interface 4.0. diff --git a/packages/video_player/video_player/README.md b/packages/video_player/video_player/README.md index d66dfcdfbd98..7e36008cbbc3 100644 --- a/packages/video_player/video_player/README.md +++ b/packages/video_player/video_player/README.md @@ -48,6 +48,8 @@ This plugin compiles for the web platform since version `0.10.5`, in recent enou Different web browsers may have different video-playback capabilities (supported formats, autoplay...). Check [package:video_player_web](https://pub.dev/packages/video_player_web) for more web-specific information. +The `VideoPlayerOptions.mixWithOthers` option can't be implemented in web, at least at the moment. If you use this option in web it will be silently ignored. + ## Supported Formats - On iOS, the backing player is [AVPlayer](https://developer.apple.com/documentation/avfoundation/avplayer). diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index e21315025005..39289d159195 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -1,7 +1,7 @@ name: video_player description: Flutter plugin for displaying inline video with other Flutter widgets on Android, iOS, and web. -version: 2.0.0-nullsafety.10 +version: 2.0.0-nullsafety.11 homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player flutter: diff --git a/packages/video_player/video_player_platform_interface/CHANGELOG.md b/packages/video_player/video_player_platform_interface/CHANGELOG.md index 34df33664c68..7b223f4d958c 100644 --- a/packages/video_player/video_player_platform_interface/CHANGELOG.md +++ b/packages/video_player/video_player_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 4.0.0-nullsafety.1 + +* Add note about the `mixWithOthers` option being ignored on the web. + ## 4.0.0-nullsafety.0 * Update to latest Pigeon. diff --git a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart index f2bc00205acc..77b34f46bc10 100644 --- a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart +++ b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart @@ -346,6 +346,9 @@ class DurationRange { class VideoPlayerOptions { /// Set this to true to mix the video players audio with other audio sources. /// The default value is false + /// + /// Note: This option will be silently ignored in the web platform (there is + /// currently no way to implement this feature in this platform). final bool mixWithOthers; /// set additional optional player settings diff --git a/packages/video_player/video_player_platform_interface/pubspec.yaml b/packages/video_player/video_player_platform_interface/pubspec.yaml index e493eebd800e..ed16ea1033fa 100644 --- a/packages/video_player/video_player_platform_interface/pubspec.yaml +++ b/packages/video_player/video_player_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the video_player plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 4.0.0-nullsafety.0 +version: 4.0.0-nullsafety.1 dependencies: flutter: diff --git a/packages/video_player/video_player_web/CHANGELOG.md b/packages/video_player/video_player_web/CHANGELOG.md index 7b3fc7871628..4c58311508a2 100644 --- a/packages/video_player/video_player_web/CHANGELOG.md +++ b/packages/video_player/video_player_web/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.4 + +* Calling `setMixWithOthers()` now is silently ignored instead of throwing an exception. + ## 2.0.0-nullsafety.3 * Updated to video_player_platform_interface 4.0. diff --git a/packages/video_player/video_player_web/README.md b/packages/video_player/video_player_web/README.md index 4f222be914eb..d44f738aeb66 100644 --- a/packages/video_player/video_player_web/README.md +++ b/packages/video_player/video_player_web/README.md @@ -28,6 +28,10 @@ The Web platform does **not** suppport `dart:io`, so attempts to create a `Video Playing videos without prior interaction with the site might be prohibited by the browser and lead to runtime errors. See also: https://goo.gl/xX8pDD. +## Mixing audio with other audio sources + +The `VideoPlayerOptions.mixWithOthers` option can't be implemented in web, at least at the moment. If you use this option it will be silently ignored. + ## Supported Formats **Different web browsers support different sets of video codecs.** diff --git a/packages/video_player/video_player_web/lib/video_player_web.dart b/packages/video_player/video_player_web/lib/video_player_web.dart index 9132a08437da..18f9e5e58cd6 100644 --- a/packages/video_player/video_player_web/lib/video_player_web.dart +++ b/packages/video_player/video_player_web/lib/video_player_web.dart @@ -144,6 +144,10 @@ class VideoPlayerPlugin extends VideoPlayerPlatform { Widget buildView(int textureId) { return HtmlElementView(viewType: 'videoPlayer-$textureId'); } + + /// Sets the audio mode to mix with other sources (ignored) + @override + Future setMixWithOthers(bool mixWithOthers) => Future.value(); } class _VideoPlayer { diff --git a/packages/video_player/video_player_web/pubspec.yaml b/packages/video_player/video_player_web/pubspec.yaml index df5f4564bf4a..d9628535e353 100644 --- a/packages/video_player/video_player_web/pubspec.yaml +++ b/packages/video_player/video_player_web/pubspec.yaml @@ -1,7 +1,7 @@ name: video_player_web description: Web platform implementation of video_player. homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player_web -version: 2.0.0-nullsafety.3 +version: 2.0.0-nullsafety.4 flutter: plugin: diff --git a/packages/video_player/video_player_web/test/video_player_web_test.dart b/packages/video_player/video_player_web/test/video_player_web_test.dart index 94b788872b03..604bebf4e17a 100644 --- a/packages/video_player/video_player_web/test/video_player_web_test.dart +++ b/packages/video_player/video_player_web/test/video_player_web_test.dart @@ -136,5 +136,10 @@ void main() { expect(VideoPlayerPlatform.instance.buildView(textureId), isInstanceOf()); }); + + test('ignores setting mixWithOthers', () { + expect(VideoPlayerPlatform.instance.setMixWithOthers(true), completes); + expect(VideoPlayerPlatform.instance.setMixWithOthers(false), completes); + }); }); } From 982e1ca54bac31572b9c43897eec39e24f818dc5 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 19 Feb 2021 07:29:09 -0800 Subject: [PATCH 0153/1565] [path_provider] Migrate examples to null-safety (#3559) Allows running the examples in strong mode, even though the integration tests can't yet be. Converts the macOS example to use the platform interface, rather than the app-facing package, to eliminate the circular dependency. Also does some cleanup and simplification of the desktop example pubspecs. Does not update versions/changelogs since this won't be explicitly published, given that it's example-only. --- .../integration_test/path_provider_test.dart | 2 + .../path_provider/example/lib/main.dart | 38 ++-- .../path_provider/example/pubspec.yaml | 2 +- .../example/test_driver/integration_test.dart | 2 + .../integration_test/path_provider_test.dart | 2 + .../path_provider_linux/example/lib/main.dart | 18 +- .../path_provider_linux/example/pubspec.yaml | 44 +---- .../example/test/widget_test.dart | 8 +- .../example/test_driver/integration_test.dart | 2 + .../integration_test/path_provider_test.dart | 36 ++-- .../path_provider_macos/example/lib/main.dart | 170 ++++++------------ .../macos/Runner.xcodeproj/project.pbxproj | 21 +-- .../macos/Runner/DebugProfile.entitlements | 2 + .../example/macos/Runner/Release.entitlements | 2 + .../path_provider_macos/example/pubspec.yaml | 8 +- .../example/test_driver/integration_test.dart | 2 + .../integration_test/path_provider_test.dart | 6 +- .../example/lib/main.dart | 18 +- .../example/pubspec.yaml | 8 +- .../example/test_driver/integration_test.dart | 8 +- .../path_provider_windows/pubspec.yaml | 2 +- 21 files changed, 162 insertions(+), 239 deletions(-) diff --git a/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart b/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart index 8eb8520b5b4b..2b12c82f959b 100644 --- a/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider/example/integration_test/path_provider_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:io'; diff --git a/packages/path_provider/path_provider/example/lib/main.dart b/packages/path_provider/path_provider/example/lib/main.dart index 8e929a6882fe..ddc1f8a6e2d5 100644 --- a/packages/path_provider/path_provider/example/lib/main.dart +++ b/packages/path_provider/path_provider/example/lib/main.dart @@ -28,7 +28,7 @@ class MyApp extends StatelessWidget { } class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); + MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @override @@ -36,13 +36,13 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { - Future _tempDirectory; - Future _appSupportDirectory; - Future _appLibraryDirectory; - Future _appDocumentsDirectory; - Future _externalDocumentsDirectory; - Future> _externalStorageDirectories; - Future> _externalCacheDirectories; + Future? _tempDirectory; + Future? _appSupportDirectory; + Future? _appLibraryDirectory; + Future? _appDocumentsDirectory; + Future? _externalDocumentsDirectory; + Future?>? _externalStorageDirectories; + Future?>? _externalCacheDirectories; void _requestTempDirectory() { setState(() { @@ -51,13 +51,13 @@ class _MyHomePageState extends State { } Widget _buildDirectory( - BuildContext context, AsyncSnapshot snapshot) { + BuildContext context, AsyncSnapshot snapshot) { Text text = const Text(''); if (snapshot.connectionState == ConnectionState.done) { if (snapshot.hasError) { text = Text('Error: ${snapshot.error}'); } else if (snapshot.hasData) { - text = Text('path: ${snapshot.data.path}'); + text = Text('path: ${snapshot.data!.path}'); } else { text = const Text('path unavailable'); } @@ -66,14 +66,14 @@ class _MyHomePageState extends State { } Widget _buildDirectories( - BuildContext context, AsyncSnapshot> snapshot) { + BuildContext context, AsyncSnapshot?> snapshot) { Text text = const Text(''); if (snapshot.connectionState == ConnectionState.done) { if (snapshot.hasError) { text = Text('Error: ${snapshot.error}'); } else if (snapshot.hasData) { final String combined = - snapshot.data.map((Directory d) => d.path).join(', '); + snapshot.data!.map((Directory d) => d.path).join(', '); text = Text('paths: $combined'); } else { text = const Text('path unavailable'); @@ -134,7 +134,7 @@ class _MyHomePageState extends State { onPressed: _requestTempDirectory, ), ), - FutureBuilder( + FutureBuilder( future: _tempDirectory, builder: _buildDirectory), Padding( padding: const EdgeInsets.all(16.0), @@ -143,7 +143,7 @@ class _MyHomePageState extends State { onPressed: _requestAppDocumentsDirectory, ), ), - FutureBuilder( + FutureBuilder( future: _appDocumentsDirectory, builder: _buildDirectory), Padding( padding: const EdgeInsets.all(16.0), @@ -152,7 +152,7 @@ class _MyHomePageState extends State { onPressed: _requestAppSupportDirectory, ), ), - FutureBuilder( + FutureBuilder( future: _appSupportDirectory, builder: _buildDirectory), Padding( padding: const EdgeInsets.all(16.0), @@ -161,7 +161,7 @@ class _MyHomePageState extends State { onPressed: _requestAppLibraryDirectory, ), ), - FutureBuilder( + FutureBuilder( future: _appLibraryDirectory, builder: _buildDirectory), Padding( padding: const EdgeInsets.all(16.0), @@ -172,7 +172,7 @@ class _MyHomePageState extends State { Platform.isIOS ? null : _requestExternalStorageDirectory, ), ), - FutureBuilder( + FutureBuilder( future: _externalDocumentsDirectory, builder: _buildDirectory), Column(children: [ Padding( @@ -190,7 +190,7 @@ class _MyHomePageState extends State { ), ), ]), - FutureBuilder>( + FutureBuilder?>( future: _externalStorageDirectories, builder: _buildDirectories), Column(children: [ @@ -204,7 +204,7 @@ class _MyHomePageState extends State { ), ), ]), - FutureBuilder>( + FutureBuilder?>( future: _externalCacheDirectories, builder: _buildDirectories), ], ), diff --git a/packages/path_provider/path_provider/example/pubspec.yaml b/packages/path_provider/path_provider/example/pubspec.yaml index bbb140e8f4bf..cef0449ca01a 100644 --- a/packages/path_provider/path_provider/example/pubspec.yaml +++ b/packages/path_provider/path_provider/example/pubspec.yaml @@ -23,5 +23,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" diff --git a/packages/path_provider/path_provider/example/test_driver/integration_test.dart b/packages/path_provider/path_provider/example/test_driver/integration_test.dart index 7a2c21338786..ac106b63b339 100644 --- a/packages/path_provider/path_provider/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider/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/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart b/packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart index febd52172759..d08b3878a4d5 100644 --- a/packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider_linux/example/integration_test/path_provider_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:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:path_provider_linux/path_provider_linux.dart'; diff --git a/packages/path_provider/path_provider_linux/example/lib/main.dart b/packages/path_provider/path_provider_linux/example/lib/main.dart index 069308233acb..6958ed10cb23 100644 --- a/packages/path_provider/path_provider_linux/example/lib/main.dart +++ b/packages/path_provider/path_provider_linux/example/lib/main.dart @@ -4,7 +4,7 @@ import 'dart:async'; import 'package:flutter/services.dart'; import 'package:path_provider_linux/path_provider_linux.dart'; -void main() async { +void main() { runApp(MyApp()); } @@ -15,10 +15,10 @@ class MyApp extends StatefulWidget { } class _MyAppState extends State { - String _tempDirectory = 'Unknown'; - String _downloadsDirectory = 'Unknown'; - String _appSupportDirectory = 'Unknown'; - String _documentsDirectory = 'Unknown'; + String? _tempDirectory = 'Unknown'; + String? _downloadsDirectory = 'Unknown'; + String? _appSupportDirectory = 'Unknown'; + String? _documentsDirectory = 'Unknown'; final PathProviderLinux _provider = PathProviderLinux(); @override @@ -29,10 +29,10 @@ class _MyAppState extends State { // Platform messages are asynchronous, so we initialize in an async method. Future initDirectories() async { - String tempDirectory; - String downloadsDirectory; - String appSupportDirectory; - String documentsDirectory; + String? tempDirectory; + String? downloadsDirectory; + String? appSupportDirectory; + String? documentsDirectory; // Platform messages may fail, so we use a try/catch PlatformException. try { tempDirectory = await _provider.getTemporaryPath(); diff --git a/packages/path_provider/path_provider_linux/example/pubspec.yaml b/packages/path_provider/path_provider_linux/example/pubspec.yaml index a1a9dde163cf..1fd55712ee44 100644 --- a/packages/path_provider/path_provider_linux/example/pubspec.yaml +++ b/packages/path_provider/path_provider_linux/example/pubspec.yaml @@ -3,19 +3,13 @@ description: Demonstrates how to use the path_provider_linux plugin. publish_to: "none" environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" + flutter: ">=1.10.0" dependencies: flutter: sdk: flutter - path_provider_linux: any - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - -dependency_overrides: path_provider_linux: # When depending on this package from a real application you should use: # path_provider_linux: ^x.y.z @@ -32,39 +26,5 @@ dev_dependencies: integration_test: path: ../../../integration_test -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/packages/path_provider/path_provider_linux/example/test/widget_test.dart b/packages/path_provider/path_provider_linux/example/test/widget_test.dart index 8ebda3b77176..086b6d614e13 100644 --- a/packages/path_provider/path_provider_linux/example/test/widget_test.dart +++ b/packages/path_provider/path_provider_linux/example/test/widget_test.dart @@ -30,7 +30,7 @@ void main() { find.byWidgetPredicate( (Widget widget) => widget is Text && - widget.data.startsWith('Temp Directory: /tmp'), + widget.data!.startsWith('Temp Directory: /tmp'), ), findsOneWidget, ); @@ -48,7 +48,7 @@ void main() { find.byWidgetPredicate( (Widget widget) => widget is Text && - widget.data.startsWith('Documents Directory: /'), + widget.data!.startsWith('Documents Directory: /'), ), findsOneWidget, ); @@ -66,7 +66,7 @@ void main() { find.byWidgetPredicate( (Widget widget) => widget is Text && - widget.data.startsWith('Downloads Directory: /'), + widget.data!.startsWith('Downloads Directory: /'), ), findsOneWidget, ); @@ -85,7 +85,7 @@ void main() { find.byWidgetPredicate( (Widget widget) => widget is Text && - widget.data.startsWith('Application Support Directory: /'), + widget.data!.startsWith('Application Support Directory: /'), ), findsOneWidget, ); diff --git a/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart b/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart index 7a2c21338786..ac106b63b339 100644 --- a/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider_linux/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/path_provider/path_provider_macos/example/integration_test/path_provider_test.dart b/packages/path_provider/path_provider_macos/example/integration_test/path_provider_test.dart index 58a4d1805cb0..1bb079051cfc 100644 --- a/packages/path_provider/path_provider_macos/example/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider_macos/example/integration_test/path_provider_test.dart @@ -2,42 +2,56 @@ // 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:io'; import 'package:flutter_test/flutter_test.dart'; -import 'package:path_provider/path_provider.dart'; +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; import 'package:integration_test/integration_test.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('getTemporaryDirectory', (WidgetTester tester) async { - final Directory result = await getTemporaryDirectory(); + final PathProviderPlatform provider = PathProviderPlatform.instance; + final String result = await provider.getTemporaryPath(); _verifySampleFile(result, 'temporaryDirectory'); }); testWidgets('getApplicationDocumentsDirectory', (WidgetTester tester) async { - final Directory result = await getApplicationDocumentsDirectory(); + final PathProviderPlatform provider = PathProviderPlatform.instance; + final String result = await provider.getApplicationDocumentsPath(); _verifySampleFile(result, 'applicationDocuments'); }); testWidgets('getApplicationSupportDirectory', (WidgetTester tester) async { - final Directory result = await getApplicationSupportDirectory(); + final PathProviderPlatform provider = PathProviderPlatform.instance; + final String result = await provider.getApplicationSupportPath(); _verifySampleFile(result, 'applicationSupport'); }); testWidgets('getLibraryDirectory', (WidgetTester tester) async { - if (!Platform.isMacOS) { - return; - } - final Directory result = await getLibraryDirectory(); + final PathProviderPlatform provider = PathProviderPlatform.instance; + final String result = await provider.getLibraryPath(); _verifySampleFile(result, 'library'); }); + + testWidgets('getDownloadsDirectory', (WidgetTester tester) async { + final PathProviderPlatform provider = PathProviderPlatform.instance; + final String result = await provider.getDownloadsPath(); + // _verifySampleFile causes hangs in driver for some reason, so just + // validate that a non-empty path was returned. + expect(result, isNotEmpty); + }); } -/// Verify a file called [name] in [directory] by recreating it with test +/// Verify a file called [name] in [directoryPath] by recreating it with test /// contents when necessary. -void _verifySampleFile(Directory directory, String name) { - final File file = File('${directory.path}/$name'); +/// +/// If [createDirectory] is true, the directory will be created if missing. +void _verifySampleFile(String directoryPath, String name) { + final Directory directory = Directory(directoryPath); + final File file = File('${directory.path}${Platform.pathSeparator}$name'); if (file.existsSync()) { file.deleteSync(); diff --git a/packages/path_provider/path_provider_macos/example/lib/main.dart b/packages/path_provider/path_provider_macos/example/lib/main.dart index 1c1c90b983c3..f19807f1c273 100644 --- a/packages/path_provider/path_provider_macos/example/lib/main.dart +++ b/packages/path_provider/path_provider_macos/example/lib/main.dart @@ -5,143 +5,87 @@ // ignore_for_file: public_member_api_docs import 'dart:async'; -import 'dart:io' show Directory; import 'package:flutter/material.dart'; -import 'package:path_provider/path_provider.dart'; +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; void main() { runApp(MyApp()); } -class MyApp extends StatelessWidget { +/// Sample app +class MyApp extends StatefulWidget { @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Path Provider', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: MyHomePage(title: 'Path Provider'), - ); - } + _MyAppState createState() => _MyAppState(); } -class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); - final String title; +class _MyAppState extends State { + String? _tempDirectory = 'Unknown'; + String? _downloadsDirectory = 'Unknown'; + String? _appSupportDirectory = 'Unknown'; + String? _documentsDirectory = 'Unknown'; @override - _MyHomePageState createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - Future _tempDirectory; - Future _appSupportDirectory; - Future _appDocumentsDirectory; - Future _appLibraryDirectory; - Future _downloadsDirectory; - - void _requestTempDirectory() { - setState(() { - _tempDirectory = getTemporaryDirectory(); - }); + void initState() { + super.initState(); + initDirectories(); } - Widget _buildDirectory( - BuildContext context, AsyncSnapshot snapshot) { - Text text = const Text(''); - if (snapshot.connectionState == ConnectionState.done) { - if (snapshot.hasError) { - text = Text('Error: ${snapshot.error}'); - } else if (snapshot.hasData) { - text = Text('path: ${snapshot.data.path}'); - } else { - text = const Text('path unavailable'); - } - } - return Padding(padding: const EdgeInsets.all(16.0), child: text); - } + // Platform messages are asynchronous, so we initialize in an async method. + Future initDirectories() async { + String? tempDirectory; + String? downloadsDirectory; + String? appSupportDirectory; + String? documentsDirectory; + final PathProviderPlatform provider = PathProviderPlatform.instance; - void _requestAppDocumentsDirectory() { - setState(() { - _appDocumentsDirectory = getApplicationDocumentsDirectory(); - }); - } + try { + tempDirectory = await provider.getTemporaryPath(); + } catch (exception) { + tempDirectory = 'Failed to get temp directory: $exception'; + } + try { + downloadsDirectory = await provider.getDownloadsPath(); + } catch (exception) { + downloadsDirectory = 'Failed to get downloads directory: $exception'; + } - void _requestAppSupportDirectory() { - setState(() { - _appSupportDirectory = getApplicationSupportDirectory(); - }); - } + try { + documentsDirectory = await provider.getApplicationDocumentsPath(); + } catch (exception) { + documentsDirectory = 'Failed to get documents directory: $exception'; + } - void _requestAppLibraryDirectory() { - setState(() { - _appLibraryDirectory = getLibraryDirectory(); - }); - } + try { + appSupportDirectory = await provider.getApplicationSupportPath(); + } catch (exception) { + appSupportDirectory = 'Failed to get app support directory: $exception'; + } - void _requestDownloadsDirectory() { setState(() { - _downloadsDirectory = getDownloadsDirectory(); + _tempDirectory = tempDirectory; + _downloadsDirectory = downloadsDirectory; + _appSupportDirectory = appSupportDirectory; + _documentsDirectory = documentsDirectory; }); } @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), - body: Center( - child: ListView( - children: [ - Padding( - padding: const EdgeInsets.all(16.0), - child: ElevatedButton( - child: const Text('Get Temporary Directory'), - onPressed: _requestTempDirectory, - ), - ), - FutureBuilder( - future: _tempDirectory, builder: _buildDirectory), - Padding( - padding: const EdgeInsets.all(16.0), - child: ElevatedButton( - child: const Text('Get Application Documents Directory'), - onPressed: _requestAppDocumentsDirectory, - ), - ), - FutureBuilder( - future: _appDocumentsDirectory, builder: _buildDirectory), - Padding( - padding: const EdgeInsets.all(16.0), - child: ElevatedButton( - child: const Text('Get Application Support Directory'), - onPressed: _requestAppSupportDirectory, - ), - ), - FutureBuilder( - future: _appSupportDirectory, builder: _buildDirectory), - Padding( - padding: const EdgeInsets.all(16.0), - child: ElevatedButton( - child: const Text('Get Application Library Directory'), - onPressed: _requestAppLibraryDirectory, - ), - ), - FutureBuilder( - future: _appLibraryDirectory, builder: _buildDirectory), - Padding( - padding: const EdgeInsets.all(16.0), - child: ElevatedButton( - child: const Text('Get Downlads Directory'), - onPressed: _requestDownloadsDirectory, - ), - ), - FutureBuilder( - future: _downloadsDirectory, builder: _buildDirectory), - ], + return MaterialApp( + home: Scaffold( + appBar: AppBar( + title: const Text('Path Provider example app'), + ), + body: Center( + child: Column( + children: [ + Text('Temp Directory: $_tempDirectory\n'), + Text('Documents Directory: $_documentsDirectory\n'), + Text('Downloads Directory: $_downloadsDirectory\n'), + Text('Application Support Directory: $_appSupportDirectory\n'), + ], + ), ), ), ); diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner.xcodeproj/project.pbxproj b/packages/path_provider/path_provider_macos/example/macos/Runner.xcodeproj/project.pbxproj index 1e39683e1446..51bfc333fa23 100644 --- a/packages/path_provider/path_provider_macos/example/macos/Runner.xcodeproj/project.pbxproj +++ b/packages/path_provider/path_provider_macos/example/macos/Runner.xcodeproj/project.pbxproj @@ -27,10 +27,6 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; - 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; }; - 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; }; - D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -50,8 +46,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */, - 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */, ); name = "Bundle Framework"; runOnlyForDeploymentPostprocessing = 0; @@ -72,14 +66,12 @@ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; - 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; }; 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; 46139048DB9F59D473B61B5E /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; - D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; }; F4586DA69948E3A954A2FC9C /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -88,8 +80,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D73912F022F37F9E000D13A0 /* App.framework in Frameworks */, - 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */, 23F6FAA3AF82DFCF2B7DD79A /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -156,8 +146,6 @@ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, - D73912EF22F37F9E000D13A0 /* App.framework */, - 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */, ); path = Flutter; sourceTree = ""; @@ -281,7 +269,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n"; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; }; 33CC111E2044C6BF0003C045 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; @@ -308,10 +296,13 @@ buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/path_provider_macos/path_provider_macos.framework", ); name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_macos.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/DebugProfile.entitlements b/packages/path_provider/path_provider_macos/example/macos/Runner/DebugProfile.entitlements index dddb8a30c851..8139952b3e55 100644 --- a/packages/path_provider/path_provider_macos/example/macos/Runner/DebugProfile.entitlements +++ b/packages/path_provider/path_provider_macos/example/macos/Runner/DebugProfile.entitlements @@ -8,5 +8,7 @@ com.apple.security.network.server + com.apple.security.files.downloads.read-write + diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/Release.entitlements b/packages/path_provider/path_provider_macos/example/macos/Runner/Release.entitlements index 852fa1a4728a..2f9659c917fb 100644 --- a/packages/path_provider/path_provider_macos/example/macos/Runner/Release.entitlements +++ b/packages/path_provider/path_provider_macos/example/macos/Runner/Release.entitlements @@ -4,5 +4,7 @@ com.apple.security.app-sandbox + com.apple.security.files.downloads.read-write + diff --git a/packages/path_provider/path_provider_macos/example/pubspec.yaml b/packages/path_provider/path_provider_macos/example/pubspec.yaml index cb904fa5ea98..495459319ca4 100644 --- a/packages/path_provider/path_provider_macos/example/pubspec.yaml +++ b/packages/path_provider/path_provider_macos/example/pubspec.yaml @@ -4,11 +4,6 @@ description: Demonstrates how to use the path_provider plugin. dependencies: flutter: sdk: flutter - path_provider: ^1.6.14 - -# path_provider_macos is endorsed, so we need to add it to dependency_overrides -# to depend on it from path: -dependency_overrides: path_provider_macos: # When depending on this package from a real application you should use: # path_provider_macos: ^x.y.z @@ -16,6 +11,7 @@ dependency_overrides: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ + path_provider_platform_interface: 2.0.0-nullsafety dev_dependencies: integration_test: @@ -28,5 +24,5 @@ flutter: uses-material-design: true environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.10.0" diff --git a/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart b/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart index 7a2c21338786..ac106b63b339 100644 --- a/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider_macos/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/path_provider/path_provider_windows/example/integration_test/path_provider_test.dart b/packages/path_provider/path_provider_windows/example/integration_test/path_provider_test.dart index ee9427686026..0953fc100950 100644 --- a/packages/path_provider/path_provider_windows/example/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider_windows/example/integration_test/path_provider_test.dart @@ -2,13 +2,15 @@ // 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:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:path_provider_windows/path_provider_windows.dart'; -import 'package:e2e/e2e.dart'; +import 'package:integration_test/integration_test.dart'; void main() { - E2EWidgetsFlutterBinding.ensureInitialized(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('getTemporaryDirectory', (WidgetTester tester) async { final PathProviderWindows provider = PathProviderWindows(); diff --git a/packages/path_provider/path_provider_windows/example/lib/main.dart b/packages/path_provider/path_provider_windows/example/lib/main.dart index 4fbb1decf2f4..964ef3d04db1 100644 --- a/packages/path_provider/path_provider_windows/example/lib/main.dart +++ b/packages/path_provider/path_provider_windows/example/lib/main.dart @@ -9,7 +9,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:path_provider_windows/path_provider_windows.dart'; -void main() async { +void main() { runApp(MyApp()); } @@ -20,10 +20,10 @@ class MyApp extends StatefulWidget { } class _MyAppState extends State { - String _tempDirectory = 'Unknown'; - String _downloadsDirectory = 'Unknown'; - String _appSupportDirectory = 'Unknown'; - String _documentsDirectory = 'Unknown'; + String? _tempDirectory = 'Unknown'; + String? _downloadsDirectory = 'Unknown'; + String? _appSupportDirectory = 'Unknown'; + String? _documentsDirectory = 'Unknown'; @override void initState() { @@ -33,10 +33,10 @@ class _MyAppState extends State { // Platform messages are asynchronous, so we initialize in an async method. Future initDirectories() async { - String tempDirectory; - String downloadsDirectory; - String appSupportDirectory; - String documentsDirectory; + String? tempDirectory; + String? downloadsDirectory; + String? appSupportDirectory; + String? documentsDirectory; final PathProviderWindows provider = PathProviderWindows(); try { diff --git a/packages/path_provider/path_provider_windows/example/pubspec.yaml b/packages/path_provider/path_provider_windows/example/pubspec.yaml index 7a34d90c0f6c..5704502528f7 100644 --- a/packages/path_provider/path_provider_windows/example/pubspec.yaml +++ b/packages/path_provider/path_provider_windows/example/pubspec.yaml @@ -4,9 +4,6 @@ description: Demonstrates how to use the path_provider plugin. dependencies: flutter: sdk: flutter - path_provider_windows: any - -dependency_overrides: path_provider_windows: # When depending on this package from a real application you should use: # path_provider_windows: ^x.y.z @@ -16,7 +13,8 @@ dependency_overrides: path: ../ dev_dependencies: - e2e: ^0.2.1 + integration_test: + path: ../../../integration_test flutter_driver: sdk: flutter pedantic: ^1.8.0 @@ -25,5 +23,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.4" diff --git a/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart b/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart index f3aa9e218d82..ac106b63b339 100644 --- a/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart @@ -2,14 +2,18 @@ // 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'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - final String result = + final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - exit(result == 'pass' ? 0 : 1); + final Map result = jsonDecode(data); + exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/path_provider/path_provider_windows/pubspec.yaml b/packages/path_provider/path_provider_windows/pubspec.yaml index 384eae94f5e5..eb7d1087d5f5 100644 --- a/packages/path_provider/path_provider_windows/pubspec.yaml +++ b/packages/path_provider/path_provider_windows/pubspec.yaml @@ -25,5 +25,5 @@ dev_dependencies: pedantic: ^1.10.0-nullsafety.3 environment: - sdk: '>=2.12.0-259.8.beta <3.0.0' + sdk: ">=2.12.0-0 <3.0.0" flutter: ">=1.12.13+hotfix.4" From e8b38f6e03d1fea2746669c6e654714eca582b6e Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Fri, 19 Feb 2021 11:13:29 -0800 Subject: [PATCH 0154/1565] [image_picker_for_web] Add doc comments to point out that some arguments aren't supported on the web (#3566) Re-landing a PR that @ditman messed up! https://github.com/flutter/plugins/pull/3566 Co-authored-by: Jens Becker Co-authored-by: Chris Yang --- .../image_picker_for_web/CHANGELOG.md | 4 ++++ .../image_picker_for_web/README.md | 8 ++++++- .../lib/image_picker_for_web.dart | 24 +++++++++++++++++++ .../image_picker_for_web/pubspec.yaml | 2 +- 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/CHANGELOG.md b/packages/image_picker/image_picker_for_web/CHANGELOG.md index 37b17b3eef26..fcc6c9980c29 100644 --- a/packages/image_picker/image_picker_for_web/CHANGELOG.md +++ b/packages/image_picker/image_picker_for_web/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.0.0-nullsafety.1 + +* Add doc comments to point out that some arguments aren't supported on the web. + # 2.0.0-nullsafety * Migrate to null safety. diff --git a/packages/image_picker/image_picker_for_web/README.md b/packages/image_picker/image_picker_for_web/README.md index 81452e290984..074053c9b956 100644 --- a/packages/image_picker/image_picker_for_web/README.md +++ b/packages/image_picker/image_picker_for_web/README.md @@ -2,7 +2,7 @@ A web implementation of [`image_picker`][1]. -## Browser Support +## Limitations on the web platform Since Web Browsers don't offer direct access to their users' file system, this plugin provides a `PickedFile` abstraction to make access access uniform @@ -42,6 +42,12 @@ In order to "take a photo", some mobile browsers offer a [`capture` attribute](h Each browser may implement `capture` any way they please, so it may (or may not) make a difference in your users' experience. +### pickImage() +The arguments `maxWidth`, `maxHeight` and `imageQuality` are not supported on the web. + +### pickVideo() +The argument `maxDuration` is not supported on the web. + ## Usage ### Import the package diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index 0c05980172aa..05afd2e54a4c 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -30,6 +30,18 @@ class ImagePickerPlugin extends ImagePickerPlatform { ImagePickerPlatform.instance = ImagePickerPlugin(); } + /// Returns a [PickedFile] with the image that was picked. + /// + /// The `source` argument controls where the image comes from. This can + /// be either [ImageSource.camera] or [ImageSource.gallery]. + /// + /// Note that the `maxWidth`, `maxHeight` and `imageQuality` arguments are not supported on the web. If any of these arguments is supplied, it'll be silently ignored by the web version of the plugin. + /// + /// Use `preferredCameraDevice` to specify the camera to use when the `source` is [ImageSource.camera]. + /// The `preferredCameraDevice` is ignored when `source` is [ImageSource.gallery]. It is also ignored if the chosen camera is not supported on the device. + /// Defaults to [CameraDevice.rear]. + /// + /// If no images were picked, the return value is null. @override Future pickImage({ required ImageSource source, @@ -42,6 +54,18 @@ class ImagePickerPlugin extends ImagePickerPlatform { return pickFile(accept: _kAcceptImageMimeType, capture: capture); } + /// Returns a [PickedFile] containing the video that was picked. + /// + /// The [source] argument controls where the video comes from. This can + /// be either [ImageSource.camera] or [ImageSource.gallery]. + /// + /// Note that the `maxDuration` argument is not supported on the web. If the argument is supplied, it'll be silently ignored by the web version of the plugin. + /// + /// Use `preferredCameraDevice` to specify the camera to use when the `source` is [ImageSource.camera]. + /// The `preferredCameraDevice` is ignored when `source` is [ImageSource.gallery]. It is also ignored if the chosen camera is not supported on the device. + /// Defaults to [CameraDevice.rear]. + /// + /// If no images were picked, the return value is null. @override Future pickVideo({ required ImageSource source, diff --git a/packages/image_picker/image_picker_for_web/pubspec.yaml b/packages/image_picker/image_picker_for_web/pubspec.yaml index c270cd597c87..adc636192c69 100644 --- a/packages/image_picker/image_picker_for_web/pubspec.yaml +++ b/packages/image_picker/image_picker_for_web/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker_for_web description: Web platform implementation of image_picker homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker_for_web -version: 2.0.0-nullsafety +version: 2.0.0-nullsafety.1 flutter: plugin: From 849f25818d67e4a2f43682e9d747f9e94f8ae584 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 19 Feb 2021 11:18:32 -0800 Subject: [PATCH 0155/1565] [google_maps_flutter] Migrate to NNBD (#3548) Migrates the full plugin to null safety. --- .../google_maps_flutter/CHANGELOG.md | 8 + .../google_map_inspector.dart | 1 + .../integration_test/google_maps_test.dart | 7 +- .../example/lib/animate_camera.dart | 22 +- .../example/lib/map_click.dart | 6 +- .../example/lib/map_coordinates.dart | 4 +- .../example/lib/map_ui.dart | 7 +- .../example/lib/marker_icons.dart | 26 +- .../example/lib/move_camera.dart | 22 +- .../example/lib/padding.dart | 10 +- .../example/lib/place_circle.dart | 60 ++-- .../example/lib/place_marker.dart | 130 ++++---- .../example/lib/place_polygon.dart | 96 +++--- .../example/lib/place_polyline.dart | 103 ++++--- .../example/lib/scrolling_map.dart | 50 ++-- .../example/lib/snapshot.dart | 6 +- .../example/lib/tile_overlay.dart | 16 +- .../google_maps_flutter/example/pubspec.yaml | 4 +- .../example/test_driver/integration_test.dart | 1 + .../lib/src/controller.dart | 111 +++---- .../lib/src/google_map.dart | 277 +++++++++-------- .../google_maps_flutter/pubspec.yaml | 16 +- .../test/android_google_map_test.dart | 2 +- .../test/circle_updates_test.dart | 68 ++--- .../test/fake_maps_controllers.dart | 196 +++++------- .../test/google_map_test.dart | 38 +-- .../test/map_creation_test.dart | 278 ++++++++++++++---- .../test/marker_updates_test.dart | 68 ++--- .../test/polygon_updates_test.dart | 118 ++++---- .../test/polyline_updates_test.dart | 78 ++--- .../test/tile_overlay_updates_test.dart | 62 ++-- script/nnbd_plugins.sh | 2 +- 32 files changed, 1003 insertions(+), 890 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index fd73ad6ca0eb..549aa4e06f3c 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,3 +1,11 @@ +## 2.0.0-nullsafety + +* Migrate to null-safety +* BREAKING CHANGE: Passing an unknown map object ID (e.g., MarkerId) to a + method, it will throw an `UnknownMapObjectIDError`. Previously it would + either silently do nothing, or throw an error trying to call a function on + `null`, depneding on the method. + ## 1.2.0 * Support custom tiles. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart index 0f2dafb80f70..a5025590d72a 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart @@ -1,6 +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. +// @dart=2.9 import 'dart:typed_data'; import 'package:flutter/services.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart index 557337f0c025..01b0c9b03e68 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart @@ -1,6 +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. +// @dart=2.9 import 'dart:async'; import 'dart:io'; @@ -954,10 +955,8 @@ void main() { final BitmapDescriptor scaled = await BitmapDescriptor.fromAssetImage( imageConfiguration, 'red_square.png', mipmaps: false); - // ignore: invalid_use_of_visible_for_testing_member - expect(mip.toJson()[2], 1); - // ignore: invalid_use_of_visible_for_testing_member - expect(scaled.toJson()[2], 2); + expect((mip.toJson() as List)[2], 1); + expect((scaled.toJson() as List)[2], 2); }); testWidgets('testTakeSnapshot', (WidgetTester tester) async { diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/animate_camera.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/animate_camera.dart index ae5e9f6cee3a..f6a2fecf5b0d 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/animate_camera.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/animate_camera.dart @@ -26,7 +26,7 @@ class AnimateCamera extends StatefulWidget { } class AnimateCameraState extends State { - GoogleMapController mapController; + GoogleMapController? mapController; void _onMapCreated(GoogleMapController controller) { mapController = controller; @@ -56,7 +56,7 @@ class AnimateCameraState extends State { children: [ TextButton( onPressed: () { - mapController.animateCamera( + mapController?.animateCamera( CameraUpdate.newCameraPosition( const CameraPosition( bearing: 270.0, @@ -71,7 +71,7 @@ class AnimateCameraState extends State { ), TextButton( onPressed: () { - mapController.animateCamera( + mapController?.animateCamera( CameraUpdate.newLatLng( const LatLng(56.1725505, 10.1850512), ), @@ -81,7 +81,7 @@ class AnimateCameraState extends State { ), TextButton( onPressed: () { - mapController.animateCamera( + mapController?.animateCamera( CameraUpdate.newLatLngBounds( LatLngBounds( southwest: const LatLng(-38.483935, 113.248673), @@ -95,7 +95,7 @@ class AnimateCameraState extends State { ), TextButton( onPressed: () { - mapController.animateCamera( + mapController?.animateCamera( CameraUpdate.newLatLngZoom( const LatLng(37.4231613, -122.087159), 11.0, @@ -106,7 +106,7 @@ class AnimateCameraState extends State { ), TextButton( onPressed: () { - mapController.animateCamera( + mapController?.animateCamera( CameraUpdate.scrollBy(150.0, -225.0), ); }, @@ -118,7 +118,7 @@ class AnimateCameraState extends State { children: [ TextButton( onPressed: () { - mapController.animateCamera( + mapController?.animateCamera( CameraUpdate.zoomBy( -0.5, const Offset(30.0, 20.0), @@ -129,7 +129,7 @@ class AnimateCameraState extends State { ), TextButton( onPressed: () { - mapController.animateCamera( + mapController?.animateCamera( CameraUpdate.zoomBy(-0.5), ); }, @@ -137,7 +137,7 @@ class AnimateCameraState extends State { ), TextButton( onPressed: () { - mapController.animateCamera( + mapController?.animateCamera( CameraUpdate.zoomIn(), ); }, @@ -145,7 +145,7 @@ class AnimateCameraState extends State { ), TextButton( onPressed: () { - mapController.animateCamera( + mapController?.animateCamera( CameraUpdate.zoomOut(), ); }, @@ -153,7 +153,7 @@ class AnimateCameraState extends State { ), TextButton( onPressed: () { - mapController.animateCamera( + mapController?.animateCamera( CameraUpdate.zoomTo(16.0), ); }, diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_click.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_click.dart index 029d3a1f187e..eaeb463e1b33 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_click.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_click.dart @@ -31,9 +31,9 @@ class _MapClickBody extends StatefulWidget { class _MapClickBodyState extends State<_MapClickBody> { _MapClickBodyState(); - GoogleMapController mapController; - LatLng _lastTap; - LatLng _lastLongPress; + GoogleMapController? mapController; + LatLng? _lastTap; + LatLng? _lastLongPress; @override Widget build(BuildContext context) { diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_coordinates.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_coordinates.dart index f194f8cb3f3b..20cccd6b61fd 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_coordinates.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_coordinates.dart @@ -31,7 +31,7 @@ class _MapCoordinatesBody extends StatefulWidget { class _MapCoordinatesBodyState extends State<_MapCoordinatesBody> { _MapCoordinatesBodyState(); - GoogleMapController mapController; + GoogleMapController? mapController; LatLngBounds _visibleRegion = LatLngBounds( southwest: const LatLng(0, 0), northeast: const LatLng(0, 0), @@ -87,7 +87,7 @@ class _MapCoordinatesBodyState extends State<_MapCoordinatesBody> { child: const Text('Get Visible Region Bounds'), onPressed: () async { final LatLngBounds visibleRegion = - await mapController.getVisibleRegion(); + await mapController!.getVisibleRegion(); setState(() { _visibleRegion = visibleRegion; }); diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_ui.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_ui.dart index 61a62ac0cf6d..edae82e4074c 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_ui.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_ui.dart @@ -56,7 +56,7 @@ class MapUiBodyState extends State { bool _myLocationEnabled = true; bool _myTrafficEnabled = false; bool _myLocationButtonEnabled = true; - GoogleMapController _controller; + late GoogleMapController _controller; bool _nightMode = false; @override @@ -249,10 +249,9 @@ class MapUiBodyState extends State { }); } + // Should only be called if _isMapCreated is true. Widget _nightModeToggler() { - if (!_isMapCreated) { - return null; - } + assert(_isMapCreated); return TextButton( child: Text('${_nightMode ? 'disable' : 'enable'} night mode'), onPressed: () { diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/marker_icons.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/marker_icons.dart index b62d898c3a3b..90404c347dd8 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/marker_icons.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/marker_icons.dart @@ -29,8 +29,8 @@ class MarkerIconsBody extends StatefulWidget { const LatLng _kMapCenter = LatLng(52.4478, -3.5402); class MarkerIconsBodyState extends State { - GoogleMapController controller; - BitmapDescriptor _markerIcon; + GoogleMapController? controller; + BitmapDescriptor? _markerIcon; @override Widget build(BuildContext context) { @@ -48,7 +48,7 @@ class MarkerIconsBodyState extends State { target: _kMapCenter, zoom: 7.0, ), - markers: _createMarker(), + markers: {_createMarker()}, onMapCreated: _onMapCreated, ), ), @@ -57,17 +57,19 @@ class MarkerIconsBodyState extends State { ); } - Set _createMarker() { - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - return [ - Marker( + Marker _createMarker() { + if (_markerIcon != null) { + return Marker( markerId: MarkerId("marker_1"), position: _kMapCenter, - icon: _markerIcon, - ), - ].toSet(); + icon: _markerIcon!, + ); + } else { + return Marker( + markerId: MarkerId("marker_1"), + position: _kMapCenter, + ); + } } Future _createMarkerImageFromAsset(BuildContext context) async { diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/move_camera.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/move_camera.dart index 262d362d8c3e..860b19e7925c 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/move_camera.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/move_camera.dart @@ -25,7 +25,7 @@ class MoveCamera extends StatefulWidget { } class MoveCameraState extends State { - GoogleMapController mapController; + GoogleMapController? mapController; void _onMapCreated(GoogleMapController controller) { mapController = controller; @@ -55,7 +55,7 @@ class MoveCameraState extends State { children: [ TextButton( onPressed: () { - mapController.moveCamera( + mapController?.moveCamera( CameraUpdate.newCameraPosition( const CameraPosition( bearing: 270.0, @@ -70,7 +70,7 @@ class MoveCameraState extends State { ), TextButton( onPressed: () { - mapController.moveCamera( + mapController?.moveCamera( CameraUpdate.newLatLng( const LatLng(56.1725505, 10.1850512), ), @@ -80,7 +80,7 @@ class MoveCameraState extends State { ), TextButton( onPressed: () { - mapController.moveCamera( + mapController?.moveCamera( CameraUpdate.newLatLngBounds( LatLngBounds( southwest: const LatLng(-38.483935, 113.248673), @@ -94,7 +94,7 @@ class MoveCameraState extends State { ), TextButton( onPressed: () { - mapController.moveCamera( + mapController?.moveCamera( CameraUpdate.newLatLngZoom( const LatLng(37.4231613, -122.087159), 11.0, @@ -105,7 +105,7 @@ class MoveCameraState extends State { ), TextButton( onPressed: () { - mapController.moveCamera( + mapController?.moveCamera( CameraUpdate.scrollBy(150.0, -225.0), ); }, @@ -117,7 +117,7 @@ class MoveCameraState extends State { children: [ TextButton( onPressed: () { - mapController.moveCamera( + mapController?.moveCamera( CameraUpdate.zoomBy( -0.5, const Offset(30.0, 20.0), @@ -128,7 +128,7 @@ class MoveCameraState extends State { ), TextButton( onPressed: () { - mapController.moveCamera( + mapController?.moveCamera( CameraUpdate.zoomBy(-0.5), ); }, @@ -136,7 +136,7 @@ class MoveCameraState extends State { ), TextButton( onPressed: () { - mapController.moveCamera( + mapController?.moveCamera( CameraUpdate.zoomIn(), ); }, @@ -144,7 +144,7 @@ class MoveCameraState extends State { ), TextButton( onPressed: () { - mapController.moveCamera( + mapController?.moveCamera( CameraUpdate.zoomOut(), ); }, @@ -152,7 +152,7 @@ class MoveCameraState extends State { ), TextButton( onPressed: () { - mapController.moveCamera( + mapController?.moveCamera( CameraUpdate.zoomTo(16.0), ); }, diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/padding.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/padding.dart index 934d4c647aa4..45b4a9e09e5c 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/padding.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/padding.dart @@ -27,7 +27,7 @@ class MarkerIconsBody extends StatefulWidget { const LatLng _kMapCenter = LatLng(52.4478, -3.5402); class MarkerIconsBodyState extends State { - GoogleMapController controller; + GoogleMapController? controller; EdgeInsets _padding = const EdgeInsets.all(0); @@ -152,10 +152,10 @@ class MarkerIconsBodyState extends State { onPressed: () { setState(() { _padding = EdgeInsets.fromLTRB( - double.tryParse(_leftController.value?.text) ?? 0, - double.tryParse(_topController.value?.text) ?? 0, - double.tryParse(_rightController.value?.text) ?? 0, - double.tryParse(_bottomController.value?.text) ?? 0); + double.tryParse(_leftController.value.text) ?? 0, + double.tryParse(_topController.value.text) ?? 0, + double.tryParse(_rightController.value.text) ?? 0, + double.tryParse(_bottomController.value.text) ?? 0); }); }, ), diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_circle.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_circle.dart index 7f0447e9a279..59d30e51ce8b 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_circle.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_circle.dart @@ -28,10 +28,10 @@ class PlaceCircleBody extends StatefulWidget { class PlaceCircleBodyState extends State { PlaceCircleBodyState(); - GoogleMapController controller; + GoogleMapController? controller; Map circles = {}; int _circleIdCounter = 1; - CircleId selectedCircle; + CircleId? selectedCircle; // Values when toggling circle color int fillColorsIndex = 0; @@ -62,12 +62,14 @@ class PlaceCircleBodyState extends State { }); } - void _remove() { + void _remove(CircleId circleId) { setState(() { - if (circles.containsKey(selectedCircle)) { - circles.remove(selectedCircle); + if (circles.containsKey(circleId)) { + circles.remove(circleId); + } + if (circleId == selectedCircle) { + selectedCircle = null; } - selectedCircle = null; }); } @@ -100,37 +102,37 @@ class PlaceCircleBodyState extends State { }); } - void _toggleVisible() { - final Circle circle = circles[selectedCircle]; + void _toggleVisible(CircleId circleId) { + final Circle circle = circles[circleId]!; setState(() { - circles[selectedCircle] = circle.copyWith( + circles[circleId] = circle.copyWith( visibleParam: !circle.visible, ); }); } - void _changeFillColor() { - final Circle circle = circles[selectedCircle]; + void _changeFillColor(CircleId circleId) { + final Circle circle = circles[circleId]!; setState(() { - circles[selectedCircle] = circle.copyWith( + circles[circleId] = circle.copyWith( fillColorParam: colors[++fillColorsIndex % colors.length], ); }); } - void _changeStrokeColor() { - final Circle circle = circles[selectedCircle]; + void _changeStrokeColor(CircleId circleId) { + final Circle circle = circles[circleId]!; setState(() { - circles[selectedCircle] = circle.copyWith( + circles[circleId] = circle.copyWith( strokeColorParam: colors[++strokeColorsIndex % colors.length], ); }); } - void _changeStrokeWidth() { - final Circle circle = circles[selectedCircle]; + void _changeStrokeWidth(CircleId circleId) { + final Circle circle = circles[circleId]!; setState(() { - circles[selectedCircle] = circle.copyWith( + circles[circleId] = circle.copyWith( strokeWidthParam: widths[++widthsIndex % widths.length], ); }); @@ -138,6 +140,7 @@ class PlaceCircleBodyState extends State { @override Widget build(BuildContext context) { + final CircleId? selectedId = selectedCircle; return Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.stretch, @@ -171,12 +174,15 @@ class PlaceCircleBodyState extends State { ), TextButton( child: const Text('remove'), - onPressed: (selectedCircle == null) ? null : _remove, + onPressed: (selectedId == null) + ? null + : () => _remove(selectedId), ), TextButton( child: const Text('toggle visible'), - onPressed: - (selectedCircle == null) ? null : _toggleVisible, + onPressed: (selectedId == null) + ? null + : () => _toggleVisible(selectedId), ), ], ), @@ -184,21 +190,21 @@ class PlaceCircleBodyState extends State { children: [ TextButton( child: const Text('change stroke width'), - onPressed: (selectedCircle == null) + onPressed: (selectedId == null) ? null - : _changeStrokeWidth, + : () => _changeStrokeWidth(selectedId), ), TextButton( child: const Text('change stroke color'), - onPressed: (selectedCircle == null) + onPressed: (selectedId == null) ? null - : _changeStrokeColor, + : () => _changeStrokeColor(selectedId), ), TextButton( child: const Text('change fill color'), - onPressed: (selectedCircle == null) + onPressed: (selectedId == null) ? null - : _changeFillColor, + : () => _changeFillColor(selectedId), ), ], ) diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart index 2c5439590443..576808c38a5e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart @@ -35,9 +35,9 @@ class PlaceMarkerBodyState extends State { PlaceMarkerBodyState(); static final LatLng center = const LatLng(-33.86711, 151.1947171); - GoogleMapController controller; + GoogleMapController? controller; Map markers = {}; - MarkerId selectedMarker; + MarkerId? selectedMarker; int _markerIdCounter = 1; void _onMapCreated(GoogleMapController controller) { @@ -50,13 +50,13 @@ class PlaceMarkerBodyState extends State { } void _onMarkerTapped(MarkerId markerId) { - final Marker tappedMarker = markers[markerId]; + final Marker? tappedMarker = markers[markerId]; if (tappedMarker != null) { setState(() { - if (markers.containsKey(selectedMarker)) { - final Marker resetOld = markers[selectedMarker] + if (markers.containsKey(markerId)) { + final Marker resetOld = markers[markerId]! .copyWith(iconParam: BitmapDescriptor.defaultMarker); - markers[selectedMarker] = resetOld; + markers[markerId] = resetOld; } selectedMarker = markerId; final Marker newMarker = tappedMarker.copyWith( @@ -70,7 +70,7 @@ class PlaceMarkerBodyState extends State { } void _onMarkerDragEnd(MarkerId markerId, LatLng newPosition) async { - final Marker tappedMarker = markers[markerId]; + final Marker? tappedMarker = markers[markerId]; if (tappedMarker != null) { await showDialog( context: context, @@ -126,23 +126,23 @@ class PlaceMarkerBodyState extends State { }); } - void _remove() { + void _remove(MarkerId markerId) { setState(() { - if (markers.containsKey(selectedMarker)) { - markers.remove(selectedMarker); + if (markers.containsKey(markerId)) { + markers.remove(markerId); } }); } - void _changePosition() { - final Marker marker = markers[selectedMarker]; + void _changePosition(MarkerId markerId) { + final Marker marker = markers[markerId]!; final LatLng current = marker.position; final Offset offset = Offset( center.latitude - current.latitude, center.longitude - current.longitude, ); setState(() { - markers[selectedMarker] = marker.copyWith( + markers[markerId] = marker.copyWith( positionParam: LatLng( center.latitude + offset.dy, center.longitude + offset.dx, @@ -151,23 +151,23 @@ class PlaceMarkerBodyState extends State { }); } - void _changeAnchor() { - final Marker marker = markers[selectedMarker]; + void _changeAnchor(MarkerId markerId) { + final Marker marker = markers[markerId]!; final Offset currentAnchor = marker.anchor; final Offset newAnchor = Offset(1.0 - currentAnchor.dy, currentAnchor.dx); setState(() { - markers[selectedMarker] = marker.copyWith( + markers[markerId] = marker.copyWith( anchorParam: newAnchor, ); }); } - Future _changeInfoAnchor() async { - final Marker marker = markers[selectedMarker]; + Future _changeInfoAnchor(MarkerId markerId) async { + final Marker marker = markers[markerId]!; final Offset currentAnchor = marker.infoWindow.anchor; final Offset newAnchor = Offset(1.0 - currentAnchor.dy, currentAnchor.dx); setState(() { - markers[selectedMarker] = marker.copyWith( + markers[markerId] = marker.copyWith( infoWindowParam: marker.infoWindow.copyWith( anchorParam: newAnchor, ), @@ -175,29 +175,29 @@ class PlaceMarkerBodyState extends State { }); } - Future _toggleDraggable() async { - final Marker marker = markers[selectedMarker]; + Future _toggleDraggable(MarkerId markerId) async { + final Marker marker = markers[markerId]!; setState(() { - markers[selectedMarker] = marker.copyWith( + markers[markerId] = marker.copyWith( draggableParam: !marker.draggable, ); }); } - Future _toggleFlat() async { - final Marker marker = markers[selectedMarker]; + Future _toggleFlat(MarkerId markerId) async { + final Marker marker = markers[markerId]!; setState(() { - markers[selectedMarker] = marker.copyWith( + markers[markerId] = marker.copyWith( flatParam: !marker.flat, ); }); } - Future _changeInfo() async { - final Marker marker = markers[selectedMarker]; - final String newSnippet = marker.infoWindow.snippet + '*'; + Future _changeInfo(MarkerId markerId) async { + final Marker marker = markers[markerId]!; + final String newSnippet = marker.infoWindow.snippet! + '*'; setState(() { - markers[selectedMarker] = marker.copyWith( + markers[markerId] = marker.copyWith( infoWindowParam: marker.infoWindow.copyWith( snippetParam: newSnippet, ), @@ -205,40 +205,40 @@ class PlaceMarkerBodyState extends State { }); } - Future _changeAlpha() async { - final Marker marker = markers[selectedMarker]; + Future _changeAlpha(MarkerId markerId) async { + final Marker marker = markers[markerId]!; final double current = marker.alpha; setState(() { - markers[selectedMarker] = marker.copyWith( + markers[markerId] = marker.copyWith( alphaParam: current < 0.1 ? 1.0 : current * 0.75, ); }); } - Future _changeRotation() async { - final Marker marker = markers[selectedMarker]; + Future _changeRotation(MarkerId markerId) async { + final Marker marker = markers[markerId]!; final double current = marker.rotation; setState(() { - markers[selectedMarker] = marker.copyWith( + markers[markerId] = marker.copyWith( rotationParam: current == 330.0 ? 0.0 : current + 30.0, ); }); } - Future _toggleVisible() async { - final Marker marker = markers[selectedMarker]; + Future _toggleVisible(MarkerId markerId) async { + final Marker marker = markers[markerId]!; setState(() { - markers[selectedMarker] = marker.copyWith( + markers[markerId] = marker.copyWith( visibleParam: !marker.visible, ); }); } - Future _changeZIndex() async { - final Marker marker = markers[selectedMarker]; + Future _changeZIndex(MarkerId markerId) async { + final Marker marker = markers[markerId]!; final double current = marker.zIndex; setState(() { - markers[selectedMarker] = marker.copyWith( + markers[markerId] = marker.copyWith( zIndexParam: current == 12.0 ? 0.0 : current + 1.0, ); }); @@ -283,6 +283,7 @@ class PlaceMarkerBodyState extends State { @override Widget build(BuildContext context) { + final MarkerId? selectedId = selectedMarker; return Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.stretch, @@ -297,9 +298,6 @@ class PlaceMarkerBodyState extends State { target: LatLng(-33.852, 151.211), zoom: 11.0, ), - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals markers: Set.of(markers.values), ), ), @@ -319,15 +317,21 @@ class PlaceMarkerBodyState extends State { ), TextButton( child: const Text('remove'), - onPressed: _remove, + onPressed: selectedId == null + ? null + : () => _remove(selectedId), ), TextButton( child: const Text('change info'), - onPressed: _changeInfo, + onPressed: selectedId == null + ? null + : () => _changeInfo(selectedId), ), TextButton( child: const Text('change info anchor'), - onPressed: _changeInfoAnchor, + onPressed: selectedId == null + ? null + : () => _changeInfoAnchor(selectedId), ), ], ), @@ -335,35 +339,51 @@ class PlaceMarkerBodyState extends State { children: [ TextButton( child: const Text('change alpha'), - onPressed: _changeAlpha, + onPressed: selectedId == null + ? null + : () => _changeAlpha(selectedId), ), TextButton( child: const Text('change anchor'), - onPressed: _changeAnchor, + onPressed: selectedId == null + ? null + : () => _changeAnchor(selectedId), ), TextButton( child: const Text('toggle draggable'), - onPressed: _toggleDraggable, + onPressed: selectedId == null + ? null + : () => _toggleDraggable(selectedId), ), TextButton( child: const Text('toggle flat'), - onPressed: _toggleFlat, + onPressed: selectedId == null + ? null + : () => _toggleFlat(selectedId), ), TextButton( child: const Text('change position'), - onPressed: _changePosition, + onPressed: selectedId == null + ? null + : () => _changePosition(selectedId), ), TextButton( child: const Text('change rotation'), - onPressed: _changeRotation, + onPressed: selectedId == null + ? null + : () => _changeRotation(selectedId), ), TextButton( child: const Text('toggle visible'), - onPressed: _toggleVisible, + onPressed: selectedId == null + ? null + : () => _toggleVisible(selectedId), ), TextButton( child: const Text('change zIndex'), - onPressed: _changeZIndex, + onPressed: selectedId == null + ? null + : () => _changeZIndex(selectedId), ), // A breaking change to the ImageStreamListener API affects this sample. // I've updates the sample to use the new API, but as we cannot use the new diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart index 5f2a0985b1b9..8ee58420f508 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart @@ -28,11 +28,11 @@ class PlacePolygonBody extends StatefulWidget { class PlacePolygonBodyState extends State { PlacePolygonBodyState(); - GoogleMapController controller; + GoogleMapController? controller; Map polygons = {}; Map polygonOffsets = {}; int _polygonIdCounter = 0; - PolygonId selectedPolygon; + PolygonId? selectedPolygon; // Values when toggling polygon color int strokeColorsIndex = 0; @@ -63,10 +63,10 @@ class PlacePolygonBodyState extends State { }); } - void _remove() { + void _remove(PolygonId polygonId) { setState(() { - if (polygons.containsKey(selectedPolygon)) { - polygons.remove(selectedPolygon); + if (polygons.containsKey(polygonId)) { + polygons.remove(polygonId); } selectedPolygon = null; }); @@ -102,62 +102,63 @@ class PlacePolygonBodyState extends State { }); } - void _toggleGeodesic() { - final Polygon polygon = polygons[selectedPolygon]; + void _toggleGeodesic(PolygonId polygonId) { + final Polygon polygon = polygons[polygonId]!; setState(() { - polygons[selectedPolygon] = polygon.copyWith( + polygons[polygonId] = polygon.copyWith( geodesicParam: !polygon.geodesic, ); }); } - void _toggleVisible() { - final Polygon polygon = polygons[selectedPolygon]; + void _toggleVisible(PolygonId polygonId) { + final Polygon polygon = polygons[polygonId]!; setState(() { - polygons[selectedPolygon] = polygon.copyWith( + polygons[polygonId] = polygon.copyWith( visibleParam: !polygon.visible, ); }); } - void _changeStrokeColor() { - final Polygon polygon = polygons[selectedPolygon]; + void _changeStrokeColor(PolygonId polygonId) { + final Polygon polygon = polygons[polygonId]!; setState(() { - polygons[selectedPolygon] = polygon.copyWith( + polygons[polygonId] = polygon.copyWith( strokeColorParam: colors[++strokeColorsIndex % colors.length], ); }); } - void _changeFillColor() { - final Polygon polygon = polygons[selectedPolygon]; + void _changeFillColor(PolygonId polygonId) { + final Polygon polygon = polygons[polygonId]!; setState(() { - polygons[selectedPolygon] = polygon.copyWith( + polygons[polygonId] = polygon.copyWith( fillColorParam: colors[++fillColorsIndex % colors.length], ); }); } - void _changeWidth() { - final Polygon polygon = polygons[selectedPolygon]; + void _changeWidth(PolygonId polygonId) { + final Polygon polygon = polygons[polygonId]!; setState(() { - polygons[selectedPolygon] = polygon.copyWith( + polygons[polygonId] = polygon.copyWith( strokeWidthParam: widths[++widthsIndex % widths.length], ); }); } - void _addHoles() { - final Polygon polygon = polygons[selectedPolygon]; + void _addHoles(PolygonId polygonId) { + final Polygon polygon = polygons[polygonId]!; setState(() { - polygons[selectedPolygon] = polygon.copyWith(holesParam: _createHoles()); + polygons[polygonId] = + polygon.copyWith(holesParam: _createHoles(polygonId)); }); } - void _removeHoles() { - final Polygon polygon = polygons[selectedPolygon]; + void _removeHoles(PolygonId polygonId) { + final Polygon polygon = polygons[polygonId]!; setState(() { - polygons[selectedPolygon] = polygon.copyWith( + polygons[polygonId] = polygon.copyWith( holesParam: >[], ); }); @@ -165,6 +166,7 @@ class PlacePolygonBodyState extends State { @override Widget build(BuildContext context) { + final PolygonId? selectedId = selectedPolygon; return Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.stretch, @@ -198,18 +200,21 @@ class PlacePolygonBodyState extends State { ), TextButton( child: const Text('remove'), - onPressed: (selectedPolygon == null) ? null : _remove, + onPressed: (selectedId == null) + ? null + : () => _remove(selectedId), ), TextButton( child: const Text('toggle visible'), - onPressed: - (selectedPolygon == null) ? null : _toggleVisible, + onPressed: (selectedId == null) + ? null + : () => _toggleVisible(selectedId), ), TextButton( child: const Text('toggle geodesic'), - onPressed: (selectedPolygon == null) + onPressed: (selectedId == null) ? null - : _toggleGeodesic, + : () => _toggleGeodesic(selectedId), ), ], ), @@ -217,36 +222,37 @@ class PlacePolygonBodyState extends State { children: [ TextButton( child: const Text('add holes'), - onPressed: (selectedPolygon == null) + onPressed: (selectedId == null) ? null - : ((polygons[selectedPolygon].holes.isNotEmpty) + : ((polygons[selectedId]!.holes.isNotEmpty) ? null - : _addHoles), + : () => _addHoles(selectedId)), ), TextButton( child: const Text('remove holes'), - onPressed: (selectedPolygon == null) + onPressed: (selectedId == null) ? null - : ((polygons[selectedPolygon].holes.isEmpty) + : ((polygons[selectedId]!.holes.isEmpty) ? null - : _removeHoles), + : () => _removeHoles(selectedId)), ), TextButton( child: const Text('change stroke width'), - onPressed: - (selectedPolygon == null) ? null : _changeWidth, + onPressed: (selectedId == null) + ? null + : () => _changeWidth(selectedId), ), TextButton( child: const Text('change stroke color'), - onPressed: (selectedPolygon == null) + onPressed: (selectedId == null) ? null - : _changeStrokeColor, + : () => _changeStrokeColor(selectedId), ), TextButton( child: const Text('change fill color'), - onPressed: (selectedPolygon == null) + onPressed: (selectedId == null) ? null - : _changeFillColor, + : () => _changeFillColor(selectedId), ), ], ) @@ -270,9 +276,9 @@ class PlacePolygonBodyState extends State { return points; } - List> _createHoles() { + List> _createHoles(PolygonId polygonId) { final List> holes = >[]; - final double offset = polygonOffsets[selectedPolygon]; + final double offset = polygonOffsets[polygonId]!; final List hole1 = []; hole1.add(_createLatLng(51.8395 + offset, -3.8814)); diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart index fe22603853bc..c66343d78f00 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart @@ -29,10 +29,10 @@ class PlacePolylineBody extends StatefulWidget { class PlacePolylineBodyState extends State { PlacePolylineBodyState(); - GoogleMapController controller; + GoogleMapController? controller; Map polylines = {}; int _polylineIdCounter = 0; - PolylineId selectedPolyline; + PolylineId? selectedPolyline; // Values when toggling polyline color int colorsIndex = 0; @@ -91,10 +91,10 @@ class PlacePolylineBodyState extends State { }); } - void _remove() { + void _remove(PolylineId polylineId) { setState(() { - if (polylines.containsKey(selectedPolyline)) { - polylines.remove(selectedPolyline); + if (polylines.containsKey(polylineId)) { + polylines.remove(polylineId); } selectedPolyline = null; }); @@ -127,73 +127,73 @@ class PlacePolylineBodyState extends State { }); } - void _toggleGeodesic() { - final Polyline polyline = polylines[selectedPolyline]; + void _toggleGeodesic(PolylineId polylineId) { + final Polyline polyline = polylines[polylineId]!; setState(() { - polylines[selectedPolyline] = polyline.copyWith( + polylines[polylineId] = polyline.copyWith( geodesicParam: !polyline.geodesic, ); }); } - void _toggleVisible() { - final Polyline polyline = polylines[selectedPolyline]; + void _toggleVisible(PolylineId polylineId) { + final Polyline polyline = polylines[polylineId]!; setState(() { - polylines[selectedPolyline] = polyline.copyWith( + polylines[polylineId] = polyline.copyWith( visibleParam: !polyline.visible, ); }); } - void _changeColor() { - final Polyline polyline = polylines[selectedPolyline]; + void _changeColor(PolylineId polylineId) { + final Polyline polyline = polylines[polylineId]!; setState(() { - polylines[selectedPolyline] = polyline.copyWith( + polylines[polylineId] = polyline.copyWith( colorParam: colors[++colorsIndex % colors.length], ); }); } - void _changeWidth() { - final Polyline polyline = polylines[selectedPolyline]; + void _changeWidth(PolylineId polylineId) { + final Polyline polyline = polylines[polylineId]!; setState(() { - polylines[selectedPolyline] = polyline.copyWith( + polylines[polylineId] = polyline.copyWith( widthParam: widths[++widthsIndex % widths.length], ); }); } - void _changeJointType() { - final Polyline polyline = polylines[selectedPolyline]; + void _changeJointType(PolylineId polylineId) { + final Polyline polyline = polylines[polylineId]!; setState(() { - polylines[selectedPolyline] = polyline.copyWith( + polylines[polylineId] = polyline.copyWith( jointTypeParam: jointTypes[++jointTypesIndex % jointTypes.length], ); }); } - void _changeEndCap() { - final Polyline polyline = polylines[selectedPolyline]; + void _changeEndCap(PolylineId polylineId) { + final Polyline polyline = polylines[polylineId]!; setState(() { - polylines[selectedPolyline] = polyline.copyWith( + polylines[polylineId] = polyline.copyWith( endCapParam: endCaps[++endCapsIndex % endCaps.length], ); }); } - void _changeStartCap() { - final Polyline polyline = polylines[selectedPolyline]; + void _changeStartCap(PolylineId polylineId) { + final Polyline polyline = polylines[polylineId]!; setState(() { - polylines[selectedPolyline] = polyline.copyWith( + polylines[polylineId] = polyline.copyWith( startCapParam: startCaps[++startCapsIndex % startCaps.length], ); }); } - void _changePattern() { - final Polyline polyline = polylines[selectedPolyline]; + void _changePattern(PolylineId polylineId) { + final Polyline polyline = polylines[polylineId]!; setState(() { - polylines[selectedPolyline] = polyline.copyWith( + polylines[polylineId] = polyline.copyWith( patternsParam: patterns[++patternsIndex % patterns.length], ); }); @@ -201,9 +201,9 @@ class PlacePolylineBodyState extends State { @override Widget build(BuildContext context) { - final bool iOSorNotSelected = - (!kIsWeb && defaultTargetPlatform == TargetPlatform.iOS) || - (selectedPolyline == null); + final bool isIOS = !kIsWeb && defaultTargetPlatform == TargetPlatform.iOS; + + final PolylineId? selectedId = selectedPolyline; return Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, @@ -238,20 +238,21 @@ class PlacePolylineBodyState extends State { ), TextButton( child: const Text('remove'), - onPressed: - (selectedPolyline == null) ? null : _remove, + onPressed: (selectedId == null) + ? null + : () => _remove(selectedId), ), TextButton( child: const Text('toggle visible'), - onPressed: (selectedPolyline == null) + onPressed: (selectedId == null) ? null - : _toggleVisible, + : () => _toggleVisible(selectedId), ), TextButton( child: const Text('toggle geodesic'), - onPressed: (selectedPolyline == null) + onPressed: (selectedId == null) ? null - : _toggleGeodesic, + : () => _toggleGeodesic(selectedId), ), ], ), @@ -259,29 +260,39 @@ class PlacePolylineBodyState extends State { children: [ TextButton( child: const Text('change width'), - onPressed: - (selectedPolyline == null) ? null : _changeWidth, + onPressed: (selectedId == null) + ? null + : () => _changeWidth(selectedId), ), TextButton( child: const Text('change color'), - onPressed: - (selectedPolyline == null) ? null : _changeColor, + onPressed: (selectedId == null) + ? null + : () => _changeColor(selectedId), ), TextButton( child: const Text('change start cap [Android only]'), - onPressed: iOSorNotSelected ? null : _changeStartCap, + onPressed: isIOS || (selectedId == null) + ? null + : () => _changeStartCap(selectedId), ), TextButton( child: const Text('change end cap [Android only]'), - onPressed: iOSorNotSelected ? null : _changeEndCap, + onPressed: isIOS || (selectedId == null) + ? null + : () => _changeEndCap(selectedId), ), TextButton( child: const Text('change joint type [Android only]'), - onPressed: iOSorNotSelected ? null : _changeJointType, + onPressed: isIOS || (selectedId == null) + ? null + : () => _changeJointType(selectedId), ), TextButton( child: const Text('change pattern [Android only]'), - onPressed: iOSorNotSelected ? null : _changePattern, + onPressed: isIOS || (selectedId == null) + ? null + : () => _changePattern(selectedId), ), ], ) diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/scrolling_map.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/scrolling_map.dart index 2aa1243fd27c..b7d88bc46a58 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/scrolling_map.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/scrolling_map.dart @@ -48,15 +48,12 @@ class ScrollingMapBody extends StatelessWidget { target: center, zoom: 11.0, ), - gestureRecognizers: - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - >[ + gestureRecognizers: // + >{ Factory( () => EagerGestureRecognizer(), ), - ].toSet(), + }, ), ), ), @@ -84,34 +81,25 @@ class ScrollingMapBody extends StatelessWidget { target: center, zoom: 11.0, ), - markers: - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - Set.of( - [ - Marker( - markerId: MarkerId("test_marker_id"), - position: LatLng( - center.latitude, - center.longitude, - ), - infoWindow: const InfoWindow( - title: 'An interesting location', - snippet: '*', - ), - ) - ], - ), - gestureRecognizers: - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - >[ + markers: { + Marker( + markerId: MarkerId("test_marker_id"), + position: LatLng( + center.latitude, + center.longitude, + ), + infoWindow: const InfoWindow( + title: 'An interesting location', + snippet: '*', + ), + ), + }, + gestureRecognizers: < + Factory>{ Factory( () => ScaleGestureRecognizer(), ), - ].toSet(), + }, ), ), ), diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/snapshot.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/snapshot.dart index f470a4f9783e..3ba12bfac3f2 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/snapshot.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/snapshot.dart @@ -30,8 +30,8 @@ class _SnapshotBody extends StatefulWidget { } class _SnapshotBodyState extends State<_SnapshotBody> { - GoogleMapController _mapController; - Uint8List _imageBytes; + GoogleMapController? _mapController; + Uint8List? _imageBytes; @override Widget build(BuildContext context) { @@ -59,7 +59,7 @@ class _SnapshotBodyState extends State<_SnapshotBody> { Container( decoration: BoxDecoration(color: Colors.blueGrey[50]), height: 180, - child: _imageBytes != null ? Image.memory(_imageBytes) : null, + child: _imageBytes != null ? Image.memory(_imageBytes!) : null, ), ], ), diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart index 354fa06a7ab7..8ae3b3bca979 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart @@ -31,8 +31,8 @@ class TileOverlayBody extends StatefulWidget { class TileOverlayBodyState extends State { TileOverlayBodyState(); - GoogleMapController controller; - TileOverlay _tileOverlay; + GoogleMapController? controller; + TileOverlay? _tileOverlay; void _onMapCreated(GoogleMapController controller) { this.controller = controller; @@ -61,12 +61,15 @@ class TileOverlayBodyState extends State { void _clearTileCache() { if (_tileOverlay != null && controller != null) { - controller.clearTileCache(_tileOverlay.tileOverlayId); + controller!.clearTileCache(_tileOverlay!.tileOverlayId); } } @override Widget build(BuildContext context) { + Set overlays = { + if (_tileOverlay != null) _tileOverlay, + }; return Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.spaceEvenly, @@ -81,8 +84,7 @@ class TileOverlayBodyState extends State { target: LatLng(59.935460, 30.325177), zoom: 7.0, ), - tileOverlays: - _tileOverlay != null ? {_tileOverlay} : null, + tileOverlays: overlays as Set, onMapCreated: _onMapCreated, ), ), @@ -121,7 +123,7 @@ class _DebugTileProvider implements TileProvider { ); @override - Future getTile(int x, int y, int zoom) async { + Future getTile(int x, int y, int? zoom) async { final ui.PictureRecorder recorder = ui.PictureRecorder(); final Canvas canvas = Canvas(recorder); final TextSpan textSpan = TextSpan( @@ -145,7 +147,7 @@ class _DebugTileProvider implements TileProvider { .toImage(width, height) .then((ui.Image image) => image.toByteData(format: ui.ImageByteFormat.png)) - .then((ByteData byteData) => byteData.buffer.asUint8List()); + .then((ByteData? byteData) => byteData!.buffer.asUint8List()); return Tile(width, height, byteData); } } diff --git a/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml index b3a0ae75daad..181550d32877 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml @@ -2,7 +2,7 @@ name: google_maps_flutter_example description: Demonstrates how to use the google_maps_flutter plugin. environment: - sdk: ">=2.2.0 <3.0.0" + sdk: '>=2.12.0-0 <3.0.0' flutter: ">=1.22.0" dependencies: @@ -19,7 +19,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - flutter_plugin_android_lifecycle: ^1.0.0 + flutter_plugin_android_lifecycle: ^2.0.0-nullsafety.2 dev_dependencies: flutter_driver: diff --git a/packages/google_maps_flutter/google_maps_flutter/example/test_driver/integration_test.dart b/packages/google_maps_flutter/google_maps_flutter/example/test_driver/integration_test.dart index 7a2c21338786..ceb6c4d6a3a0 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/test_driver/integration_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/test_driver/integration_test.dart @@ -1,6 +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. +// @dart=2.9 import 'dart:async'; import 'dart:convert'; diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart index 3967179b0e50..9b61ec002ff9 100644 --- a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart @@ -4,9 +4,6 @@ part of google_maps_flutter; -final GoogleMapsFlutterPlatform _googleMapsFlutterPlatform = - GoogleMapsFlutterPlatform.instance; - /// Controller for a single GoogleMap instance running on the host platform. class GoogleMapController { /// The mapId for this controller @@ -15,8 +12,8 @@ class GoogleMapController { GoogleMapController._( CameraPosition initialCameraPosition, this._googleMapState, { - @required this.mapId, - }) : assert(_googleMapsFlutterPlatform != null) { + required this.mapId, + }) { _connectStreams(mapId); } @@ -30,7 +27,7 @@ class GoogleMapController { _GoogleMapState googleMapState, ) async { assert(id != null); - await _googleMapsFlutterPlatform.init(id); + await GoogleMapsFlutterPlatform.instance.init(id); return GoogleMapController._( initialCameraPosition, googleMapState, @@ -43,9 +40,10 @@ class GoogleMapController { /// Accessible only for testing. // TODO(dit) https://github.com/flutter/flutter/issues/55504 Remove this getter. @visibleForTesting - MethodChannel get channel { - if (_googleMapsFlutterPlatform is MethodChannelGoogleMapsFlutter) { - return (_googleMapsFlutterPlatform as MethodChannelGoogleMapsFlutter) + MethodChannel? get channel { + if (GoogleMapsFlutterPlatform.instance is MethodChannelGoogleMapsFlutter) { + return (GoogleMapsFlutterPlatform.instance + as MethodChannelGoogleMapsFlutter) .channel(mapId); } return null; @@ -55,40 +53,40 @@ class GoogleMapController { void _connectStreams(int mapId) { if (_googleMapState.widget.onCameraMoveStarted != null) { - _googleMapsFlutterPlatform + GoogleMapsFlutterPlatform.instance .onCameraMoveStarted(mapId: mapId) - .listen((_) => _googleMapState.widget.onCameraMoveStarted()); + .listen((_) => _googleMapState.widget.onCameraMoveStarted!()); } if (_googleMapState.widget.onCameraMove != null) { - _googleMapsFlutterPlatform.onCameraMove(mapId: mapId).listen( - (CameraMoveEvent e) => _googleMapState.widget.onCameraMove(e.value)); + GoogleMapsFlutterPlatform.instance.onCameraMove(mapId: mapId).listen( + (CameraMoveEvent e) => _googleMapState.widget.onCameraMove!(e.value)); } if (_googleMapState.widget.onCameraIdle != null) { - _googleMapsFlutterPlatform + GoogleMapsFlutterPlatform.instance .onCameraIdle(mapId: mapId) - .listen((_) => _googleMapState.widget.onCameraIdle()); + .listen((_) => _googleMapState.widget.onCameraIdle!()); } - _googleMapsFlutterPlatform + GoogleMapsFlutterPlatform.instance .onMarkerTap(mapId: mapId) .listen((MarkerTapEvent e) => _googleMapState.onMarkerTap(e.value)); - _googleMapsFlutterPlatform.onMarkerDragEnd(mapId: mapId).listen( + GoogleMapsFlutterPlatform.instance.onMarkerDragEnd(mapId: mapId).listen( (MarkerDragEndEvent e) => _googleMapState.onMarkerDragEnd(e.value, e.position)); - _googleMapsFlutterPlatform.onInfoWindowTap(mapId: mapId).listen( + GoogleMapsFlutterPlatform.instance.onInfoWindowTap(mapId: mapId).listen( (InfoWindowTapEvent e) => _googleMapState.onInfoWindowTap(e.value)); - _googleMapsFlutterPlatform + GoogleMapsFlutterPlatform.instance .onPolylineTap(mapId: mapId) .listen((PolylineTapEvent e) => _googleMapState.onPolylineTap(e.value)); - _googleMapsFlutterPlatform + GoogleMapsFlutterPlatform.instance .onPolygonTap(mapId: mapId) .listen((PolygonTapEvent e) => _googleMapState.onPolygonTap(e.value)); - _googleMapsFlutterPlatform + GoogleMapsFlutterPlatform.instance .onCircleTap(mapId: mapId) .listen((CircleTapEvent e) => _googleMapState.onCircleTap(e.value)); - _googleMapsFlutterPlatform + GoogleMapsFlutterPlatform.instance .onTap(mapId: mapId) .listen((MapTapEvent e) => _googleMapState.onTap(e.position)); - _googleMapsFlutterPlatform.onLongPress(mapId: mapId).listen( + GoogleMapsFlutterPlatform.instance.onLongPress(mapId: mapId).listen( (MapLongPressEvent e) => _googleMapState.onLongPress(e.position)); } @@ -100,8 +98,8 @@ class GoogleMapController { /// The returned [Future] completes after listeners have been notified. Future _updateMapOptions(Map optionsUpdate) { assert(optionsUpdate != null); - return _googleMapsFlutterPlatform.updateMapOptions(optionsUpdate, - mapId: mapId); + return GoogleMapsFlutterPlatform.instance + .updateMapOptions(optionsUpdate, mapId: mapId); } /// Updates marker configuration. @@ -112,8 +110,8 @@ class GoogleMapController { /// The returned [Future] completes after listeners have been notified. Future _updateMarkers(MarkerUpdates markerUpdates) { assert(markerUpdates != null); - return _googleMapsFlutterPlatform.updateMarkers(markerUpdates, - mapId: mapId); + return GoogleMapsFlutterPlatform.instance + .updateMarkers(markerUpdates, mapId: mapId); } /// Updates polygon configuration. @@ -124,8 +122,8 @@ class GoogleMapController { /// The returned [Future] completes after listeners have been notified. Future _updatePolygons(PolygonUpdates polygonUpdates) { assert(polygonUpdates != null); - return _googleMapsFlutterPlatform.updatePolygons(polygonUpdates, - mapId: mapId); + return GoogleMapsFlutterPlatform.instance + .updatePolygons(polygonUpdates, mapId: mapId); } /// Updates polyline configuration. @@ -136,8 +134,8 @@ class GoogleMapController { /// The returned [Future] completes after listeners have been notified. Future _updatePolylines(PolylineUpdates polylineUpdates) { assert(polylineUpdates != null); - return _googleMapsFlutterPlatform.updatePolylines(polylineUpdates, - mapId: mapId); + return GoogleMapsFlutterPlatform.instance + .updatePolylines(polylineUpdates, mapId: mapId); } /// Updates circle configuration. @@ -148,8 +146,8 @@ class GoogleMapController { /// The returned [Future] completes after listeners have been notified. Future _updateCircles(CircleUpdates circleUpdates) { assert(circleUpdates != null); - return _googleMapsFlutterPlatform.updateCircles(circleUpdates, - mapId: mapId); + return GoogleMapsFlutterPlatform.instance + .updateCircles(circleUpdates, mapId: mapId); } /// Updates tile overlays configuration. @@ -159,8 +157,8 @@ class GoogleMapController { /// /// The returned [Future] completes after listeners have been notified. Future _updateTileOverlays(Set newTileOverlays) { - return _googleMapsFlutterPlatform.updateTileOverlays( - newTileOverlays: newTileOverlays, mapId: mapId); + return GoogleMapsFlutterPlatform.instance + .updateTileOverlays(newTileOverlays: newTileOverlays, mapId: mapId); } /// Clears the tile cache so that all tiles will be requested again from the @@ -172,8 +170,8 @@ class GoogleMapController { /// should implement an on-disk cache. Future clearTileCache(TileOverlayId tileOverlayId) async { assert(tileOverlayId != null); - return _googleMapsFlutterPlatform.clearTileCache(tileOverlayId, - mapId: mapId); + return GoogleMapsFlutterPlatform.instance + .clearTileCache(tileOverlayId, mapId: mapId); } /// Starts an animated change of the map camera position. @@ -181,7 +179,8 @@ class GoogleMapController { /// The returned [Future] completes after the change has been started on the /// platform side. Future animateCamera(CameraUpdate cameraUpdate) { - return _googleMapsFlutterPlatform.animateCamera(cameraUpdate, mapId: mapId); + return GoogleMapsFlutterPlatform.instance + .animateCamera(cameraUpdate, mapId: mapId); } /// Changes the map camera position. @@ -189,7 +188,8 @@ class GoogleMapController { /// The returned [Future] completes after the change has been made on the /// platform side. Future moveCamera(CameraUpdate cameraUpdate) { - return _googleMapsFlutterPlatform.moveCamera(cameraUpdate, mapId: mapId); + return GoogleMapsFlutterPlatform.instance + .moveCamera(cameraUpdate, mapId: mapId); } /// Sets the styling of the base map. @@ -205,13 +205,14 @@ class GoogleMapController { /// Also, refer [iOS](https://developers.google.com/maps/documentation/ios-sdk/style-reference) /// and [Android](https://developers.google.com/maps/documentation/android-sdk/style-reference) /// style reference for more information regarding the supported styles. - Future setMapStyle(String mapStyle) { - return _googleMapsFlutterPlatform.setMapStyle(mapStyle, mapId: mapId); + Future setMapStyle(String? mapStyle) { + return GoogleMapsFlutterPlatform.instance + .setMapStyle(mapStyle, mapId: mapId); } /// Return [LatLngBounds] defining the region that is visible in a map. Future getVisibleRegion() { - return _googleMapsFlutterPlatform.getVisibleRegion(mapId: mapId); + return GoogleMapsFlutterPlatform.instance.getVisibleRegion(mapId: mapId); } /// Return [ScreenCoordinate] of the [LatLng] in the current map view. @@ -220,7 +221,8 @@ class GoogleMapController { /// Screen location is in screen pixels (not display pixels) with respect to the top left corner /// of the map, not necessarily of the whole screen. Future getScreenCoordinate(LatLng latLng) { - return _googleMapsFlutterPlatform.getScreenCoordinate(latLng, mapId: mapId); + return GoogleMapsFlutterPlatform.instance + .getScreenCoordinate(latLng, mapId: mapId); } /// Returns [LatLng] corresponding to the [ScreenCoordinate] in the current map view. @@ -228,7 +230,8 @@ class GoogleMapController { /// Returned [LatLng] corresponds to a screen location. The screen location is specified in screen /// pixels (not display pixels) relative to the top left of the map, not top left of the whole screen. Future getLatLng(ScreenCoordinate screenCoordinate) { - return _googleMapsFlutterPlatform.getLatLng(screenCoordinate, mapId: mapId); + return GoogleMapsFlutterPlatform.instance + .getLatLng(screenCoordinate, mapId: mapId); } /// Programmatically show the Info Window for a [Marker]. @@ -241,8 +244,8 @@ class GoogleMapController { /// * [isMarkerInfoWindowShown] to check if the Info Window is showing. Future showMarkerInfoWindow(MarkerId markerId) { assert(markerId != null); - return _googleMapsFlutterPlatform.showMarkerInfoWindow(markerId, - mapId: mapId); + return GoogleMapsFlutterPlatform.instance + .showMarkerInfoWindow(markerId, mapId: mapId); } /// Programmatically hide the Info Window for a [Marker]. @@ -255,8 +258,8 @@ class GoogleMapController { /// * [isMarkerInfoWindowShown] to check if the Info Window is showing. Future hideMarkerInfoWindow(MarkerId markerId) { assert(markerId != null); - return _googleMapsFlutterPlatform.hideMarkerInfoWindow(markerId, - mapId: mapId); + return GoogleMapsFlutterPlatform.instance + .hideMarkerInfoWindow(markerId, mapId: mapId); } /// Returns `true` when the [InfoWindow] is showing, `false` otherwise. @@ -269,22 +272,22 @@ class GoogleMapController { /// * [hideMarkerInfoWindow] to hide the Info Window. Future isMarkerInfoWindowShown(MarkerId markerId) { assert(markerId != null); - return _googleMapsFlutterPlatform.isMarkerInfoWindowShown(markerId, - mapId: mapId); + return GoogleMapsFlutterPlatform.instance + .isMarkerInfoWindowShown(markerId, mapId: mapId); } /// Returns the current zoom level of the map Future getZoomLevel() { - return _googleMapsFlutterPlatform.getZoomLevel(mapId: mapId); + return GoogleMapsFlutterPlatform.instance.getZoomLevel(mapId: mapId); } /// Returns the image bytes of the map - Future takeSnapshot() { - return _googleMapsFlutterPlatform.takeSnapshot(mapId: mapId); + Future takeSnapshot() { + return GoogleMapsFlutterPlatform.instance.takeSnapshot(mapId: mapId); } /// Disposes of the platform resources void dispose() { - _googleMapsFlutterPlatform.dispose(mapId: mapId); + GoogleMapsFlutterPlatform.instance.dispose(mapId: mapId); } } diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart index e7f5e32d61b9..deac00658d6b 100644 --- a/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart +++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart @@ -14,7 +14,29 @@ typedef void MapCreatedCallback(GoogleMapController controller); // to the buildView function, so the web implementation can use it as a // cache key. This needs to be provided from the outside, because web // views seem to re-render much more often that mobile platform views. -int _webOnlyMapId = 0; +int _nextMapCreationId = 0; + +/// Error thrown when an unknown map object ID is provided to a method. +class UnknownMapObjectIdError extends Error { + /// Creates an assertion error with the provided [message]. + UnknownMapObjectIdError(this.objectType, this.objectId, [this.context]); + + /// The name of the map object whose ID is unknown. + final String objectType; + + /// The unknown maps object ID. + final MapsObjectId objectId; + + /// The context where the error occurred. + final String? context; + + String toString() { + if (context != null) { + return 'Unknown $objectType ID "${objectId.value}" in $context'; + } + return 'Unknown $objectType ID "${objectId.value}"'; + } +} /// A widget which displays a map with data obtained from the Google Maps service. class GoogleMap extends StatefulWidget { @@ -22,10 +44,10 @@ class GoogleMap extends StatefulWidget { /// /// [AssertionError] will be thrown if [initialCameraPosition] is null; const GoogleMap({ - Key key, - @required this.initialCameraPosition, + Key? key, + required this.initialCameraPosition, this.onMapCreated, - this.gestureRecognizers, + this.gestureRecognizers = const >{}, this.compassEnabled = true, this.mapToolbarEnabled = true, this.cameraTargetBounds = CameraTargetBounds.unbounded, @@ -45,12 +67,12 @@ class GoogleMap extends StatefulWidget { this.indoorViewEnabled = false, this.trafficEnabled = false, this.buildingsEnabled = true, - this.markers, - this.polygons, - this.polylines, - this.circles, + this.markers = const {}, + this.polygons = const {}, + this.polylines = const {}, + this.circles = const {}, this.onCameraMoveStarted, - this.tileOverlays, + this.tileOverlays = const {}, this.onCameraMove, this.onCameraIdle, this.onTap, @@ -61,7 +83,7 @@ class GoogleMap extends StatefulWidget { /// Callback method for when the map is ready to be used. /// /// Used to receive a [GoogleMapController] for this [GoogleMap]. - final MapCreatedCallback onMapCreated; + final MapCreatedCallback? onMapCreated; /// The initial position of the map's camera. final CameraPosition initialCameraPosition; @@ -132,24 +154,24 @@ class GoogleMap extends StatefulWidget { /// 2. Programmatically initiated animation. /// 3. Camera motion initiated in response to user gestures on the map. /// For example: pan, tilt, pinch to zoom, or rotate. - final VoidCallback onCameraMoveStarted; + final VoidCallback? onCameraMoveStarted; /// Called repeatedly as the camera continues to move after an /// onCameraMoveStarted call. /// /// This may be called as often as once every frame and should /// not perform expensive operations. - final CameraPositionCallback onCameraMove; + final CameraPositionCallback? onCameraMove; /// Called when camera movement has ended, there are no pending /// animations and the user has stopped interacting with the map. - final VoidCallback onCameraIdle; + final VoidCallback? onCameraIdle; /// Called every time a [GoogleMap] is tapped. - final ArgumentCallback onTap; + final ArgumentCallback? onTap; /// Called every time a [GoogleMap] is long pressed. - final ArgumentCallback onLongPress; + final ArgumentCallback? onLongPress; /// True if a "My Location" layer should be shown on the map. /// @@ -205,7 +227,7 @@ class GoogleMap extends StatefulWidget { /// vertical drags. The map will claim gestures that are recognized by any of the /// recognizers on this list. /// - /// When this set is empty or null, the map will only handle pointer events for gestures that + /// When this set is empty, the map will only handle pointer events for gestures that /// were not claimed by any other gesture recognizer. final Set> gestureRecognizers; @@ -215,7 +237,7 @@ class GoogleMap extends StatefulWidget { } class _GoogleMapState extends State { - final _webOnlyMapCreationId = _webOnlyMapId++; + final _mapId = _nextMapCreationId++; final Completer _controller = Completer(); @@ -224,25 +246,20 @@ class _GoogleMapState extends State { Map _polygons = {}; Map _polylines = {}; Map _circles = {}; - _GoogleMapOptions _googleMapOptions; + late _GoogleMapOptions _googleMapOptions; @override Widget build(BuildContext context) { - final Map creationParams = { - 'initialCameraPosition': widget.initialCameraPosition?.toMap(), - 'options': _googleMapOptions.toMap(), - 'markersToAdd': serializeMarkerSet(widget.markers), - 'polygonsToAdd': serializePolygonSet(widget.polygons), - 'polylinesToAdd': serializePolylineSet(widget.polylines), - 'circlesToAdd': serializeCircleSet(widget.circles), - '_webOnlyMapCreationId': _webOnlyMapCreationId, - 'tileOverlaysToAdd': serializeTileOverlaySet(widget.tileOverlays), - }; - - return _googleMapsFlutterPlatform.buildView( - creationParams, - widget.gestureRecognizers, + return GoogleMapsFlutterPlatform.instance.buildView( + _mapId, onPlatformViewCreated, + initialCameraPosition: widget.initialCameraPosition, + markers: widget.markers, + polygons: widget.polygons, + polylines: widget.polylines, + circles: widget.circles, + gestureRecognizers: widget.gestureRecognizers, + mapOptions: _googleMapOptions.toMap(), ); } @@ -333,116 +350,123 @@ class _GoogleMapState extends State { ); _controller.complete(controller); _updateTileOverlays(); - if (widget.onMapCreated != null) { - widget.onMapCreated(controller); + final MapCreatedCallback? onMapCreated = widget.onMapCreated; + if (onMapCreated != null) { + onMapCreated(controller); } } void onMarkerTap(MarkerId markerId) { assert(markerId != null); - if (_markers[markerId]?.onTap != null) { - _markers[markerId].onTap(); + final Marker? marker = _markers[markerId]; + if (marker == null) { + throw UnknownMapObjectIdError('marker', markerId, 'onTap'); + } + final VoidCallback? onTap = marker.onTap; + if (onTap != null) { + onTap(); } } void onMarkerDragEnd(MarkerId markerId, LatLng position) { assert(markerId != null); - if (_markers[markerId]?.onDragEnd != null) { - _markers[markerId].onDragEnd(position); + final Marker? marker = _markers[markerId]; + if (marker == null) { + throw UnknownMapObjectIdError('marker', markerId, 'onDragEnd'); + } + final ValueChanged? onDragEnd = marker.onDragEnd; + if (onDragEnd != null) { + onDragEnd(position); } } void onPolygonTap(PolygonId polygonId) { assert(polygonId != null); - _polygons[polygonId].onTap(); + final Polygon? polygon = _polygons[polygonId]; + if (polygon == null) { + throw UnknownMapObjectIdError('polygon', polygonId, 'onTap'); + } + final VoidCallback? onTap = polygon.onTap; + if (onTap != null) { + onTap(); + } } void onPolylineTap(PolylineId polylineId) { assert(polylineId != null); - if (_polylines[polylineId]?.onTap != null) { - _polylines[polylineId].onTap(); + final Polyline? polyline = _polylines[polylineId]; + if (polyline == null) { + throw UnknownMapObjectIdError('polyline', polylineId, 'onTap'); + } + final VoidCallback? onTap = polyline.onTap; + if (onTap != null) { + onTap(); } } void onCircleTap(CircleId circleId) { assert(circleId != null); - _circles[circleId].onTap(); + final Circle? circle = _circles[circleId]; + if (circle == null) { + throw UnknownMapObjectIdError('marker', circleId, 'onTap'); + } + final VoidCallback? onTap = circle.onTap; + if (onTap != null) { + onTap(); + } } void onInfoWindowTap(MarkerId markerId) { assert(markerId != null); - if (_markers[markerId]?.infoWindow?.onTap != null) { - _markers[markerId].infoWindow.onTap(); + final Marker? marker = _markers[markerId]; + if (marker == null) { + throw UnknownMapObjectIdError('marker', markerId, 'InfoWindow onTap'); + } + final VoidCallback? onTap = marker.infoWindow.onTap; + if (onTap != null) { + onTap(); } } void onTap(LatLng position) { assert(position != null); - if (widget.onTap != null) { - widget.onTap(position); + final ArgumentCallback? onTap = widget.onTap; + if (onTap != null) { + onTap(position); } } void onLongPress(LatLng position) { assert(position != null); - if (widget.onLongPress != null) { - widget.onLongPress(position); + final ArgumentCallback? onLongPress = widget.onLongPress; + if (onLongPress != null) { + onLongPress(position); } } } /// Configuration options for the GoogleMaps user interface. -/// -/// When used to change configuration, null values will be interpreted as -/// "do not change this configuration option". class _GoogleMapOptions { - _GoogleMapOptions({ - this.compassEnabled, - this.mapToolbarEnabled, - this.cameraTargetBounds, - this.mapType, - this.minMaxZoomPreference, - this.rotateGesturesEnabled, - this.scrollGesturesEnabled, - this.tiltGesturesEnabled, - this.trackCameraPosition, - this.zoomControlsEnabled, - this.zoomGesturesEnabled, - this.liteModeEnabled, - this.myLocationEnabled, - this.myLocationButtonEnabled, - this.padding, - this.indoorViewEnabled, - this.trafficEnabled, - this.buildingsEnabled, - }) { - assert(liteModeEnabled == null || - !liteModeEnabled || - (liteModeEnabled && Platform.isAndroid)); - } - - static _GoogleMapOptions fromWidget(GoogleMap map) { - return _GoogleMapOptions( - compassEnabled: map.compassEnabled, - mapToolbarEnabled: map.mapToolbarEnabled, - cameraTargetBounds: map.cameraTargetBounds, - mapType: map.mapType, - minMaxZoomPreference: map.minMaxZoomPreference, - rotateGesturesEnabled: map.rotateGesturesEnabled, - scrollGesturesEnabled: map.scrollGesturesEnabled, - tiltGesturesEnabled: map.tiltGesturesEnabled, - trackCameraPosition: map.onCameraMove != null, - zoomControlsEnabled: map.zoomControlsEnabled, - zoomGesturesEnabled: map.zoomGesturesEnabled, - liteModeEnabled: map.liteModeEnabled, - myLocationEnabled: map.myLocationEnabled, - myLocationButtonEnabled: map.myLocationButtonEnabled, - padding: map.padding, - indoorViewEnabled: map.indoorViewEnabled, - trafficEnabled: map.trafficEnabled, - buildingsEnabled: map.buildingsEnabled, - ); - } + _GoogleMapOptions.fromWidget(GoogleMap map) + : compassEnabled = map.compassEnabled, + mapToolbarEnabled = map.mapToolbarEnabled, + cameraTargetBounds = map.cameraTargetBounds, + mapType = map.mapType, + minMaxZoomPreference = map.minMaxZoomPreference, + rotateGesturesEnabled = map.rotateGesturesEnabled, + scrollGesturesEnabled = map.scrollGesturesEnabled, + tiltGesturesEnabled = map.tiltGesturesEnabled, + trackCameraPosition = map.onCameraMove != null, + zoomControlsEnabled = map.zoomControlsEnabled, + zoomGesturesEnabled = map.zoomGesturesEnabled, + liteModeEnabled = map.liteModeEnabled, + myLocationEnabled = map.myLocationEnabled, + myLocationButtonEnabled = map.myLocationButtonEnabled, + padding = map.padding, + indoorViewEnabled = map.indoorViewEnabled, + trafficEnabled = map.trafficEnabled, + buildingsEnabled = map.buildingsEnabled, + assert(!map.liteModeEnabled || Platform.isAndroid); final bool compassEnabled; @@ -481,38 +505,31 @@ class _GoogleMapOptions { final bool buildingsEnabled; Map toMap() { - final Map optionsMap = {}; - - void addIfNonNull(String fieldName, dynamic value) { - if (value != null) { - optionsMap[fieldName] = value; - } - } - - addIfNonNull('compassEnabled', compassEnabled); - addIfNonNull('mapToolbarEnabled', mapToolbarEnabled); - addIfNonNull('cameraTargetBounds', cameraTargetBounds?.toJson()); - addIfNonNull('mapType', mapType?.index); - addIfNonNull('minMaxZoomPreference', minMaxZoomPreference?.toJson()); - addIfNonNull('rotateGesturesEnabled', rotateGesturesEnabled); - addIfNonNull('scrollGesturesEnabled', scrollGesturesEnabled); - addIfNonNull('tiltGesturesEnabled', tiltGesturesEnabled); - addIfNonNull('zoomControlsEnabled', zoomControlsEnabled); - addIfNonNull('zoomGesturesEnabled', zoomGesturesEnabled); - addIfNonNull('liteModeEnabled', liteModeEnabled); - addIfNonNull('trackCameraPosition', trackCameraPosition); - addIfNonNull('myLocationEnabled', myLocationEnabled); - addIfNonNull('myLocationButtonEnabled', myLocationButtonEnabled); - addIfNonNull('padding', [ - padding?.top, - padding?.left, - padding?.bottom, - padding?.right, - ]); - addIfNonNull('indoorEnabled', indoorViewEnabled); - addIfNonNull('trafficEnabled', trafficEnabled); - addIfNonNull('buildingsEnabled', buildingsEnabled); - return optionsMap; + return { + 'compassEnabled': compassEnabled, + 'mapToolbarEnabled': mapToolbarEnabled, + 'cameraTargetBounds': cameraTargetBounds.toJson(), + 'mapType': mapType.index, + 'minMaxZoomPreference': minMaxZoomPreference.toJson(), + 'rotateGesturesEnabled': rotateGesturesEnabled, + 'scrollGesturesEnabled': scrollGesturesEnabled, + 'tiltGesturesEnabled': tiltGesturesEnabled, + 'zoomControlsEnabled': zoomControlsEnabled, + 'zoomGesturesEnabled': zoomGesturesEnabled, + 'liteModeEnabled': liteModeEnabled, + 'trackCameraPosition': trackCameraPosition, + 'myLocationEnabled': myLocationEnabled, + 'myLocationButtonEnabled': myLocationButtonEnabled, + 'padding': [ + padding.top, + padding.left, + padding.bottom, + padding.right, + ], + 'indoorEnabled': indoorViewEnabled, + 'trafficEnabled': trafficEnabled, + 'buildingsEnabled': buildingsEnabled, + }; } Map updatesMap(_GoogleMapOptions newOptions) { diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index 20bd56ab57da..8e9ab62d5f38 100644 --- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml @@ -1,13 +1,13 @@ name: google_maps_flutter description: A Flutter plugin for integrating Google Maps in iOS and Android applications. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter -version: 1.2.0 +version: 2.0.0-nullsafety dependencies: flutter: sdk: flutter - flutter_plugin_android_lifecycle: ^1.0.0 - google_maps_flutter_platform_interface: ^1.2.0 + flutter_plugin_android_lifecycle: ^2.0.0-nullsafety.2 + google_maps_flutter_platform_interface: ^2.0.0-nullsafety.1 dev_dependencies: flutter_test: @@ -17,10 +17,10 @@ dev_dependencies: # https://github.com/dart-lang/pub/issues/2101 is resolved. flutter_driver: sdk: flutter - test: ^1.6.0 - pedantic: ^1.8.0 - plugin_platform_interface: ^1.0.2 - mockito: ^4.1.1 + test: ^1.16.0-nullsafety.17 + pedantic: ^1.10.0-nullsafety.3 + plugin_platform_interface: ^1.1.0-nullsafety.2 + stream_transform: ^2.0.0-nullsafety.0 flutter: plugin: @@ -32,5 +32,5 @@ flutter: pluginClass: FLTGoogleMapsPlugin environment: - sdk: ">=2.1.0 <3.0.0" + sdk: '>=2.12.0-0 <3.0.0' flutter: ">=1.22.0" diff --git a/packages/google_maps_flutter/google_maps_flutter/test/android_google_map_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/android_google_map_test.dart index 194efe9a66f0..2399b7b15eff 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/android_google_map_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/android_google_map_test.dart @@ -37,7 +37,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.liteModeEnabled, false); diff --git a/packages/google_maps_flutter/google_maps_flutter/test/circle_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/circle_updates_test.dart index 3533ceb229e3..d61526b2bbeb 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/circle_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/circle_updates_test.dart @@ -9,20 +9,6 @@ import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'fake_maps_controllers.dart'; -Set _toSet({Circle c1, Circle c2, Circle c3}) { - final Set res = Set.identity(); - if (c1 != null) { - res.add(c1); - } - if (c2 != null) { - res.add(c2); - } - if (c3 != null) { - res.add(c3); - } - return res; -} - Widget _mapWithCircles(Set circles) { return Directionality( textDirection: TextDirection.ltr, @@ -50,10 +36,10 @@ void main() { testWidgets('Initializing a circle', (WidgetTester tester) async { final Circle c1 = Circle(circleId: CircleId("circle_1")); - await tester.pumpWidget(_mapWithCircles(_toSet(c1: c1))); + await tester.pumpWidget(_mapWithCircles({c1})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.circlesToAdd.length, 1); final Circle initializedCircle = platformGoogleMap.circlesToAdd.first; @@ -66,11 +52,11 @@ void main() { final Circle c1 = Circle(circleId: CircleId("circle_1")); final Circle c2 = Circle(circleId: CircleId("circle_2")); - await tester.pumpWidget(_mapWithCircles(_toSet(c1: c1))); - await tester.pumpWidget(_mapWithCircles(_toSet(c1: c1, c2: c2))); + await tester.pumpWidget(_mapWithCircles({c1})); + await tester.pumpWidget(_mapWithCircles({c1, c2})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.circlesToAdd.length, 1); final Circle addedCircle = platformGoogleMap.circlesToAdd.first; @@ -84,11 +70,11 @@ void main() { testWidgets("Removing a circle", (WidgetTester tester) async { final Circle c1 = Circle(circleId: CircleId("circle_1")); - await tester.pumpWidget(_mapWithCircles(_toSet(c1: c1))); - await tester.pumpWidget(_mapWithCircles(null)); + await tester.pumpWidget(_mapWithCircles({c1})); + await tester.pumpWidget(_mapWithCircles({})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.circleIdsToRemove.length, 1); expect(platformGoogleMap.circleIdsToRemove.first, equals(c1.circleId)); @@ -100,11 +86,11 @@ void main() { final Circle c1 = Circle(circleId: CircleId("circle_1")); final Circle c2 = Circle(circleId: CircleId("circle_1"), radius: 10); - await tester.pumpWidget(_mapWithCircles(_toSet(c1: c1))); - await tester.pumpWidget(_mapWithCircles(_toSet(c1: c2))); + await tester.pumpWidget(_mapWithCircles({c1})); + await tester.pumpWidget(_mapWithCircles({c2})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.circlesToChange.length, 1); expect(platformGoogleMap.circlesToChange.first, equals(c2)); @@ -116,11 +102,11 @@ void main() { final Circle c1 = Circle(circleId: CircleId("circle_1")); final Circle c2 = Circle(circleId: CircleId("circle_1"), radius: 10); - await tester.pumpWidget(_mapWithCircles(_toSet(c1: c1))); - await tester.pumpWidget(_mapWithCircles(_toSet(c1: c2))); + await tester.pumpWidget(_mapWithCircles({c1})); + await tester.pumpWidget(_mapWithCircles({c2})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.circlesToChange.length, 1); final Circle update = platformGoogleMap.circlesToChange.first; @@ -131,16 +117,16 @@ void main() { testWidgets("Multi Update", (WidgetTester tester) async { Circle c1 = Circle(circleId: CircleId("circle_1")); Circle c2 = Circle(circleId: CircleId("circle_2")); - final Set prev = _toSet(c1: c1, c2: c2); + final Set prev = {c1, c2}; c1 = Circle(circleId: CircleId("circle_1"), visible: false); c2 = Circle(circleId: CircleId("circle_2"), radius: 10); - final Set cur = _toSet(c1: c1, c2: c2); + final Set cur = {c1, c2}; await tester.pumpWidget(_mapWithCircles(prev)); await tester.pumpWidget(_mapWithCircles(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.circlesToChange, cur); expect(platformGoogleMap.circleIdsToRemove.isEmpty, true); @@ -150,18 +136,18 @@ void main() { testWidgets("Multi Update", (WidgetTester tester) async { Circle c2 = Circle(circleId: CircleId("circle_2")); final Circle c3 = Circle(circleId: CircleId("circle_3")); - final Set prev = _toSet(c2: c2, c3: c3); + final Set prev = {c2, c3}; // c1 is added, c2 is updated, c3 is removed. final Circle c1 = Circle(circleId: CircleId("circle_1")); c2 = Circle(circleId: CircleId("circle_2"), radius: 10); - final Set cur = _toSet(c1: c1, c2: c2); + final Set cur = {c1, c2}; await tester.pumpWidget(_mapWithCircles(prev)); await tester.pumpWidget(_mapWithCircles(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.circlesToChange.length, 1); expect(platformGoogleMap.circlesToAdd.length, 1); @@ -176,32 +162,32 @@ void main() { final Circle c1 = Circle(circleId: CircleId("circle_1")); final Circle c2 = Circle(circleId: CircleId("circle_2")); Circle c3 = Circle(circleId: CircleId("circle_3")); - final Set prev = _toSet(c1: c1, c2: c2, c3: c3); + final Set prev = {c1, c2, c3}; c3 = Circle(circleId: CircleId("circle_3"), radius: 10); - final Set cur = _toSet(c1: c1, c2: c2, c3: c3); + final Set cur = {c1, c2, c3}; await tester.pumpWidget(_mapWithCircles(prev)); await tester.pumpWidget(_mapWithCircles(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; - expect(platformGoogleMap.circlesToChange, _toSet(c3: c3)); + expect(platformGoogleMap.circlesToChange, {c3}); expect(platformGoogleMap.circleIdsToRemove.isEmpty, true); expect(platformGoogleMap.circlesToAdd.isEmpty, true); }); testWidgets("Update non platform related attr", (WidgetTester tester) async { Circle c1 = Circle(circleId: CircleId("circle_1")); - final Set prev = _toSet(c1: c1); + final Set prev = {c1}; c1 = Circle(circleId: CircleId("circle_1"), onTap: () => print("hello")); - final Set cur = _toSet(c1: c1); + final Set cur = {c1}; await tester.pumpWidget(_mapWithCircles(prev)); await tester.pumpWidget(_mapWithCircles(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.circlesToChange.isEmpty, true); expect(platformGoogleMap.circleIdsToRemove.isEmpty, true); diff --git a/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart b/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart index d72ac2ebe656..8bc0fbb1d86e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart @@ -9,10 +9,11 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; class FakePlatformGoogleMap { - FakePlatformGoogleMap(int id, Map params) { - cameraPosition = CameraPosition.fromMap(params['initialCameraPosition']); - channel = MethodChannel( - 'plugins.flutter.io/google_maps_$id', const StandardMethodCodec()); + FakePlatformGoogleMap(int id, Map params) + : cameraPosition = + CameraPosition.fromMap(params['initialCameraPosition']), + channel = MethodChannel( + 'plugins.flutter.io/google_maps_$id', const StandardMethodCodec()) { channel.setMockMethodCallHandler(onMethodCall); updateOptions(params['options']); updateMarkers(params); @@ -24,71 +25,71 @@ class FakePlatformGoogleMap { MethodChannel channel; - CameraPosition cameraPosition; + CameraPosition? cameraPosition; - bool compassEnabled; + bool? compassEnabled; - bool mapToolbarEnabled; + bool? mapToolbarEnabled; - CameraTargetBounds cameraTargetBounds; + CameraTargetBounds? cameraTargetBounds; - MapType mapType; + MapType? mapType; - MinMaxZoomPreference minMaxZoomPreference; + MinMaxZoomPreference? minMaxZoomPreference; - bool rotateGesturesEnabled; + bool? rotateGesturesEnabled; - bool scrollGesturesEnabled; + bool? scrollGesturesEnabled; - bool tiltGesturesEnabled; + bool? tiltGesturesEnabled; - bool zoomGesturesEnabled; + bool? zoomGesturesEnabled; - bool zoomControlsEnabled; + bool? zoomControlsEnabled; - bool liteModeEnabled; + bool? liteModeEnabled; - bool trackCameraPosition; + bool? trackCameraPosition; - bool myLocationEnabled; + bool? myLocationEnabled; - bool trafficEnabled; + bool? trafficEnabled; - bool buildingsEnabled; + bool? buildingsEnabled; - bool myLocationButtonEnabled; + bool? myLocationButtonEnabled; - List padding; + List? padding; - Set markerIdsToRemove; + Set markerIdsToRemove = {}; - Set markersToAdd; + Set markersToAdd = {}; - Set markersToChange; + Set markersToChange = {}; - Set polygonIdsToRemove; + Set polygonIdsToRemove = {}; - Set polygonsToAdd; + Set polygonsToAdd = {}; - Set polygonsToChange; + Set polygonsToChange = {}; - Set polylineIdsToRemove; + Set polylineIdsToRemove = {}; - Set polylinesToAdd; + Set polylinesToAdd = {}; - Set polylinesToChange; + Set polylinesToChange = {}; - Set circleIdsToRemove; + Set circleIdsToRemove = {}; - Set circlesToAdd; + Set circlesToAdd = {}; - Set circlesToChange; + Set circlesToChange = {}; - Set tileOverlayIdsToRemove; + Set tileOverlayIdsToRemove = {}; - Set tileOverlaysToAdd; + Set tileOverlaysToAdd = {}; - Set tileOverlaysToChange; + Set tileOverlaysToChange = {}; Future onMethodCall(MethodCall call) { switch (call.method) { @@ -116,7 +117,7 @@ class FakePlatformGoogleMap { } } - void updateMarkers(Map markerUpdates) { + void updateMarkers(Map? markerUpdates) { if (markerUpdates == null) { return; } @@ -126,29 +127,21 @@ class FakePlatformGoogleMap { markersToChange = _deserializeMarkers(markerUpdates['markersToChange']); } - Set _deserializeMarkerIds(List markerIds) { + Set _deserializeMarkerIds(List? markerIds) { if (markerIds == null) { - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - return Set(); + return {}; } return markerIds.map((dynamic markerId) => MarkerId(markerId)).toSet(); } Set _deserializeMarkers(dynamic markers) { if (markers == null) { - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - return Set(); + return {}; } final List markersData = markers; - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - final Set result = Set(); - for (Map markerData in markersData) { + final Set result = {}; + for (Map markerData + in markersData.cast>()) { final String markerId = markerData['markerId']; final double alpha = markerData['alpha']; final bool draggable = markerData['draggable']; @@ -176,7 +169,7 @@ class FakePlatformGoogleMap { return result; } - void updatePolygons(Map polygonUpdates) { + void updatePolygons(Map? polygonUpdates) { if (polygonUpdates == null) { return; } @@ -186,29 +179,21 @@ class FakePlatformGoogleMap { polygonsToChange = _deserializePolygons(polygonUpdates['polygonsToChange']); } - Set _deserializePolygonIds(List polygonIds) { + Set _deserializePolygonIds(List? polygonIds) { if (polygonIds == null) { - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - return Set(); + return {}; } return polygonIds.map((dynamic polygonId) => PolygonId(polygonId)).toSet(); } Set _deserializePolygons(dynamic polygons) { if (polygons == null) { - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - return Set(); + return {}; } final List polygonsData = polygons; - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - final Set result = Set(); - for (Map polygonData in polygonsData) { + final Set result = {}; + for (Map polygonData + in polygonsData.cast>()) { final String polygonId = polygonData['polygonId']; final bool visible = polygonData['visible']; final bool geodesic = polygonData['geodesic']; @@ -241,7 +226,7 @@ class FakePlatformGoogleMap { }).toList(); } - void updatePolylines(Map polylineUpdates) { + void updatePolylines(Map? polylineUpdates) { if (polylineUpdates == null) { return; } @@ -252,12 +237,9 @@ class FakePlatformGoogleMap { _deserializePolylines(polylineUpdates['polylinesToChange']); } - Set _deserializePolylineIds(List polylineIds) { + Set _deserializePolylineIds(List? polylineIds) { if (polylineIds == null) { - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - return Set(); + return {}; } return polylineIds .map((dynamic polylineId) => PolylineId(polylineId)) @@ -266,17 +248,12 @@ class FakePlatformGoogleMap { Set _deserializePolylines(dynamic polylines) { if (polylines == null) { - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - return Set(); + return {}; } final List polylinesData = polylines; - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - final Set result = Set(); - for (Map polylineData in polylinesData) { + final Set result = {}; + for (Map polylineData + in polylinesData.cast>()) { final String polylineId = polylineData['polylineId']; final bool visible = polylineData['visible']; final bool geodesic = polylineData['geodesic']; @@ -293,7 +270,7 @@ class FakePlatformGoogleMap { return result; } - void updateCircles(Map circleUpdates) { + void updateCircles(Map? circleUpdates) { if (circleUpdates == null) { return; } @@ -307,17 +284,17 @@ class FakePlatformGoogleMap { if (updateTileOverlayUpdates == null) { return; } - final List> tileOverlaysToAddList = + final List>? tileOverlaysToAddList = updateTileOverlayUpdates['tileOverlaysToAdd'] != null ? List.castFrom>( updateTileOverlayUpdates['tileOverlaysToAdd']) : null; - final List tileOverlayIdsToRemoveList = + final List? tileOverlayIdsToRemoveList = updateTileOverlayUpdates['tileOverlayIdsToRemove'] != null ? List.castFrom( updateTileOverlayUpdates['tileOverlayIdsToRemove']) : null; - final List> tileOverlaysToChangeList = + final List>? tileOverlaysToChangeList = updateTileOverlayUpdates['tileOverlaysToChange'] != null ? List.castFrom>( updateTileOverlayUpdates['tileOverlaysToChange']) @@ -328,29 +305,21 @@ class FakePlatformGoogleMap { tileOverlaysToChange = _deserializeTileOverlays(tileOverlaysToChangeList); } - Set _deserializeCircleIds(List circleIds) { + Set _deserializeCircleIds(List? circleIds) { if (circleIds == null) { - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - return Set(); + return {}; } return circleIds.map((dynamic circleId) => CircleId(circleId)).toSet(); } Set _deserializeCircles(dynamic circles) { if (circles == null) { - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - return Set(); + return {}; } final List circlesData = circles; - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - final Set result = Set(); - for (Map circleData in circlesData) { + final Set result = {}; + for (Map circleData + in circlesData.cast>()) { final String circleId = circleData['circleId']; final bool visible = circleData['visible']; final double radius = circleData['radius']; @@ -365,12 +334,9 @@ class FakePlatformGoogleMap { return result; } - Set _deserializeTileOverlayIds(List tileOverlayIds) { + Set _deserializeTileOverlayIds(List? tileOverlayIds) { if (tileOverlayIds == null || tileOverlayIds.isEmpty) { - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - return Set(); + return {}; } return tileOverlayIds .map((String tileOverlayId) => TileOverlayId(tileOverlayId)) @@ -378,17 +344,11 @@ class FakePlatformGoogleMap { } Set _deserializeTileOverlays( - List> tileOverlays) { + List>? tileOverlays) { if (tileOverlays == null || tileOverlays.isEmpty) { - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - return Set(); - } - // TODO(iskakaushik): Remove this when collection literals makes it to stable. - // https://github.com/flutter/flutter/issues/28312 - // ignore: prefer_collection_literals - final Set result = Set(); + return {}; + } + final Set result = {}; for (Map tileOverlayData in tileOverlays) { final String tileOverlayId = tileOverlayData['tileOverlayId']; final bool fadeIn = tileOverlayData['fadeIn']; @@ -469,13 +429,13 @@ class FakePlatformGoogleMap { } class FakePlatformViewsController { - FakePlatformGoogleMap lastCreatedView; + FakePlatformGoogleMap? lastCreatedView; Future fakePlatformViewsMethodHandler(MethodCall call) { switch (call.method) { case 'create': final Map args = call.arguments; - final Map params = _decodeParams(args['params']); + final Map params = _decodeParams(args['params'])!; lastCreatedView = FakePlatformGoogleMap( args['id'], params, @@ -491,7 +451,7 @@ class FakePlatformViewsController { } } -Map _decodeParams(Uint8List paramsMessage) { +Map? _decodeParams(Uint8List paramsMessage) { final ByteBuffer buffer = paramsMessage.buffer; final ByteData messageBytes = buffer.asByteData( paramsMessage.offsetInBytes, diff --git a/packages/google_maps_flutter/google_maps_flutter/test/google_map_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/google_map_test.dart index 3c1eadb8d2a4..857344f5ac5e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/google_map_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/google_map_test.dart @@ -35,7 +35,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.cameraPosition, const CameraPosition(target: LatLng(10.0, 15.0))); @@ -62,7 +62,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.cameraPosition, const CameraPosition(target: LatLng(10.0, 15.0))); @@ -80,7 +80,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.compassEnabled, false); @@ -109,7 +109,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.mapToolbarEnabled, false); @@ -144,7 +144,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect( platformGoogleMap.cameraTargetBounds, @@ -193,7 +193,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.mapType, MapType.hybrid); @@ -222,7 +222,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.minMaxZoomPreference, const MinMaxZoomPreference(1.0, 3.0)); @@ -253,7 +253,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.rotateGesturesEnabled, false); @@ -282,7 +282,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.scrollGesturesEnabled, false); @@ -311,7 +311,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.tiltGesturesEnabled, false); @@ -339,7 +339,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.trackCameraPosition, false); @@ -369,7 +369,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.zoomGesturesEnabled, false); @@ -398,7 +398,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.zoomControlsEnabled, false); @@ -427,7 +427,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.myLocationEnabled, false); @@ -457,7 +457,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.myLocationButtonEnabled, true); @@ -485,7 +485,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.padding, [0, 0, 0, 0]); }); @@ -501,7 +501,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.padding, [0, 0, 0, 0]); @@ -542,7 +542,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.trafficEnabled, false); @@ -571,7 +571,7 @@ void main() { ); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.buildingsEnabled, false); diff --git a/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart index 5ea9a679a1be..684e8659c4b5 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart @@ -2,26 +2,26 @@ // 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:typed_data'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; -import 'package:plugin_platform_interface/plugin_platform_interface.dart'; -import 'package:mockito/mockito.dart'; - -class MockGoogleMapsFlutterPlatform extends Mock - with MockPlatformInterfaceMixin - implements GoogleMapsFlutterPlatform {} +import 'package:stream_transform/stream_transform.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); - final platform = MockGoogleMapsFlutterPlatform(); + late TestGoogleMapsFlutterPlatform platform; setUp(() { // Use a mock platform so we never need to hit the MethodChannel code. + platform = TestGoogleMapsFlutterPlatform(); GoogleMapsFlutterPlatform.instance = platform; - resetMockitoState(); - _setupMock(platform); }); testWidgets('_webOnlyMapCreationId increments with each GoogleMap widget', ( @@ -49,18 +49,9 @@ void main() { ); // Verify that each one was created with a different _webOnlyMapCreationId. - verifyInOrder([ - platform.buildView( - argThat(containsPair('_webOnlyMapCreationId', 0)), - any, - any, - ), - platform.buildView( - argThat(containsPair('_webOnlyMapCreationId', 1)), - any, - any, - ), - ]); + expect(platform.createdIds.length, 2); + expect(platform.createdIds[0], 0); + expect(platform.createdIds[1], 1); }); testWidgets('Calls platform.dispose when GoogleMap is disposed of', ( @@ -75,47 +66,220 @@ void main() { // Now dispose of the map... await tester.pumpWidget(Container()); - verify(platform.dispose(mapId: anyNamed('mapId'))); + expect(platform.disposed, true); }); } -// Some test setup classes below... +// A dummy implementation of the platform interface for tests. +class TestGoogleMapsFlutterPlatform extends GoogleMapsFlutterPlatform { + TestGoogleMapsFlutterPlatform(); + + // The IDs passed to each call to buildView, in call order. + List createdIds = []; + + // Whether `dispose` has been called. + bool disposed = false; + + // Stream controller to inject events for testing. + final StreamController mapEventStreamController = + StreamController.broadcast(); + + @override + Future init(int mapId) async {} + + @override + Future updateMapOptions( + Map optionsUpdate, { + required int mapId, + }) async {} + + @override + Future updateMarkers( + MarkerUpdates markerUpdates, { + required int mapId, + }) async {} + + @override + Future updatePolygons( + PolygonUpdates polygonUpdates, { + required int mapId, + }) async {} + + @override + Future updatePolylines( + PolylineUpdates polylineUpdates, { + required int mapId, + }) async {} + + @override + Future updateCircles( + CircleUpdates circleUpdates, { + required int mapId, + }) async {} + + @override + Future updateTileOverlays({ + required Set newTileOverlays, + required int mapId, + }) async {} + + @override + Future clearTileCache( + TileOverlayId tileOverlayId, { + required int mapId, + }) async {} + + @override + Future animateCamera( + CameraUpdate cameraUpdate, { + required int mapId, + }) async {} + + @override + Future moveCamera( + CameraUpdate cameraUpdate, { + required int mapId, + }) async {} + + @override + Future setMapStyle( + String? mapStyle, { + required int mapId, + }) async {} + + @override + Future getVisibleRegion({ + required int mapId, + }) async { + return LatLngBounds(southwest: LatLng(0, 0), northeast: LatLng(0, 0)); + } -class _MockStream extends Mock implements Stream {} + @override + Future getScreenCoordinate( + LatLng latLng, { + required int mapId, + }) async { + return ScreenCoordinate(x: 0, y: 0); + } -typedef _CreationCallback = void Function(int); + @override + Future getLatLng( + ScreenCoordinate screenCoordinate, { + required int mapId, + }) async { + return LatLng(0, 0); + } -// Installs test mocks on the platform -void _setupMock(MockGoogleMapsFlutterPlatform platform) { - // Used to create the view of the map... - when(platform.buildView(any, any, any)).thenAnswer((realInvocation) { - // Call the onPlatformViewCreated callback so the controller gets created. - _CreationCallback onPlatformViewCreatedCb = - realInvocation.positionalArguments[2]; - onPlatformViewCreatedCb.call(0); + @override + Future showMarkerInfoWindow( + MarkerId markerId, { + required int mapId, + }) async {} + + @override + Future hideMarkerInfoWindow( + MarkerId markerId, { + required int mapId, + }) async {} + + @override + Future isMarkerInfoWindowShown( + MarkerId markerId, { + required int mapId, + }) async { + return false; + } + + @override + Future getZoomLevel({ + required int mapId, + }) async { + return 0.0; + } + + @override + Future takeSnapshot({ + required int mapId, + }) async { + return null; + } + + @override + Stream onCameraMoveStarted({required int mapId}) { + return mapEventStreamController.stream.whereType(); + } + + @override + Stream onCameraMove({required int mapId}) { + return mapEventStreamController.stream.whereType(); + } + + @override + Stream onCameraIdle({required int mapId}) { + return mapEventStreamController.stream.whereType(); + } + + @override + Stream onMarkerTap({required int mapId}) { + return mapEventStreamController.stream.whereType(); + } + + @override + Stream onInfoWindowTap({required int mapId}) { + return mapEventStreamController.stream.whereType(); + } + + @override + Stream onMarkerDragEnd({required int mapId}) { + return mapEventStreamController.stream.whereType(); + } + + @override + Stream onPolylineTap({required int mapId}) { + return mapEventStreamController.stream.whereType(); + } + + @override + Stream onPolygonTap({required int mapId}) { + return mapEventStreamController.stream.whereType(); + } + + @override + Stream onCircleTap({required int mapId}) { + return mapEventStreamController.stream.whereType(); + } + + @override + Stream onTap({required int mapId}) { + return mapEventStreamController.stream.whereType(); + } + + @override + Stream onLongPress({required int mapId}) { + return mapEventStreamController.stream.whereType(); + } + + @override + void dispose({required int mapId}) { + disposed = true; + } + + @override + Widget buildView( + int creationId, + PlatformViewCreatedCallback onPlatformViewCreated, { + required CameraPosition initialCameraPosition, + Set markers = const {}, + Set polygons = const {}, + Set polylines = const {}, + Set circles = const {}, + Set tileOverlays = const {}, + Set>? gestureRecognizers = + const >{}, + Map mapOptions = const {}, + }) { + onPlatformViewCreated(0); + createdIds.add(creationId); return Container(); - }); - // Used to create the Controller - when(platform.onCameraIdle(mapId: anyNamed('mapId'))) - .thenAnswer((_) => _MockStream()); - when(platform.onCameraMove(mapId: anyNamed('mapId'))) - .thenAnswer((_) => _MockStream()); - when(platform.onCameraMoveStarted(mapId: anyNamed('mapId'))) - .thenAnswer((_) => _MockStream()); - when(platform.onCircleTap(mapId: anyNamed('mapId'))) - .thenAnswer((_) => _MockStream()); - when(platform.onInfoWindowTap(mapId: anyNamed('mapId'))) - .thenAnswer((_) => _MockStream()); - when(platform.onLongPress(mapId: anyNamed('mapId'))) - .thenAnswer((_) => _MockStream()); - when(platform.onMarkerDragEnd(mapId: anyNamed('mapId'))) - .thenAnswer((_) => _MockStream()); - when(platform.onMarkerTap(mapId: anyNamed('mapId'))) - .thenAnswer((_) => _MockStream()); - when(platform.onPolygonTap(mapId: anyNamed('mapId'))) - .thenAnswer((_) => _MockStream()); - when(platform.onPolylineTap(mapId: anyNamed('mapId'))) - .thenAnswer((_) => _MockStream()); - when(platform.onTap(mapId: anyNamed('mapId'))) - .thenAnswer((_) => _MockStream()); + } } diff --git a/packages/google_maps_flutter/google_maps_flutter/test/marker_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/marker_updates_test.dart index 620e1ef4bfea..ce0da4235c9c 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/marker_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/marker_updates_test.dart @@ -9,20 +9,6 @@ import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'fake_maps_controllers.dart'; -Set _toSet({Marker m1, Marker m2, Marker m3}) { - final Set res = Set.identity(); - if (m1 != null) { - res.add(m1); - } - if (m2 != null) { - res.add(m2); - } - if (m3 != null) { - res.add(m3); - } - return res; -} - Widget _mapWithMarkers(Set markers) { return Directionality( textDirection: TextDirection.ltr, @@ -50,10 +36,10 @@ void main() { testWidgets('Initializing a marker', (WidgetTester tester) async { final Marker m1 = Marker(markerId: MarkerId("marker_1")); - await tester.pumpWidget(_mapWithMarkers(_toSet(m1: m1))); + await tester.pumpWidget(_mapWithMarkers({m1})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.markersToAdd.length, 1); final Marker initializedMarker = platformGoogleMap.markersToAdd.first; @@ -66,11 +52,11 @@ void main() { final Marker m1 = Marker(markerId: MarkerId("marker_1")); final Marker m2 = Marker(markerId: MarkerId("marker_2")); - await tester.pumpWidget(_mapWithMarkers(_toSet(m1: m1))); - await tester.pumpWidget(_mapWithMarkers(_toSet(m1: m1, m2: m2))); + await tester.pumpWidget(_mapWithMarkers({m1})); + await tester.pumpWidget(_mapWithMarkers({m1, m2})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.markersToAdd.length, 1); final Marker addedMarker = platformGoogleMap.markersToAdd.first; @@ -84,11 +70,11 @@ void main() { testWidgets("Removing a marker", (WidgetTester tester) async { final Marker m1 = Marker(markerId: MarkerId("marker_1")); - await tester.pumpWidget(_mapWithMarkers(_toSet(m1: m1))); - await tester.pumpWidget(_mapWithMarkers(null)); + await tester.pumpWidget(_mapWithMarkers({m1})); + await tester.pumpWidget(_mapWithMarkers({})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.markerIdsToRemove.length, 1); expect(platformGoogleMap.markerIdsToRemove.first, equals(m1.markerId)); @@ -100,11 +86,11 @@ void main() { final Marker m1 = Marker(markerId: MarkerId("marker_1")); final Marker m2 = Marker(markerId: MarkerId("marker_1"), alpha: 0.5); - await tester.pumpWidget(_mapWithMarkers(_toSet(m1: m1))); - await tester.pumpWidget(_mapWithMarkers(_toSet(m1: m2))); + await tester.pumpWidget(_mapWithMarkers({m1})); + await tester.pumpWidget(_mapWithMarkers({m2})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.markersToChange.length, 1); expect(platformGoogleMap.markersToChange.first, equals(m2)); @@ -119,11 +105,11 @@ void main() { infoWindow: const InfoWindow(snippet: 'changed'), ); - await tester.pumpWidget(_mapWithMarkers(_toSet(m1: m1))); - await tester.pumpWidget(_mapWithMarkers(_toSet(m1: m2))); + await tester.pumpWidget(_mapWithMarkers({m1})); + await tester.pumpWidget(_mapWithMarkers({m2})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.markersToChange.length, 1); final Marker update = platformGoogleMap.markersToChange.first; @@ -134,16 +120,16 @@ void main() { testWidgets("Multi Update", (WidgetTester tester) async { Marker m1 = Marker(markerId: MarkerId("marker_1")); Marker m2 = Marker(markerId: MarkerId("marker_2")); - final Set prev = _toSet(m1: m1, m2: m2); + final Set prev = {m1, m2}; m1 = Marker(markerId: MarkerId("marker_1"), visible: false); m2 = Marker(markerId: MarkerId("marker_2"), draggable: true); - final Set cur = _toSet(m1: m1, m2: m2); + final Set cur = {m1, m2}; await tester.pumpWidget(_mapWithMarkers(prev)); await tester.pumpWidget(_mapWithMarkers(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.markersToChange, cur); expect(platformGoogleMap.markerIdsToRemove.isEmpty, true); @@ -153,18 +139,18 @@ void main() { testWidgets("Multi Update", (WidgetTester tester) async { Marker m2 = Marker(markerId: MarkerId("marker_2")); final Marker m3 = Marker(markerId: MarkerId("marker_3")); - final Set prev = _toSet(m2: m2, m3: m3); + final Set prev = {m2, m3}; // m1 is added, m2 is updated, m3 is removed. final Marker m1 = Marker(markerId: MarkerId("marker_1")); m2 = Marker(markerId: MarkerId("marker_2"), draggable: true); - final Set cur = _toSet(m1: m1, m2: m2); + final Set cur = {m1, m2}; await tester.pumpWidget(_mapWithMarkers(prev)); await tester.pumpWidget(_mapWithMarkers(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.markersToChange.length, 1); expect(platformGoogleMap.markersToAdd.length, 1); @@ -179,35 +165,35 @@ void main() { final Marker m1 = Marker(markerId: MarkerId("marker_1")); final Marker m2 = Marker(markerId: MarkerId("marker_2")); Marker m3 = Marker(markerId: MarkerId("marker_3")); - final Set prev = _toSet(m1: m1, m2: m2, m3: m3); + final Set prev = {m1, m2, m3}; m3 = Marker(markerId: MarkerId("marker_3"), draggable: true); - final Set cur = _toSet(m1: m1, m2: m2, m3: m3); + final Set cur = {m1, m2, m3}; await tester.pumpWidget(_mapWithMarkers(prev)); await tester.pumpWidget(_mapWithMarkers(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; - expect(platformGoogleMap.markersToChange, _toSet(m3: m3)); + expect(platformGoogleMap.markersToChange, {m3}); expect(platformGoogleMap.markerIdsToRemove.isEmpty, true); expect(platformGoogleMap.markersToAdd.isEmpty, true); }); testWidgets("Update non platform related attr", (WidgetTester tester) async { Marker m1 = Marker(markerId: MarkerId("marker_1")); - final Set prev = _toSet(m1: m1); + final Set prev = {m1}; m1 = Marker( markerId: MarkerId("marker_1"), onTap: () => print("hello"), onDragEnd: (LatLng latLng) => print(latLng)); - final Set cur = _toSet(m1: m1); + final Set cur = {m1}; await tester.pumpWidget(_mapWithMarkers(prev)); await tester.pumpWidget(_mapWithMarkers(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.markersToChange.isEmpty, true); expect(platformGoogleMap.markerIdsToRemove.isEmpty, true); diff --git a/packages/google_maps_flutter/google_maps_flutter/test/polygon_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/polygon_updates_test.dart index 667c7d83644e..e187426bf7f6 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/polygon_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/polygon_updates_test.dart @@ -9,20 +9,6 @@ import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'fake_maps_controllers.dart'; -Set _toSet({Polygon p1, Polygon p2, Polygon p3}) { - final Set res = Set.identity(); - if (p1 != null) { - res.add(p1); - } - if (p2 != null) { - res.add(p2); - } - if (p3 != null) { - res.add(p3); - } - return res; -} - Widget _mapWithPolygons(Set polygons) { return Directionality( textDirection: TextDirection.ltr, @@ -34,7 +20,7 @@ Widget _mapWithPolygons(Set polygons) { } List _rectPoints({ - @required double size, + required double size, LatLng center = const LatLng(0, 0), }) { final halfSize = size / 2; @@ -73,10 +59,10 @@ void main() { testWidgets('Initializing a polygon', (WidgetTester tester) async { final Polygon p1 = Polygon(polygonId: PolygonId("polygon_1")); - await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); + await tester.pumpWidget(_mapWithPolygons({p1})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polygonsToAdd.length, 1); final Polygon initializedPolygon = platformGoogleMap.polygonsToAdd.first; @@ -89,11 +75,11 @@ void main() { final Polygon p1 = Polygon(polygonId: PolygonId("polygon_1")); final Polygon p2 = Polygon(polygonId: PolygonId("polygon_2")); - await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); - await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1, p2: p2))); + await tester.pumpWidget(_mapWithPolygons({p1})); + await tester.pumpWidget(_mapWithPolygons({p1, p2})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polygonsToAdd.length, 1); final Polygon addedPolygon = platformGoogleMap.polygonsToAdd.first; @@ -107,11 +93,11 @@ void main() { testWidgets("Removing a polygon", (WidgetTester tester) async { final Polygon p1 = Polygon(polygonId: PolygonId("polygon_1")); - await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); - await tester.pumpWidget(_mapWithPolygons(null)); + await tester.pumpWidget(_mapWithPolygons({p1})); + await tester.pumpWidget(_mapWithPolygons({})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polygonIdsToRemove.length, 1); expect(platformGoogleMap.polygonIdsToRemove.first, equals(p1.polygonId)); @@ -124,11 +110,11 @@ void main() { final Polygon p2 = Polygon(polygonId: PolygonId("polygon_1"), geodesic: true); - await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); - await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p2))); + await tester.pumpWidget(_mapWithPolygons({p1})); + await tester.pumpWidget(_mapWithPolygons({p2})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polygonsToChange.length, 1); expect(platformGoogleMap.polygonsToChange.first, equals(p2)); @@ -141,13 +127,13 @@ void main() { polygonId: PolygonId("polygon_1"), points: [const LatLng(0.0, 0.0)], ); - await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); + await tester.pumpWidget(_mapWithPolygons({p1})); p1.points.add(const LatLng(1.0, 1.0)); - await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); + await tester.pumpWidget(_mapWithPolygons({p1})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polygonsToChange.length, 1); expect(platformGoogleMap.polygonsToChange.first, equals(p1)); @@ -158,16 +144,16 @@ void main() { testWidgets("Multi Update", (WidgetTester tester) async { Polygon p1 = Polygon(polygonId: PolygonId("polygon_1")); Polygon p2 = Polygon(polygonId: PolygonId("polygon_2")); - final Set prev = _toSet(p1: p1, p2: p2); + final Set prev = {p1, p2}; p1 = Polygon(polygonId: PolygonId("polygon_1"), visible: false); p2 = Polygon(polygonId: PolygonId("polygon_2"), geodesic: true); - final Set cur = _toSet(p1: p1, p2: p2); + final Set cur = {p1, p2}; await tester.pumpWidget(_mapWithPolygons(prev)); await tester.pumpWidget(_mapWithPolygons(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polygonsToChange, cur); expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true); @@ -177,18 +163,18 @@ void main() { testWidgets("Multi Update", (WidgetTester tester) async { Polygon p2 = Polygon(polygonId: PolygonId("polygon_2")); final Polygon p3 = Polygon(polygonId: PolygonId("polygon_3")); - final Set prev = _toSet(p2: p2, p3: p3); + final Set prev = {p2, p3}; // p1 is added, p2 is updated, p3 is removed. final Polygon p1 = Polygon(polygonId: PolygonId("polygon_1")); p2 = Polygon(polygonId: PolygonId("polygon_2"), geodesic: true); - final Set cur = _toSet(p1: p1, p2: p2); + final Set cur = {p1, p2}; await tester.pumpWidget(_mapWithPolygons(prev)); await tester.pumpWidget(_mapWithPolygons(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polygonsToChange.length, 1); expect(platformGoogleMap.polygonsToAdd.length, 1); @@ -203,32 +189,32 @@ void main() { final Polygon p1 = Polygon(polygonId: PolygonId("polygon_1")); final Polygon p2 = Polygon(polygonId: PolygonId("polygon_2")); Polygon p3 = Polygon(polygonId: PolygonId("polygon_3")); - final Set prev = _toSet(p1: p1, p2: p2, p3: p3); + final Set prev = {p1, p2, p3}; p3 = Polygon(polygonId: PolygonId("polygon_3"), geodesic: true); - final Set cur = _toSet(p1: p1, p2: p2, p3: p3); + final Set cur = {p1, p2, p3}; await tester.pumpWidget(_mapWithPolygons(prev)); await tester.pumpWidget(_mapWithPolygons(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; - expect(platformGoogleMap.polygonsToChange, _toSet(p3: p3)); + expect(platformGoogleMap.polygonsToChange, {p3}); expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true); expect(platformGoogleMap.polygonsToAdd.isEmpty, true); }); testWidgets("Update non platform related attr", (WidgetTester tester) async { Polygon p1 = Polygon(polygonId: PolygonId("polygon_1")); - final Set prev = _toSet(p1: p1); + final Set prev = {p1}; p1 = Polygon(polygonId: PolygonId("polygon_1"), onTap: () => print(2 + 2)); - final Set cur = _toSet(p1: p1); + final Set cur = {p1}; await tester.pumpWidget(_mapWithPolygons(prev)); await tester.pumpWidget(_mapWithPolygons(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polygonsToChange.isEmpty, true); expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true); @@ -238,10 +224,10 @@ void main() { testWidgets('Initializing a polygon with points and hole', (WidgetTester tester) async { final Polygon p1 = _polygonWithPointsAndHole(PolygonId("polygon_1")); - await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); + await tester.pumpWidget(_mapWithPolygons({p1})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polygonsToAdd.length, 1); final Polygon initializedPolygon = platformGoogleMap.polygonsToAdd.first; @@ -255,11 +241,11 @@ void main() { final Polygon p1 = Polygon(polygonId: PolygonId("polygon_1")); final Polygon p2 = _polygonWithPointsAndHole(PolygonId("polygon_2")); - await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); - await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1, p2: p2))); + await tester.pumpWidget(_mapWithPolygons({p1})); + await tester.pumpWidget(_mapWithPolygons({p1, p2})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polygonsToAdd.length, 1); final Polygon addedPolygon = platformGoogleMap.polygonsToAdd.first; @@ -274,11 +260,11 @@ void main() { (WidgetTester tester) async { final Polygon p1 = _polygonWithPointsAndHole(PolygonId("polygon_1")); - await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); - await tester.pumpWidget(_mapWithPolygons(null)); + await tester.pumpWidget(_mapWithPolygons({p1})); + await tester.pumpWidget(_mapWithPolygons({})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polygonIdsToRemove.length, 1); expect(platformGoogleMap.polygonIdsToRemove.first, equals(p1.polygonId)); @@ -291,11 +277,11 @@ void main() { final Polygon p1 = Polygon(polygonId: PolygonId("polygon_1")); final Polygon p2 = _polygonWithPointsAndHole(PolygonId("polygon_1")); - await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); - await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p2))); + await tester.pumpWidget(_mapWithPolygons({p1})); + await tester.pumpWidget(_mapWithPolygons({p2})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polygonsToChange.length, 1); expect(platformGoogleMap.polygonsToChange.first, equals(p2)); @@ -310,7 +296,7 @@ void main() { points: _rectPoints(size: 1), holes: [_rectPoints(size: 0.5)], ); - await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); + await tester.pumpWidget(_mapWithPolygons({p1})); p1.points ..clear() @@ -318,10 +304,10 @@ void main() { p1.holes ..clear() ..addAll([_rectPoints(size: 1)]); - await tester.pumpWidget(_mapWithPolygons(_toSet(p1: p1))); + await tester.pumpWidget(_mapWithPolygons({p1})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polygonsToChange.length, 1); expect(platformGoogleMap.polygonsToChange.first, equals(p1)); @@ -337,19 +323,19 @@ void main() { points: _rectPoints(size: 2), holes: [_rectPoints(size: 1)], ); - final Set prev = _toSet(p1: p1, p2: p2); + final Set prev = {p1, p2}; p1 = Polygon(polygonId: PolygonId("polygon_1"), visible: false); p2 = p2.copyWith( pointsParam: _rectPoints(size: 5), holesParam: [_rectPoints(size: 2)], ); - final Set cur = _toSet(p1: p1, p2: p2); + final Set cur = {p1, p2}; await tester.pumpWidget(_mapWithPolygons(prev)); await tester.pumpWidget(_mapWithPolygons(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polygonsToChange, cur); expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true); @@ -364,7 +350,7 @@ void main() { holes: [_rectPoints(size: 1)], ); final Polygon p3 = Polygon(polygonId: PolygonId("polygon_3")); - final Set prev = _toSet(p2: p2, p3: p3); + final Set prev = {p2, p3}; // p1 is added, p2 is updated, p3 is removed. final Polygon p1 = _polygonWithPointsAndHole(PolygonId("polygon_1")); @@ -372,13 +358,13 @@ void main() { pointsParam: _rectPoints(size: 5), holesParam: [_rectPoints(size: 3)], ); - final Set cur = _toSet(p1: p1, p2: p2); + final Set cur = {p1, p2}; await tester.pumpWidget(_mapWithPolygons(prev)); await tester.pumpWidget(_mapWithPolygons(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polygonsToChange.length, 1); expect(platformGoogleMap.polygonsToAdd.length, 1); @@ -398,20 +384,20 @@ void main() { points: _rectPoints(size: 2), holes: [_rectPoints(size: 1)], ); - final Set prev = _toSet(p1: p1, p2: p2, p3: p3); + final Set prev = {p1, p2, p3}; p3 = p3.copyWith( pointsParam: _rectPoints(size: 5), holesParam: [_rectPoints(size: 3)], ); - final Set cur = _toSet(p1: p1, p2: p2, p3: p3); + final Set cur = {p1, p2, p3}; await tester.pumpWidget(_mapWithPolygons(prev)); await tester.pumpWidget(_mapWithPolygons(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; - expect(platformGoogleMap.polygonsToChange, _toSet(p3: p3)); + expect(platformGoogleMap.polygonsToChange, {p3}); expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true); expect(platformGoogleMap.polygonsToAdd.isEmpty, true); }); diff --git a/packages/google_maps_flutter/google_maps_flutter/test/polyline_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/polyline_updates_test.dart index 269e8f1313f5..3644f83a1adc 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/polyline_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/polyline_updates_test.dart @@ -9,20 +9,6 @@ import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'fake_maps_controllers.dart'; -Set _toSet({Polyline p1, Polyline p2, Polyline p3}) { - final Set res = Set.identity(); - if (p1 != null) { - res.add(p1); - } - if (p2 != null) { - res.add(p2); - } - if (p3 != null) { - res.add(p3); - } - return res; -} - Widget _mapWithPolylines(Set polylines) { return Directionality( textDirection: TextDirection.ltr, @@ -50,10 +36,10 @@ void main() { testWidgets('Initializing a polyline', (WidgetTester tester) async { final Polyline p1 = Polyline(polylineId: PolylineId("polyline_1")); - await tester.pumpWidget(_mapWithPolylines(_toSet(p1: p1))); + await tester.pumpWidget(_mapWithPolylines({p1})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polylinesToAdd.length, 1); final Polyline initializedPolyline = platformGoogleMap.polylinesToAdd.first; @@ -66,11 +52,11 @@ void main() { final Polyline p1 = Polyline(polylineId: PolylineId("polyline_1")); final Polyline p2 = Polyline(polylineId: PolylineId("polyline_2")); - await tester.pumpWidget(_mapWithPolylines(_toSet(p1: p1))); - await tester.pumpWidget(_mapWithPolylines(_toSet(p1: p1, p2: p2))); + await tester.pumpWidget(_mapWithPolylines({p1})); + await tester.pumpWidget(_mapWithPolylines({p1, p2})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polylinesToAdd.length, 1); final Polyline addedPolyline = platformGoogleMap.polylinesToAdd.first; @@ -84,11 +70,11 @@ void main() { testWidgets("Removing a polyline", (WidgetTester tester) async { final Polyline p1 = Polyline(polylineId: PolylineId("polyline_1")); - await tester.pumpWidget(_mapWithPolylines(_toSet(p1: p1))); - await tester.pumpWidget(_mapWithPolylines(null)); + await tester.pumpWidget(_mapWithPolylines({p1})); + await tester.pumpWidget(_mapWithPolylines({})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polylineIdsToRemove.length, 1); expect(platformGoogleMap.polylineIdsToRemove.first, equals(p1.polylineId)); @@ -101,11 +87,11 @@ void main() { final Polyline p2 = Polyline(polylineId: PolylineId("polyline_1"), geodesic: true); - await tester.pumpWidget(_mapWithPolylines(_toSet(p1: p1))); - await tester.pumpWidget(_mapWithPolylines(_toSet(p1: p2))); + await tester.pumpWidget(_mapWithPolylines({p1})); + await tester.pumpWidget(_mapWithPolylines({p2})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polylinesToChange.length, 1); expect(platformGoogleMap.polylinesToChange.first, equals(p2)); @@ -118,11 +104,11 @@ void main() { final Polyline p2 = Polyline(polylineId: PolylineId("polyline_1"), geodesic: true); - await tester.pumpWidget(_mapWithPolylines(_toSet(p1: p1))); - await tester.pumpWidget(_mapWithPolylines(_toSet(p1: p2))); + await tester.pumpWidget(_mapWithPolylines({p1})); + await tester.pumpWidget(_mapWithPolylines({p2})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polylinesToChange.length, 1); final Polyline update = platformGoogleMap.polylinesToChange.first; @@ -135,13 +121,13 @@ void main() { polylineId: PolylineId("polyline_1"), points: [const LatLng(0.0, 0.0)], ); - await tester.pumpWidget(_mapWithPolylines(_toSet(p1: p1))); + await tester.pumpWidget(_mapWithPolylines({p1})); p1.points.add(const LatLng(1.0, 1.0)); - await tester.pumpWidget(_mapWithPolylines(_toSet(p1: p1))); + await tester.pumpWidget(_mapWithPolylines({p1})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polylinesToChange.length, 1); expect(platformGoogleMap.polylinesToChange.first, equals(p1)); @@ -152,16 +138,16 @@ void main() { testWidgets("Multi Update", (WidgetTester tester) async { Polyline p1 = Polyline(polylineId: PolylineId("polyline_1")); Polyline p2 = Polyline(polylineId: PolylineId("polyline_2")); - final Set prev = _toSet(p1: p1, p2: p2); + final Set prev = {p1, p2}; p1 = Polyline(polylineId: PolylineId("polyline_1"), visible: false); p2 = Polyline(polylineId: PolylineId("polyline_2"), geodesic: true); - final Set cur = _toSet(p1: p1, p2: p2); + final Set cur = {p1, p2}; await tester.pumpWidget(_mapWithPolylines(prev)); await tester.pumpWidget(_mapWithPolylines(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polylinesToChange, cur); expect(platformGoogleMap.polylineIdsToRemove.isEmpty, true); @@ -171,18 +157,18 @@ void main() { testWidgets("Multi Update", (WidgetTester tester) async { Polyline p2 = Polyline(polylineId: PolylineId("polyline_2")); final Polyline p3 = Polyline(polylineId: PolylineId("polyline_3")); - final Set prev = _toSet(p2: p2, p3: p3); + final Set prev = {p2, p3}; // p1 is added, p2 is updated, p3 is removed. final Polyline p1 = Polyline(polylineId: PolylineId("polyline_1")); p2 = Polyline(polylineId: PolylineId("polyline_2"), geodesic: true); - final Set cur = _toSet(p1: p1, p2: p2); + final Set cur = {p1, p2}; await tester.pumpWidget(_mapWithPolylines(prev)); await tester.pumpWidget(_mapWithPolylines(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polylinesToChange.length, 1); expect(platformGoogleMap.polylinesToAdd.length, 1); @@ -197,37 +183,33 @@ void main() { final Polyline p1 = Polyline(polylineId: PolylineId("polyline_1")); final Polyline p2 = Polyline(polylineId: PolylineId("polyline_2")); Polyline p3 = Polyline(polylineId: PolylineId("polyline_3")); - final Set prev = _toSet(p1: p1, p2: p2, p3: p3); + final Set prev = {p1, p2, p3}; p3 = Polyline(polylineId: PolylineId("polyline_3"), geodesic: true); - final Set cur = _toSet(p1: p1, p2: p2, p3: p3); + final Set cur = {p1, p2, p3}; await tester.pumpWidget(_mapWithPolylines(prev)); await tester.pumpWidget(_mapWithPolylines(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; - expect(platformGoogleMap.polylinesToChange, _toSet(p3: p3)); + expect(platformGoogleMap.polylinesToChange, {p3}); expect(platformGoogleMap.polylineIdsToRemove.isEmpty, true); expect(platformGoogleMap.polylinesToAdd.isEmpty, true); }); testWidgets("Update non platform related attr", (WidgetTester tester) async { Polyline p1 = Polyline(polylineId: PolylineId("polyline_1"), onTap: null); - final Set prev = _toSet( - p1: p1, - ); + final Set prev = {p1}; p1 = Polyline( polylineId: PolylineId("polyline_1"), onTap: () => print(2 + 2)); - final Set cur = _toSet( - p1: p1, - ); + final Set cur = {p1}; await tester.pumpWidget(_mapWithPolylines(prev)); await tester.pumpWidget(_mapWithPolylines(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.polylinesToChange.isEmpty, true); expect(platformGoogleMap.polylineIdsToRemove.isEmpty, true); diff --git a/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart index b94d4906dec7..d2b6efb69e66 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart @@ -5,20 +5,6 @@ import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'fake_maps_controllers.dart'; -Set _toSet({TileOverlay t1, TileOverlay t2, TileOverlay t3}) { - final Set res = Set.identity(); - if (t1 != null) { - res.add(t1); - } - if (t2 != null) { - res.add(t2); - } - if (t3 != null) { - res.add(t3); - } - return res; -} - Widget _mapWithTileOverlays(Set tileOverlays) { return Directionality( textDirection: TextDirection.ltr, @@ -45,10 +31,10 @@ void main() { testWidgets('Initializing a tile overlay', (WidgetTester tester) async { final TileOverlay t1 = TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_1")); - await tester.pumpWidget(_mapWithTileOverlays(_toSet(t1: t1))); + await tester.pumpWidget(_mapWithTileOverlays({t1})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.tileOverlaysToAdd.length, 1); final TileOverlay initializedTileOverlay = @@ -64,11 +50,11 @@ void main() { final TileOverlay t2 = TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_2")); - await tester.pumpWidget(_mapWithTileOverlays(_toSet(t1: t1))); - await tester.pumpWidget(_mapWithTileOverlays(_toSet(t1: t1, t2: t2))); + await tester.pumpWidget(_mapWithTileOverlays({t1})); + await tester.pumpWidget(_mapWithTileOverlays({t1, t2})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.tileOverlaysToAdd.length, 1); final TileOverlay addedTileOverlay = @@ -83,11 +69,11 @@ void main() { final TileOverlay t1 = TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_1")); - await tester.pumpWidget(_mapWithTileOverlays(_toSet(t1: t1))); - await tester.pumpWidget(_mapWithTileOverlays(null)); + await tester.pumpWidget(_mapWithTileOverlays({t1})); + await tester.pumpWidget(_mapWithTileOverlays({})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.tileOverlayIdsToRemove.length, 1); expect(platformGoogleMap.tileOverlayIdsToRemove.first, equals(t1.tileOverlayId)); @@ -102,11 +88,11 @@ void main() { final TileOverlay t2 = TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_1"), zIndex: 10); - await tester.pumpWidget(_mapWithTileOverlays(_toSet(t1: t1))); - await tester.pumpWidget(_mapWithTileOverlays(_toSet(t1: t2))); + await tester.pumpWidget(_mapWithTileOverlays({t1})); + await tester.pumpWidget(_mapWithTileOverlays({t2})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.tileOverlaysToChange.length, 1); expect(platformGoogleMap.tileOverlaysToChange.first, equals(t2)); @@ -120,11 +106,11 @@ void main() { final TileOverlay t2 = TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_1"), zIndex: 10); - await tester.pumpWidget(_mapWithTileOverlays(_toSet(t1: t1))); - await tester.pumpWidget(_mapWithTileOverlays(_toSet(t1: t2))); + await tester.pumpWidget(_mapWithTileOverlays({t1})); + await tester.pumpWidget(_mapWithTileOverlays({t2})); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.tileOverlaysToChange.length, 1); final TileOverlay update = platformGoogleMap.tileOverlaysToChange.first; @@ -137,18 +123,18 @@ void main() { TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_1")); TileOverlay t2 = TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_2")); - final Set prev = _toSet(t1: t1, t2: t2); + final Set prev = {t1, t2}; t1 = TileOverlay( tileOverlayId: TileOverlayId("tile_overlay_1"), visible: false); t2 = TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_2"), zIndex: 10); - final Set cur = _toSet(t1: t1, t2: t2); + final Set cur = {t1, t2}; await tester.pumpWidget(_mapWithTileOverlays(prev)); await tester.pumpWidget(_mapWithTileOverlays(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.tileOverlaysToChange, cur); expect(platformGoogleMap.tileOverlayIdsToRemove.isEmpty, true); @@ -160,20 +146,20 @@ void main() { TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_2")); final TileOverlay t3 = TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_3")); - final Set prev = _toSet(t2: t2, t3: t3); + final Set prev = {t2, t3}; // t1 is added, t2 is updated, t3 is removed. final TileOverlay t1 = TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_1")); t2 = TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_2"), zIndex: 10); - final Set cur = _toSet(t1: t1, t2: t2); + final Set cur = {t1, t2}; await tester.pumpWidget(_mapWithTileOverlays(prev)); await tester.pumpWidget(_mapWithTileOverlays(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; expect(platformGoogleMap.tileOverlaysToChange.length, 1); expect(platformGoogleMap.tileOverlaysToAdd.length, 1); @@ -192,18 +178,18 @@ void main() { TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_2")); TileOverlay t3 = TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_3")); - final Set prev = _toSet(t1: t1, t2: t2, t3: t3); + final Set prev = {t1, t2, t3}; t3 = TileOverlay(tileOverlayId: TileOverlayId("tile_overlay_3"), zIndex: 10); - final Set cur = _toSet(t1: t1, t2: t2, t3: t3); + final Set cur = {t1, t2, t3}; await tester.pumpWidget(_mapWithTileOverlays(prev)); await tester.pumpWidget(_mapWithTileOverlays(cur)); final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView; + fakePlatformViewsController.lastCreatedView!; - expect(platformGoogleMap.tileOverlaysToChange, _toSet(t3: t3)); + expect(platformGoogleMap.tileOverlaysToChange, {t3}); expect(platformGoogleMap.tileOverlayIdsToRemove.isEmpty, true); expect(platformGoogleMap.tileOverlaysToAdd.isEmpty, true); }); diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index 112dccfcbba8..3e9e50ebd0f4 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -40,7 +40,7 @@ readonly NNBD_PLUGINS_LIST=( readonly NON_NNBD_PLUGINS_LIST=( "extension_google_sign_in_as_googleapis_auth" - "google_maps_flutter" # partially migrated + "google_maps_flutter_web" # Not yet migrated. ) export EXCLUDED_PLUGINS_FROM_STABLE=$(IFS=, ; echo "${NNBD_PLUGINS_LIST[*]}") From 23155313346866ee7ba8503bfb26201526208be3 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 19 Feb 2021 11:19:23 -0800 Subject: [PATCH 0156/1565] [url_launcher] Bump platform interface package to stable NNBD (#3570) Also enables null safety for the unit tests, which had been opted out. --- .../url_launcher_platform_interface/CHANGELOG.md | 6 +----- .../url_launcher_platform_interface/pubspec.yaml | 10 +++++----- .../test/link_test.dart | 15 +++++++-------- .../test/method_channel_url_launcher_test.dart | 4 +--- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md b/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md index 5bbbe9d28cd1..5cd56432ece4 100644 --- a/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md @@ -1,8 +1,4 @@ -## 2.0.0-nullsafety.1 - -* Bump Dart SDK to support null safety. - -## 2.0.0-nullsafety +## 2.0.0 * Migrate to null safety. diff --git a/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml b/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml index e576e967ec46..a8761c3594ea 100644 --- a/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml +++ b/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml @@ -3,19 +3,19 @@ description: A common platform interface for the url_launcher plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0-nullsafety.1 +version: 2.0.0 dependencies: flutter: sdk: flutter - plugin_platform_interface: ^1.1.0-nullsafety.1 + plugin_platform_interface: ">=1.0.0 <3.0.0" dev_dependencies: flutter_test: sdk: flutter - mockito: ^4.1.1 - pedantic: ^1.10.0-nullsafety.1 + mockito: ^5.0.0-nullsafety.7 + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-2.12.0-259.9.beta <3.0.0" flutter: ">=1.22.0" diff --git a/packages/url_launcher/url_launcher_platform_interface/test/link_test.dart b/packages/url_launcher/url_launcher_platform_interface/test/link_test.dart index 58cdd22dca02..a01637e2f378 100644 --- a/packages/url_launcher/url_launcher_platform_interface/test/link_test.dart +++ b/packages/url_launcher/url_launcher_platform_interface/test/link_test.dart @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(egarciad): Remove once Mockito has been migrated to null safety. -// @dart = 2.9 - import 'dart:ui'; import 'package:mockito/mockito.dart'; @@ -19,18 +16,20 @@ final MethodCodec _codec = const JSONMethodCodec(); void main() { TestWidgetsFlutterBinding.ensureInitialized(); - PlatformMessageCallback oldHandler; - MethodCall lastCall; + PlatformMessageCallback? oldHandler; + MethodCall? lastCall; setUp(() { oldHandler = window.onPlatformMessage; window.onPlatformMessage = ( String name, - ByteData data, - PlatformMessageResponseCallback callback, + ByteData? data, + PlatformMessageResponseCallback? callback, ) { lastCall = _codec.decodeMethodCall(data); - callback(_codec.encodeSuccessEnvelope(true)); + if (callback != null) { + callback(_codec.encodeSuccessEnvelope(true)); + } }; }); diff --git a/packages/url_launcher/url_launcher_platform_interface/test/method_channel_url_launcher_test.dart b/packages/url_launcher/url_launcher_platform_interface/test/method_channel_url_launcher_test.dart index dfd4b7380c3e..b5a96b18c91a 100644 --- a/packages/url_launcher/url_launcher_platform_interface/test/method_channel_url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_platform_interface/test/method_channel_url_launcher_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(mvanbeusekom): Remove once Mockito is migrated to null safety. -// @dart = 2.9 import 'package:mockito/mockito.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -315,5 +313,5 @@ class ImplementsUrlLauncherPlatform extends Mock class ExtendsUrlLauncherPlatform extends UrlLauncherPlatform { @override - final LinkDelegate linkDelegate = null; + final LinkDelegate? linkDelegate = null; } From 0638189d6a8e61e38a6412845f50340a641ba3a2 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Fri, 19 Feb 2021 11:56:26 -0800 Subject: [PATCH 0157/1565] [in_app_purchase] Migrate to NNBD (#3555) --- packages/in_app_purchase/CHANGELOG.md | 7 + packages/in_app_purchase/build.yaml | 1 - .../in_app_purchase/example/lib/main.dart | 19 ++- packages/in_app_purchase/example/pubspec.yaml | 8 +- .../test_driver/test/integration_test.dart | 1 + .../in_app_purchase_test.dart | 1 + .../ios/Classes/FIAPReceiptManager.m | 7 - .../ios/Classes/InAppPurchasePlugin.m | 4 +- .../billing_client_wrapper.dart | 112 ++++++++-------- .../enum_converters.dart | 49 ++++--- .../enum_converters.g.dart | 35 ++--- .../purchase_wrapper.dart | 81 +++++++----- .../purchase_wrapper.g.dart | 61 +++++---- .../sku_details_wrapper.dart | 74 +++++++---- .../sku_details_wrapper.g.dart | 49 +++---- packages/in_app_purchase/lib/src/channel.dart | 9 +- .../in_app_purchase/app_store_connection.dart | 82 +++++++----- .../google_play_connection.dart | 61 +++++---- .../in_app_purchase_connection.dart | 44 ++++--- .../src/in_app_purchase/product_details.dart | 23 ++-- .../src/in_app_purchase/purchase_details.dart | 77 ++++++----- .../store_kit_wrappers/enum_converters.dart | 75 +++++++++-- .../store_kit_wrappers/enum_converters.g.dart | 58 ++++++--- .../sk_payment_queue_wrapper.dart | 87 ++++++++----- .../sk_payment_queue_wrapper.g.dart | 22 ++-- .../sk_payment_transaction_wrappers.dart | 58 +++++---- .../sk_payment_transaction_wrappers.g.dart | 18 +-- .../sk_product_wrapper.dart | 110 +++++++++------- .../sk_product_wrapper.g.dart | 123 +++++++----------- .../sk_receipt_manager.dart | 7 +- .../store_kit_wrappers/sk_request_maker.dart | 5 +- packages/in_app_purchase/pubspec.yaml | 22 ++-- .../billing_client_wrapper_test.dart | 115 ++++++++++++++-- .../purchase_wrapper_test.dart | 24 ++++ .../sku_details_wrapper_test.dart | 27 ++++ .../app_store_connection_test.dart | 85 ++++++------ .../google_play_connection_test.dart | 50 +++---- .../sk_methodchannel_apis_test.dart | 51 +++++--- .../store_kit_wrappers/sk_product_test.dart | 66 +++++++--- .../sk_test_stub_objects.dart | 20 +-- .../test/stub_in_app_purchase_platform.dart | 12 +- script/nnbd_plugins.sh | 1 + .../tool/lib/src/publish_check_command.dart | 2 +- 43 files changed, 1134 insertions(+), 709 deletions(-) diff --git a/packages/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/CHANGELOG.md index abafaf506f3a..79f64d5bda53 100644 --- a/packages/in_app_purchase/CHANGELOG.md +++ b/packages/in_app_purchase/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.4.0 + +* Migrate to nullsafety. +* Deprecate `sandboxTesting`, introduce `simulatesAskToBuyInSandbox`. +* **Breaking Change:** + * Removed `callbackChannel` in `channels.dart`, see https://github.com/flutter/flutter/issues/69225. + ## 0.3.5+2 * Migrate deprecated references. diff --git a/packages/in_app_purchase/build.yaml b/packages/in_app_purchase/build.yaml index d7b59734f27e..e15cf14b85fd 100644 --- a/packages/in_app_purchase/build.yaml +++ b/packages/in_app_purchase/build.yaml @@ -5,4 +5,3 @@ targets: options: any_map: true create_to_json: true - nullable: false \ No newline at end of file diff --git a/packages/in_app_purchase/example/lib/main.dart b/packages/in_app_purchase/example/lib/main.dart index 911edae98cfb..82cd509b30be 100644 --- a/packages/in_app_purchase/example/lib/main.dart +++ b/packages/in_app_purchase/example/lib/main.dart @@ -32,7 +32,7 @@ class _MyApp extends StatefulWidget { class _MyAppState extends State<_MyApp> { final InAppPurchaseConnection _connection = InAppPurchaseConnection.instance; - StreamSubscription> _subscription; + late StreamSubscription> _subscription; List _notFoundIds = []; List _products = []; List _purchases = []; @@ -40,11 +40,11 @@ class _MyAppState extends State<_MyApp> { bool _isAvailable = false; bool _purchasePending = false; bool _loading = true; - String _queryProductError; + String? _queryProductError; @override void initState() { - Stream purchaseUpdated = + final Stream> purchaseUpdated = InAppPurchaseConnection.instance.purchaseUpdatedStream; _subscription = purchaseUpdated.listen((purchaseDetailsList) { _listenToPurchaseUpdated(purchaseDetailsList); @@ -76,7 +76,7 @@ class _MyAppState extends State<_MyApp> { await _connection.queryProductDetails(_kProductIds.toSet()); if (productDetailResponse.error != null) { setState(() { - _queryProductError = productDetailResponse.error.message; + _queryProductError = productDetailResponse.error!.message; _isAvailable = isAvailable; _products = productDetailResponse.productDetails; _purchases = []; @@ -146,7 +146,7 @@ class _MyAppState extends State<_MyApp> { ); } else { stack.add(Center( - child: Text(_queryProductError), + child: Text(_queryProductError!), )); } if (_purchasePending) { @@ -235,7 +235,7 @@ class _MyAppState extends State<_MyApp> { })); productList.addAll(_products.map( (ProductDetails productDetails) { - PurchaseDetails previousPurchase = purchases[productDetails.id]; + PurchaseDetails? previousPurchase = purchases[productDetails.id]; return ListTile( title: Text( productDetails.title, @@ -254,8 +254,7 @@ class _MyAppState extends State<_MyApp> { onPressed: () { PurchaseParam purchaseParam = PurchaseParam( productDetails: productDetails, - applicationUserName: null, - sandboxTesting: true); + applicationUserName: null); if (productDetails.id == _kConsumableId) { _connection.buyConsumable( purchaseParam: purchaseParam, @@ -329,7 +328,7 @@ class _MyAppState extends State<_MyApp> { void deliverProduct(PurchaseDetails purchaseDetails) async { // IMPORTANT!! Always verify a purchase purchase details before delivering the product. if (purchaseDetails.productID == _kConsumableId) { - await ConsumableStore.save(purchaseDetails.purchaseID); + await ConsumableStore.save(purchaseDetails.purchaseID!); List consumables = await ConsumableStore.load(); setState(() { _purchasePending = false; @@ -365,7 +364,7 @@ class _MyAppState extends State<_MyApp> { showPendingUI(); } else { if (purchaseDetails.status == PurchaseStatus.error) { - handleError(purchaseDetails.error); + handleError(purchaseDetails.error!); } else if (purchaseDetails.status == PurchaseStatus.purchased) { bool valid = await _verifyPurchase(purchaseDetails); if (valid) { diff --git a/packages/in_app_purchase/example/pubspec.yaml b/packages/in_app_purchase/example/pubspec.yaml index 9b623a15795a..8c9296dc98c8 100644 --- a/packages/in_app_purchase/example/pubspec.yaml +++ b/packages/in_app_purchase/example/pubspec.yaml @@ -5,11 +5,9 @@ author: Flutter Team dependencies: flutter: sdk: flutter - cupertino_icons: ^0.1.2 - shared_preferences: ^0.5.2 + shared_preferences: ^2.0.0-nullsafety.1 dev_dependencies: - test: ^1.5.2 flutter_driver: sdk: flutter in_app_purchase: @@ -21,11 +19,11 @@ dev_dependencies: path: ../ integration_test: path: ../../integration_test - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.3.0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.9.1+hotfix.2" diff --git a/packages/in_app_purchase/example/test_driver/test/integration_test.dart b/packages/in_app_purchase/example/test_driver/test/integration_test.dart index 7a2c21338786..0352d4aaeb2d 100644 --- a/packages/in_app_purchase/example/test_driver/test/integration_test.dart +++ b/packages/in_app_purchase/example/test_driver/test/integration_test.dart @@ -2,6 +2,7 @@ // 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/in_app_purchase/integration_test/in_app_purchase_test.dart b/packages/in_app_purchase/integration_test/in_app_purchase_test.dart index a5bfdb0eb409..aa3430fbc7d2 100644 --- a/packages/in_app_purchase/integration_test/in_app_purchase_test.dart +++ b/packages/in_app_purchase/integration_test/in_app_purchase_test.dart @@ -2,6 +2,7 @@ // 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:in_app_purchase/in_app_purchase.dart'; import 'package:integration_test/integration_test.dart'; diff --git a/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.m b/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.m index 92872d91234e..f6bdf0c4f249 100644 --- a/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.m +++ b/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.m @@ -2,13 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// -// FIAPReceiptManager.m -// in_app_purchase -// -// Created by Chris Yang on 3/2/19. -// - #import "FIAPReceiptManager.h" #import diff --git a/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m b/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m index 872a34a94954..9b44ad766a98 100644 --- a/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m +++ b/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m @@ -75,7 +75,7 @@ - (instancetype)initWithRegistrar:(NSObject *)registrar }]; [_paymentQueueHandler startObservingPaymentQueue]; _callbackChannel = - [FlutterMethodChannel methodChannelWithName:@"plugins.flutter.io/in_app_purchase_callback" + [FlutterMethodChannel methodChannelWithName:@"plugins.flutter.io/in_app_purchase" binaryMessenger:[registrar messenger]]; return self; } @@ -290,7 +290,7 @@ - (void)refreshReceipt:(FlutterMethodCall *)call result:(FlutterResult)result { }]; } -#pragma mark - delegates +#pragma mark - delegates: - (void)handleTransactionsUpdated:(NSArray *)transactions { NSMutableArray *maps = [NSMutableArray new]; diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart index 2aa91d9f9225..9f96c05e15f9 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart @@ -53,10 +53,7 @@ class BillingClient { bool _enablePendingPurchases = false; /// Creates a billing client. - /// - /// The `onPurchasesUpdated` parameter must not be null. BillingClient(PurchasesUpdatedListener onPurchasesUpdated) { - assert(onPurchasesUpdated != null); channel.setMethodCallHandler(callHandler); _callbacks[kOnPurchasesUpdated] = [onPurchasesUpdated]; } @@ -74,8 +71,11 @@ class BillingClient { /// Calls /// [`BillingClient#isReady()`](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html#isReady()) /// to get the ready status of the BillingClient instance. - Future isReady() async => - await channel.invokeMethod('BillingClient#isReady()'); + Future isReady() async { + final bool? ready = + await channel.invokeMethod('BillingClient#isReady()'); + return ready ?? false; + } /// Enable the [BillingClientWrapper] to handle pending purchases. /// @@ -100,20 +100,21 @@ class BillingClient { /// This triggers the creation of a new `BillingClient` instance in Java if /// one doesn't already exist. Future startConnection( - {@required - OnBillingServiceDisconnected onBillingServiceDisconnected}) async { + {required OnBillingServiceDisconnected + onBillingServiceDisconnected}) async { assert(_enablePendingPurchases, 'enablePendingPurchases() must be called before calling startConnection'); List disconnectCallbacks = _callbacks[_kOnBillingServiceDisconnected] ??= []; disconnectCallbacks.add(onBillingServiceDisconnected); - return BillingResultWrapper.fromJson(await channel - .invokeMapMethod( - "BillingClient#startConnection(BillingClientStateListener)", - { - 'handle': disconnectCallbacks.length - 1, - 'enablePendingPurchases': _enablePendingPurchases - })); + return BillingResultWrapper.fromJson((await channel + .invokeMapMethod( + "BillingClient#startConnection(BillingClientStateListener)", + { + 'handle': disconnectCallbacks.length - 1, + 'enablePendingPurchases': _enablePendingPurchases + })) ?? + {}); } /// Calls @@ -137,15 +138,16 @@ class BillingClient { /// `SkuDetailsParams` as direct arguments instead of requiring it constructed /// and passed in as a class. Future querySkuDetails( - {@required SkuType skuType, @required List skusList}) async { + {required SkuType skuType, required List skusList}) async { final Map arguments = { 'skuType': SkuTypeConverter().toJson(skuType), 'skusList': skusList }; - return SkuDetailsResponseWrapper.fromJson(await channel.invokeMapMethod< - String, dynamic>( - 'BillingClient#querySkuDetailsAsync(SkuDetailsParams, SkuDetailsResponseListener)', - arguments)); + return SkuDetailsResponseWrapper.fromJson((await channel.invokeMapMethod< + String, dynamic>( + 'BillingClient#querySkuDetailsAsync(SkuDetailsParams, SkuDetailsResponseListener)', + arguments)) ?? + {}); } /// Attempt to launch the Play Billing Flow for a given [skuDetails]. @@ -172,16 +174,17 @@ class BillingClient { /// and [the given /// accountId](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.Builder.html#setAccountId(java.lang.String)). Future launchBillingFlow( - {@required String sku, String accountId}) async { + {required String sku, String? accountId}) async { assert(sku != null); final Map arguments = { 'sku': sku, 'accountId': accountId, }; return BillingResultWrapper.fromJson( - await channel.invokeMapMethod( - 'BillingClient#launchBillingFlow(Activity, BillingFlowParams)', - arguments)); + (await channel.invokeMapMethod( + 'BillingClient#launchBillingFlow(Activity, BillingFlowParams)', + arguments)) ?? + {}); } /// Fetches recent purchases for the given [SkuType]. @@ -197,10 +200,12 @@ class BillingClient { /// skutype)`](https://developer.android.com/reference/com/android/billingclient/api/BillingClient#querypurchases). Future queryPurchases(SkuType skuType) async { assert(skuType != null); - return PurchasesResultWrapper.fromJson(await channel - .invokeMapMethod( - 'BillingClient#queryPurchases(String)', - {'skuType': SkuTypeConverter().toJson(skuType)})); + return PurchasesResultWrapper.fromJson((await channel + .invokeMapMethod( + 'BillingClient#queryPurchases(String)', { + 'skuType': SkuTypeConverter().toJson(skuType) + })) ?? + {}); } /// Fetches purchase history for the given [SkuType]. @@ -218,10 +223,13 @@ class BillingClient { /// listener)`](https://developer.android.com/reference/com/android/billingclient/api/BillingClient#querypurchasehistoryasync). Future queryPurchaseHistory(SkuType skuType) async { assert(skuType != null); - return PurchasesHistoryResult.fromJson(await channel.invokeMapMethod( - 'BillingClient#queryPurchaseHistoryAsync(String, PurchaseHistoryResponseListener)', - {'skuType': SkuTypeConverter().toJson(skuType)})); + return PurchasesHistoryResult.fromJson((await channel.invokeMapMethod< + String, dynamic>( + 'BillingClient#queryPurchaseHistoryAsync(String, PurchaseHistoryResponseListener)', + { + 'skuType': SkuTypeConverter().toJson(skuType) + })) ?? + {}); } /// Consumes a given in-app product. @@ -229,20 +237,20 @@ class BillingClient { /// Consuming can only be done on an item that's owned, and as a result of consumption, the user will no longer own it. /// Consumption is done asynchronously. The method returns a Future containing a [BillingResultWrapper]. /// - /// The `purchaseToken` must not be null. /// The `developerPayload` is the developer data associated with the purchase to be consumed, it defaults to null. /// /// This wraps [`BillingClient#consumeAsync(String, ConsumeResponseListener)`](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html#consumeAsync(java.lang.String,%20com.android.billingclient.api.ConsumeResponseListener)) Future consumeAsync(String purchaseToken, - {String developerPayload}) async { + {String? developerPayload}) async { assert(purchaseToken != null); - return BillingResultWrapper.fromJson(await channel - .invokeMapMethod( - 'BillingClient#consumeAsync(String, ConsumeResponseListener)', - { - 'purchaseToken': purchaseToken, - 'developerPayload': developerPayload, - })); + return BillingResultWrapper.fromJson((await channel + .invokeMapMethod( + 'BillingClient#consumeAsync(String, ConsumeResponseListener)', + { + 'purchaseToken': purchaseToken, + 'developerPayload': developerPayload, + })) ?? + {}); } /// Acknowledge an in-app purchase. @@ -261,20 +269,20 @@ class BillingClient { /// Please refer to [acknowledge](https://developer.android.com/google/play/billing/billing_library_overview#acknowledge) for more /// details. /// - /// The `purchaseToken` must not be null. /// The `developerPayload` is the developer data associated with the purchase to be consumed, it defaults to null. /// /// This wraps [`BillingClient#acknowledgePurchase(String, AcknowledgePurchaseResponseListener)`](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html#acknowledgePurchase(com.android.billingclient.api.AcknowledgePurchaseParams,%20com.android.billingclient.api.AcknowledgePurchaseResponseListener)) Future acknowledgePurchase(String purchaseToken, - {String developerPayload}) async { + {String? developerPayload}) async { assert(purchaseToken != null); - return BillingResultWrapper.fromJson(await channel.invokeMapMethod( - 'BillingClient#(AcknowledgePurchaseParams params, (AcknowledgePurchaseParams, AcknowledgePurchaseResponseListener)', - { - 'purchaseToken': purchaseToken, - 'developerPayload': developerPayload, - })); + return BillingResultWrapper.fromJson((await channel.invokeMapMethod( + 'BillingClient#(AcknowledgePurchaseParams params, (AcknowledgePurchaseParams, AcknowledgePurchaseResponseListener)', + { + 'purchaseToken': purchaseToken, + 'developerPayload': developerPayload, + })) ?? + {}); } /// The method call handler for [channel]. @@ -283,15 +291,15 @@ class BillingClient { switch (call.method) { case kOnPurchasesUpdated: // The purchases updated listener is a singleton. - assert(_callbacks[kOnPurchasesUpdated].length == 1); + assert(_callbacks[kOnPurchasesUpdated]!.length == 1); final PurchasesUpdatedListener listener = - _callbacks[kOnPurchasesUpdated].first; + _callbacks[kOnPurchasesUpdated]!.first as PurchasesUpdatedListener; listener(PurchasesResultWrapper.fromJson( call.arguments.cast())); break; case _kOnBillingServiceDisconnected: final int handle = call.arguments['handle']; - await _callbacks[_kOnBillingServiceDisconnected][handle](); + await _callbacks[_kOnBillingServiceDisconnected]![handle](); break; } } diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart index 966c89176b1e..30828d8882a7 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart @@ -12,40 +12,50 @@ part 'enum_converters.g.dart'; /// /// Use these in `@JsonSerializable()` classes by annotating them with /// `@BillingResponseConverter()`. -class BillingResponseConverter implements JsonConverter { +class BillingResponseConverter implements JsonConverter { /// Default const constructor. const BillingResponseConverter(); @override - BillingResponse fromJson(int json) => _$enumDecode( - _$BillingResponseEnumMap.cast(), json); + BillingResponse fromJson(int? json) { + if (json == null) { + return BillingResponse.error; + } + return _$enumDecode( + _$BillingResponseEnumMap.cast(), json); + } @override - int toJson(BillingResponse object) => _$BillingResponseEnumMap[object]; + int toJson(BillingResponse object) => _$BillingResponseEnumMap[object]!; } /// Serializer for [SkuType]. /// /// Use these in `@JsonSerializable()` classes by annotating them with /// `@SkuTypeConverter()`. -class SkuTypeConverter implements JsonConverter { +class SkuTypeConverter implements JsonConverter { /// Default const constructor. const SkuTypeConverter(); @override - SkuType fromJson(String json) => - _$enumDecode(_$SkuTypeEnumMap.cast(), json); + SkuType fromJson(String? json) { + if (json == null) { + return SkuType.inapp; + } + return _$enumDecode( + _$SkuTypeEnumMap.cast(), json); + } @override - String toJson(SkuType object) => _$SkuTypeEnumMap[object]; + String toJson(SkuType object) => _$SkuTypeEnumMap[object]!; } // Define a class so we generate serializer helper methods for the enums @JsonSerializable() class _SerializedEnums { - BillingResponse response; - SkuType type; - PurchaseStateWrapper purchaseState; + late BillingResponse response; + late SkuType type; + late PurchaseStateWrapper purchaseState; } /// Serializer for [PurchaseStateWrapper]. @@ -53,18 +63,23 @@ class _SerializedEnums { /// Use these in `@JsonSerializable()` classes by annotating them with /// `@PurchaseStateConverter()`. class PurchaseStateConverter - implements JsonConverter { + implements JsonConverter { /// Default const constructor. const PurchaseStateConverter(); @override - PurchaseStateWrapper fromJson(int json) => _$enumDecode( - _$PurchaseStateWrapperEnumMap.cast(), - json); + PurchaseStateWrapper fromJson(int? json) { + if (json == null) { + return PurchaseStateWrapper.unspecified_state; + } + return _$enumDecode( + _$PurchaseStateWrapperEnumMap.cast(), + json); + } @override int toJson(PurchaseStateWrapper object) => - _$PurchaseStateWrapperEnumMap[object]; + _$PurchaseStateWrapperEnumMap[object]!; /// Converts the purchase state stored in `object` to a [PurchaseStatus]. /// @@ -78,7 +93,5 @@ class PurchaseStateConverter case PurchaseStateWrapper.unspecified_state: return PurchaseStatus.error; } - - throw ArgumentError('$object isn\'t mapped to PurchaseStatus'); } } diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.g.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.g.dart index 947700df64df..5d59dd8888b7 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.g.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.g.dart @@ -21,25 +21,30 @@ Map _$_SerializedEnumsToJson(_SerializedEnums instance) => 'purchaseState': _$PurchaseStateWrapperEnumMap[instance.purchaseState], }; -T _$enumDecode( - Map enumValues, - dynamic source, { - T unknownValue, +K _$enumDecode( + Map enumValues, + Object? source, { + K? unknownValue, }) { if (source == null) { - throw ArgumentError('A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}'); + throw ArgumentError( + 'A value must be provided. Supported values: ' + '${enumValues.values.join(', ')}', + ); } - final value = enumValues.entries - .singleWhere((e) => e.value == source, orElse: () => null) - ?.key; - - if (value == null && unknownValue == null) { - throw ArgumentError('`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}'); - } - return value ?? unknownValue; + return enumValues.entries.singleWhere( + (e) => e.value == source, + orElse: () { + if (unknownValue == null) { + throw ArgumentError( + '`$source` is not one of the supported values: ' + '${enumValues.values.join(', ')}', + ); + } + return MapEntry(unknownValue, enumValues.values.first); + }, + ).key; } const _$BillingResponseEnumMap = { diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart index 8bdd738e7ed3..05472278968a 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart @@ -27,26 +27,27 @@ class PurchaseWrapper { /// Creates a purchase wrapper with the given purchase details. @visibleForTesting PurchaseWrapper( - {@required this.orderId, - @required this.packageName, - @required this.purchaseTime, - @required this.purchaseToken, - @required this.signature, - @required this.sku, - @required this.isAutoRenewing, - @required this.originalJson, - @required this.developerPayload, - @required this.isAcknowledged, - @required this.purchaseState}); + {required this.orderId, + required this.packageName, + required this.purchaseTime, + required this.purchaseToken, + required this.signature, + required this.sku, + required this.isAutoRenewing, + required this.originalJson, + this.developerPayload, + required this.isAcknowledged, + required this.purchaseState}); /// Factory for creating a [PurchaseWrapper] from a [Map] with the purchase details. - factory PurchaseWrapper.fromJson(Map map) => _$PurchaseWrapperFromJson(map); + factory PurchaseWrapper.fromJson(Map map) => + _$PurchaseWrapperFromJson(map); @override bool operator ==(Object other) { if (identical(other, this)) return true; if (other.runtimeType != runtimeType) return false; - final PurchaseWrapper typedOther = other; + final PurchaseWrapper typedOther = other as PurchaseWrapper; return typedOther.orderId == orderId && typedOther.packageName == packageName && typedOther.purchaseTime == purchaseTime && @@ -74,22 +75,28 @@ class PurchaseWrapper { /// The unique ID for this purchase. Corresponds to the Google Payments order /// ID. + @JsonKey(defaultValue: '') final String orderId; /// The package name the purchase was made from. + @JsonKey(defaultValue: '') final String packageName; /// When the purchase was made, as an epoch timestamp. + @JsonKey(defaultValue: 0) final int purchaseTime; /// A unique ID for a given [SkuDetailsWrapper], user, and purchase. + @JsonKey(defaultValue: '') final String purchaseToken; /// Signature of purchase data, signed with the developer's private key. Uses /// RSASSA-PKCS1-v1_5. + @JsonKey(defaultValue: '') final String signature; /// The product ID of this purchase. + @JsonKey(defaultValue: '') final String sku; /// True for subscriptions that renew automatically. Does not apply to @@ -97,6 +104,8 @@ class PurchaseWrapper { /// /// For [SkuType.subs] this means that the subscription is canceled when it is /// false. + /// + /// The value is `false` for [SkuType.inapp] products. final bool isAutoRenewing; /// Details about this purchase, in JSON. @@ -105,15 +114,19 @@ class PurchaseWrapper { /// device"](https://developer.android.com/google/play/billing/billing_library_overview#Verify-purchase-device). /// Note though that verifying a purchase locally is inherently insecure (see /// the article for more details). + @JsonKey(defaultValue: '') final String originalJson; /// The payload specified by the developer when the purchase was acknowledged or consumed. - final String developerPayload; + /// + /// The value is `null` if it wasn't specified when the purchase was acknowledged or consumed. + final String? developerPayload; /// Whether the purchase has been acknowledged. /// /// A successful purchase has to be acknowledged within 3 days after the purchase via [BillingClient.acknowledgePurchase]. /// * See also [BillingClient.acknowledgePurchase] for more details on acknowledging purchases. + @JsonKey(defaultValue: false) final bool isAcknowledged; /// Determines the current state of the purchase. @@ -137,29 +150,33 @@ class PurchaseHistoryRecordWrapper { /// Creates a [PurchaseHistoryRecordWrapper] with the given record details. @visibleForTesting PurchaseHistoryRecordWrapper({ - @required this.purchaseTime, - @required this.purchaseToken, - @required this.signature, - @required this.sku, - @required this.originalJson, - @required this.developerPayload, + required this.purchaseTime, + required this.purchaseToken, + required this.signature, + required this.sku, + required this.originalJson, + required this.developerPayload, }); /// Factory for creating a [PurchaseHistoryRecordWrapper] from a [Map] with the record details. - factory PurchaseHistoryRecordWrapper.fromJson(Map map) => + factory PurchaseHistoryRecordWrapper.fromJson(Map map) => _$PurchaseHistoryRecordWrapperFromJson(map); /// When the purchase was made, as an epoch timestamp. + @JsonKey(defaultValue: 0) final int purchaseTime; /// A unique ID for a given [SkuDetailsWrapper], user, and purchase. + @JsonKey(defaultValue: '') final String purchaseToken; /// Signature of purchase data, signed with the developer's private key. Uses /// RSASSA-PKCS1-v1_5. + @JsonKey(defaultValue: '') final String signature; /// The product ID of this purchase. + @JsonKey(defaultValue: '') final String sku; /// Details about this purchase, in JSON. @@ -168,16 +185,20 @@ class PurchaseHistoryRecordWrapper { /// device"](https://developer.android.com/google/play/billing/billing_library_overview#Verify-purchase-device). /// Note though that verifying a purchase locally is inherently insecure (see /// the article for more details). + @JsonKey(defaultValue: '') final String originalJson; /// The payload specified by the developer when the purchase was acknowledged or consumed. - final String developerPayload; + /// + /// The value is `null` if it wasn't specified when the purchase was acknowledged or consumed. + final String? developerPayload; @override bool operator ==(Object other) { if (identical(other, this)) return true; if (other.runtimeType != runtimeType) return false; - final PurchaseHistoryRecordWrapper typedOther = other; + final PurchaseHistoryRecordWrapper typedOther = + other as PurchaseHistoryRecordWrapper; return typedOther.purchaseTime == purchaseTime && typedOther.purchaseToken == purchaseToken && typedOther.signature == signature && @@ -203,9 +224,9 @@ class PurchaseHistoryRecordWrapper { class PurchasesResultWrapper { /// Creates a [PurchasesResultWrapper] with the given purchase result details. PurchasesResultWrapper( - {@required this.responseCode, - @required this.billingResult, - @required this.purchasesList}); + {required this.responseCode, + required this.billingResult, + required this.purchasesList}); /// Factory for creating a [PurchaseResultWrapper] from a [Map] with the result details. factory PurchasesResultWrapper.fromJson(Map map) => @@ -215,7 +236,7 @@ class PurchasesResultWrapper { bool operator ==(Object other) { if (identical(other, this)) return true; if (other.runtimeType != runtimeType) return false; - final PurchasesResultWrapper typedOther = other; + final PurchasesResultWrapper typedOther = other as PurchasesResultWrapper; return typedOther.responseCode == responseCode && typedOther.purchasesList == purchasesList && typedOther.billingResult == billingResult; @@ -236,6 +257,7 @@ class PurchasesResultWrapper { /// The list of successful purchases made in this transaction. /// /// May be empty, especially if [responseCode] is not [BillingResponse.ok]. + @JsonKey(defaultValue: []) final List purchasesList; } @@ -248,7 +270,7 @@ class PurchasesResultWrapper { class PurchasesHistoryResult { /// Creates a [PurchasesHistoryResult] with the provided history. PurchasesHistoryResult( - {@required this.billingResult, @required this.purchaseHistoryRecordList}); + {required this.billingResult, required this.purchaseHistoryRecordList}); /// Factory for creating a [PurchasesHistoryResult] from a [Map] with the history result details. factory PurchasesHistoryResult.fromJson(Map map) => @@ -258,7 +280,7 @@ class PurchasesHistoryResult { bool operator ==(Object other) { if (identical(other, this)) return true; if (other.runtimeType != runtimeType) return false; - final PurchasesHistoryResult typedOther = other; + final PurchasesHistoryResult typedOther = other as PurchasesHistoryResult; return typedOther.purchaseHistoryRecordList == purchaseHistoryRecordList && typedOther.billingResult == billingResult; } @@ -272,6 +294,7 @@ class PurchasesHistoryResult { /// The list of queried purchase history records. /// /// May be empty, especially if [billingResult.responseCode] is not [BillingResponse.ok]. + @JsonKey(defaultValue: []) final List purchaseHistoryRecordList; } diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.g.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.g.dart index 3d555890b31e..5f0d936e09c2 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.g.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.g.dart @@ -8,18 +8,18 @@ part of 'purchase_wrapper.dart'; PurchaseWrapper _$PurchaseWrapperFromJson(Map json) { return PurchaseWrapper( - orderId: json['orderId'] as String, - packageName: json['packageName'] as String, - purchaseTime: json['purchaseTime'] as int, - purchaseToken: json['purchaseToken'] as String, - signature: json['signature'] as String, - sku: json['sku'] as String, + orderId: json['orderId'] as String? ?? '', + packageName: json['packageName'] as String? ?? '', + purchaseTime: json['purchaseTime'] as int? ?? 0, + purchaseToken: json['purchaseToken'] as String? ?? '', + signature: json['signature'] as String? ?? '', + sku: json['sku'] as String? ?? '', isAutoRenewing: json['isAutoRenewing'] as bool, - originalJson: json['originalJson'] as String, - developerPayload: json['developerPayload'] as String, - isAcknowledged: json['isAcknowledged'] as bool, + originalJson: json['originalJson'] as String? ?? '', + developerPayload: json['developerPayload'] as String?, + isAcknowledged: json['isAcknowledged'] as bool? ?? false, purchaseState: - const PurchaseStateConverter().fromJson(json['purchaseState'] as int), + const PurchaseStateConverter().fromJson(json['purchaseState'] as int?), ); } @@ -41,12 +41,12 @@ Map _$PurchaseWrapperToJson(PurchaseWrapper instance) => PurchaseHistoryRecordWrapper _$PurchaseHistoryRecordWrapperFromJson(Map json) { return PurchaseHistoryRecordWrapper( - purchaseTime: json['purchaseTime'] as int, - purchaseToken: json['purchaseToken'] as String, - signature: json['signature'] as String, - sku: json['sku'] as String, - originalJson: json['originalJson'] as String, - developerPayload: json['developerPayload'] as String, + purchaseTime: json['purchaseTime'] as int? ?? 0, + purchaseToken: json['purchaseToken'] as String? ?? '', + signature: json['signature'] as String? ?? '', + sku: json['sku'] as String? ?? '', + originalJson: json['originalJson'] as String? ?? '', + developerPayload: json['developerPayload'] as String?, ); } @@ -64,11 +64,16 @@ Map _$PurchaseHistoryRecordWrapperToJson( PurchasesResultWrapper _$PurchasesResultWrapperFromJson(Map json) { return PurchasesResultWrapper( responseCode: - const BillingResponseConverter().fromJson(json['responseCode'] as int), - billingResult: BillingResultWrapper.fromJson(json['billingResult'] as Map), - purchasesList: (json['purchasesList'] as List) - .map((e) => PurchaseWrapper.fromJson(e as Map)) - .toList(), + const BillingResponseConverter().fromJson(json['responseCode'] as int?), + billingResult: + BillingResultWrapper.fromJson((json['billingResult'] as Map?)?.map( + (k, e) => MapEntry(k as String, e), + )), + purchasesList: (json['purchasesList'] as List?) + ?.map((e) => + PurchaseWrapper.fromJson(Map.from(e as Map))) + .toList() ?? + [], ); } @@ -83,10 +88,16 @@ Map _$PurchasesResultWrapperToJson( PurchasesHistoryResult _$PurchasesHistoryResultFromJson(Map json) { return PurchasesHistoryResult( - billingResult: BillingResultWrapper.fromJson(json['billingResult'] as Map), - purchaseHistoryRecordList: (json['purchaseHistoryRecordList'] as List) - .map((e) => PurchaseHistoryRecordWrapper.fromJson(e as Map)) - .toList(), + billingResult: + BillingResultWrapper.fromJson((json['billingResult'] as Map?)?.map( + (k, e) => MapEntry(k as String, e), + )), + purchaseHistoryRecordList: + (json['purchaseHistoryRecordList'] as List?) + ?.map((e) => PurchaseHistoryRecordWrapper.fromJson( + Map.from(e as Map))) + .toList() ?? + [], ); } diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart index db65e2064a14..b3872958e5b9 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart @@ -13,6 +13,13 @@ import 'enum_converters.dart'; // rebuild and watch for further changes. part 'sku_details_wrapper.g.dart'; +/// The error message shown when the map represents billing result is invalid from method channel. +/// +/// This usually indicates a series underlining code issue in the plugin. +@visibleForTesting +const kInvalidBillingResultErrorMessage = + 'Invalid billing result map from method channel.'; + /// Dart wrapper around [`com.android.billingclient.api.SkuDetails`](https://developer.android.com/reference/com/android/billingclient/api/SkuDetails). /// /// Contains the details of an available product in Google Play Billing. @@ -22,22 +29,22 @@ class SkuDetailsWrapper { /// Creates a [SkuDetailsWrapper] with the given purchase details. @visibleForTesting SkuDetailsWrapper({ - @required this.description, - @required this.freeTrialPeriod, - @required this.introductoryPrice, - @required this.introductoryPriceMicros, - @required this.introductoryPriceCycles, - @required this.introductoryPricePeriod, - @required this.price, - @required this.priceAmountMicros, - @required this.priceCurrencyCode, - @required this.sku, - @required this.subscriptionPeriod, - @required this.title, - @required this.type, - @required this.isRewarded, - @required this.originalPrice, - @required this.originalPriceAmountMicros, + required this.description, + required this.freeTrialPeriod, + required this.introductoryPrice, + required this.introductoryPriceMicros, + required this.introductoryPriceCycles, + required this.introductoryPricePeriod, + required this.price, + required this.priceAmountMicros, + required this.priceCurrencyCode, + required this.sku, + required this.subscriptionPeriod, + required this.title, + required this.type, + required this.isRewarded, + required this.originalPrice, + required this.originalPriceAmountMicros, }); /// Constructs an instance of this from a key value map of data. @@ -45,55 +52,70 @@ class SkuDetailsWrapper { /// The map needs to have named string keys with values matching the names and /// types of all of the members on this class. @visibleForTesting - factory SkuDetailsWrapper.fromJson(Map map) => + factory SkuDetailsWrapper.fromJson(Map map) => _$SkuDetailsWrapperFromJson(map); /// Textual description of the product. + @JsonKey(defaultValue: '') final String description; /// Trial period in ISO 8601 format. + @JsonKey(defaultValue: '') final String freeTrialPeriod; /// Introductory price, only applies to [SkuType.subs]. Formatted ("$0.99"). + @JsonKey(defaultValue: '') final String introductoryPrice; /// [introductoryPrice] in micro-units 990000 + @JsonKey(defaultValue: '') final String introductoryPriceMicros; /// The number of billing perios that [introductoryPrice] is valid for ("2"). + @JsonKey(defaultValue: '') final String introductoryPriceCycles; /// The billing period of [introductoryPrice], in ISO 8601 format. + @JsonKey(defaultValue: '') final String introductoryPricePeriod; /// Formatted with currency symbol ("$0.99"). + @JsonKey(defaultValue: '') final String price; /// [price] in micro-units ("990000"). + @JsonKey(defaultValue: 0) final int priceAmountMicros; /// [price] ISO 4217 currency code. + @JsonKey(defaultValue: '') final String priceCurrencyCode; /// The product ID in Google Play Console. + @JsonKey(defaultValue: '') final String sku; /// Applies to [SkuType.subs], formatted in ISO 8601. + @JsonKey(defaultValue: '') final String subscriptionPeriod; /// The product's title. + @JsonKey(defaultValue: '') final String title; /// The [SkuType] of the product. final SkuType type; /// False if the product is paid. + @JsonKey(defaultValue: false) final bool isRewarded; /// The original price that the user purchased this product for. + @JsonKey(defaultValue: '') final String originalPrice; /// [originalPrice] in micro-units ("990000"). + @JsonKey(defaultValue: 0) final int originalPriceAmountMicros; @override @@ -150,7 +172,7 @@ class SkuDetailsResponseWrapper { /// Creates a [SkuDetailsResponseWrapper] with the given purchase details. @visibleForTesting SkuDetailsResponseWrapper( - {@required this.billingResult, this.skuDetailsList}); + {required this.billingResult, required this.skuDetailsList}); /// Constructs an instance of this from a key value map of data. /// @@ -163,6 +185,7 @@ class SkuDetailsResponseWrapper { final BillingResultWrapper billingResult; /// A list of [SkuDetailsWrapper] matching the query to [BillingClient.querySkuDetails]. + @JsonKey(defaultValue: []) final List skuDetailsList; @override @@ -186,22 +209,29 @@ class SkuDetailsResponseWrapper { @BillingResponseConverter() class BillingResultWrapper { /// Constructs the object with [responseCode] and [debugMessage]. - BillingResultWrapper({@required this.responseCode, this.debugMessage}); + BillingResultWrapper({required this.responseCode, this.debugMessage}); /// Constructs an instance of this from a key value map of data. /// /// The map needs to have named string keys with values matching the names and /// types of all of the members on this class. - factory BillingResultWrapper.fromJson(Map map) => - _$BillingResultWrapperFromJson(map); + factory BillingResultWrapper.fromJson(Map? map) { + if (map == null || map.isEmpty) { + return BillingResultWrapper( + responseCode: BillingResponse.error, + debugMessage: kInvalidBillingResultErrorMessage); + } + return _$BillingResultWrapperFromJson(map); + } /// Response code returned in the Play Billing API calls. final BillingResponse responseCode; /// Debug message returned in the Play Billing API calls. /// + /// Defaults to `null`. /// This message uses an en-US locale and should not be shown to users. - final String debugMessage; + final String? debugMessage; @override bool operator ==(dynamic other) { diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.g.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.g.dart index 70bde9318f03..247dbd54b666 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.g.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.g.dart @@ -8,22 +8,22 @@ part of 'sku_details_wrapper.dart'; SkuDetailsWrapper _$SkuDetailsWrapperFromJson(Map json) { return SkuDetailsWrapper( - description: json['description'] as String, - freeTrialPeriod: json['freeTrialPeriod'] as String, - introductoryPrice: json['introductoryPrice'] as String, - introductoryPriceMicros: json['introductoryPriceMicros'] as String, - introductoryPriceCycles: json['introductoryPriceCycles'] as String, - introductoryPricePeriod: json['introductoryPricePeriod'] as String, - price: json['price'] as String, - priceAmountMicros: json['priceAmountMicros'] as int, - priceCurrencyCode: json['priceCurrencyCode'] as String, - sku: json['sku'] as String, - subscriptionPeriod: json['subscriptionPeriod'] as String, - title: json['title'] as String, - type: const SkuTypeConverter().fromJson(json['type'] as String), - isRewarded: json['isRewarded'] as bool, - originalPrice: json['originalPrice'] as String, - originalPriceAmountMicros: json['originalPriceAmountMicros'] as int, + description: json['description'] as String? ?? '', + freeTrialPeriod: json['freeTrialPeriod'] as String? ?? '', + introductoryPrice: json['introductoryPrice'] as String? ?? '', + introductoryPriceMicros: json['introductoryPriceMicros'] as String? ?? '', + introductoryPriceCycles: json['introductoryPriceCycles'] as String? ?? '', + introductoryPricePeriod: json['introductoryPricePeriod'] as String? ?? '', + price: json['price'] as String? ?? '', + priceAmountMicros: json['priceAmountMicros'] as int? ?? 0, + priceCurrencyCode: json['priceCurrencyCode'] as String? ?? '', + sku: json['sku'] as String? ?? '', + subscriptionPeriod: json['subscriptionPeriod'] as String? ?? '', + title: json['title'] as String? ?? '', + type: const SkuTypeConverter().fromJson(json['type'] as String?), + isRewarded: json['isRewarded'] as bool? ?? false, + originalPrice: json['originalPrice'] as String? ?? '', + originalPriceAmountMicros: json['originalPriceAmountMicros'] as int? ?? 0, ); } @@ -49,10 +49,15 @@ Map _$SkuDetailsWrapperToJson(SkuDetailsWrapper instance) => SkuDetailsResponseWrapper _$SkuDetailsResponseWrapperFromJson(Map json) { return SkuDetailsResponseWrapper( - billingResult: BillingResultWrapper.fromJson(json['billingResult'] as Map), - skuDetailsList: (json['skuDetailsList'] as List) - .map((e) => SkuDetailsWrapper.fromJson(e as Map)) - .toList(), + billingResult: + BillingResultWrapper.fromJson((json['billingResult'] as Map?)?.map( + (k, e) => MapEntry(k as String, e), + )), + skuDetailsList: (json['skuDetailsList'] as List?) + ?.map((e) => + SkuDetailsWrapper.fromJson(Map.from(e as Map))) + .toList() ?? + [], ); } @@ -66,8 +71,8 @@ Map _$SkuDetailsResponseWrapperToJson( BillingResultWrapper _$BillingResultWrapperFromJson(Map json) { return BillingResultWrapper( responseCode: - const BillingResponseConverter().fromJson(json['responseCode'] as int), - debugMessage: json['debugMessage'] as String, + const BillingResponseConverter().fromJson(json['responseCode'] as int?), + debugMessage: json['debugMessage'] as String?, ); } diff --git a/packages/in_app_purchase/lib/src/channel.dart b/packages/in_app_purchase/lib/src/channel.dart index a0b92b5d5f1e..5d140e281e7b 100644 --- a/packages/in_app_purchase/lib/src/channel.dart +++ b/packages/in_app_purchase/lib/src/channel.dart @@ -4,13 +4,6 @@ import 'package:flutter/services.dart'; -/// Method channel for the plugin's platform<-->Dart calls (all but the -/// ios->Dart calls which are carried over the [callbackChannel]). +/// Method channel for the plugin's platform<-->Dart calls. const MethodChannel channel = MethodChannel('plugins.flutter.io/in_app_purchase'); - -/// Method channel for the plugin's ios->Dart calls. -// This is in a separate channel due to historic reasons only. -// TODO(cyanglaz): Remove this. https://github.com/flutter/flutter/issues/69225 -const MethodChannel callbackChannel = - MethodChannel('plugins.flutter.io/in_app_purchase_callback'); diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart b/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart index a244ab13fc28..50560a666a40 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart @@ -21,9 +21,9 @@ class AppStoreConnection implements InAppPurchaseConnection { /// Returns the singleton instance of the [AppStoreConnection] that should be /// used across the app. static AppStoreConnection get instance => _getOrCreateInstance(); - static AppStoreConnection _instance; - static SKPaymentQueueWrapper _skPaymentQueueWrapper; - static _TransactionObserver _observer; + static AppStoreConnection? _instance; + static late SKPaymentQueueWrapper _skPaymentQueueWrapper; + static late _TransactionObserver _observer; /// Creates an [AppStoreConnection] object. /// @@ -41,55 +41,61 @@ class AppStoreConnection implements InAppPurchaseConnection { static AppStoreConnection _getOrCreateInstance() { if (_instance != null) { - return _instance; + return _instance!; } _instance = AppStoreConnection(); _skPaymentQueueWrapper = SKPaymentQueueWrapper(); _observer = _TransactionObserver(StreamController.broadcast()); _skPaymentQueueWrapper.setTransactionObserver(observer); - return _instance; + return _instance!; } @override Future isAvailable() => SKPaymentQueueWrapper.canMakePayments(); @override - Future buyNonConsumable({@required PurchaseParam purchaseParam}) async { + Future buyNonConsumable({required PurchaseParam purchaseParam}) async { await _skPaymentQueueWrapper.addPayment(SKPaymentWrapper( productIdentifier: purchaseParam.productDetails.id, quantity: 1, applicationUsername: purchaseParam.applicationUserName, - simulatesAskToBuyInSandbox: purchaseParam.sandboxTesting, + simulatesAskToBuyInSandbox: purchaseParam.simulatesAskToBuyInSandbox || + // ignore: deprecated_member_use_from_same_package + purchaseParam.sandboxTesting, requestData: null)); return true; // There's no error feedback from iOS here to return. } @override Future buyConsumable( - {@required PurchaseParam purchaseParam, bool autoConsume = true}) { + {required PurchaseParam purchaseParam, bool autoConsume = true}) { assert(autoConsume == true, 'On iOS, we should always auto consume'); return buyNonConsumable(purchaseParam: purchaseParam); } @override Future completePurchase(PurchaseDetails purchase, - {String developerPayload}) async { + {String? developerPayload}) async { + if (purchase.skPaymentTransaction == null) { + throw ArgumentError( + 'completePurchase unsuccessful. The `purchase.skPaymentTransaction` is not valid'); + } await _skPaymentQueueWrapper - .finishTransaction(purchase.skPaymentTransaction); + .finishTransaction(purchase.skPaymentTransaction!); return BillingResultWrapper(responseCode: BillingResponse.ok); } @override Future consumePurchase(PurchaseDetails purchase, - {String developerPayload}) { + {String? developerPayload}) { throw UnsupportedError('consume purchase is not available on Android'); } @override Future queryPastPurchases( - {String applicationUserName}) async { - IAPError error; + {String? applicationUserName}) async { + IAPError? error; List pastPurchases = []; try { @@ -98,7 +104,6 @@ class AppStoreConnection implements InAppPurchaseConnection { await _observer.getRestoredTransactions( queue: _skPaymentQueueWrapper, applicationUserName: applicationUserName); - _observer.cleanUpRestoredTransactions(); pastPurchases = restoredTransactions.map((SKPaymentTransactionWrapper transaction) { assert(transaction.transactionState == @@ -110,16 +115,17 @@ class AppStoreConnection implements InAppPurchaseConnection { ? IAPError( source: IAPSource.AppStore, code: kPurchaseErrorCode, - message: transaction.error.domain, - details: transaction.error.userInfo, + message: transaction.error?.domain ?? '', + details: transaction.error?.userInfo, ) : null; }).toList(); + _observer.cleanUpRestoredTransactions(); } on PlatformException catch (e) { error = IAPError( source: IAPSource.AppStore, code: e.code, - message: e.message, + message: e.message ?? '', details: e.details); } on SKError catch (e) { error = IAPError( @@ -133,9 +139,12 @@ class AppStoreConnection implements InAppPurchaseConnection { } @override - Future refreshPurchaseVerificationData() async { + Future refreshPurchaseVerificationData() async { await SKRequestMaker().startRefreshReceiptRequest(); - String receipt = await SKReceiptManager.retrieveReceiptData(); + final String? receipt = await SKReceiptManager.retrieveReceiptData(); + if (receipt == null) { + return null; + } return PurchaseVerificationData( localVerificationData: receipt, serverVerificationData: receipt, @@ -152,7 +161,7 @@ class AppStoreConnection implements InAppPurchaseConnection { Set identifiers) async { final SKRequestMaker requestMaker = SKRequestMaker(); SkProductResponseWrapper response; - PlatformException exception; + PlatformException? exception; try { response = await requestMaker.startProductRequest(identifiers.toList()); } on PlatformException catch (e) { @@ -167,7 +176,7 @@ class AppStoreConnection implements InAppPurchaseConnection { ProductDetails.fromSKProduct(productWrapper)) .toList(); } - List invalidIdentifiers = response.invalidProductIdentifiers ?? []; + List invalidIdentifiers = response.invalidProductIdentifiers; if (productDetails.isEmpty) { invalidIdentifiers = identifiers.toList(); } @@ -179,7 +188,7 @@ class AppStoreConnection implements InAppPurchaseConnection { : IAPError( source: IAPSource.AppStore, code: exception.code, - message: exception.message, + message: exception.message ?? '', details: exception.details), ); return productDetailsResponse; @@ -189,27 +198,27 @@ class AppStoreConnection implements InAppPurchaseConnection { class _TransactionObserver implements SKTransactionObserverWrapper { final StreamController> purchaseUpdatedController; - Completer> _restoreCompleter; - List _restoredTransactions; - String _receiptData; + Completer>? _restoreCompleter; + List _restoredTransactions = + []; + late String _receiptData; _TransactionObserver(this.purchaseUpdatedController); Future> getRestoredTransactions( - {@required SKPaymentQueueWrapper queue, String applicationUserName}) { - assert(queue != null); + {required SKPaymentQueueWrapper queue, String? applicationUserName}) { _restoreCompleter = Completer(); queue.restoreTransactions(applicationUserName: applicationUserName); - return _restoreCompleter.future; + return _restoreCompleter!.future; } void cleanUpRestoredTransactions() { - _restoredTransactions = null; + _restoredTransactions.clear(); _restoreCompleter = null; } void updatedTransactions( - {List transactions}) async { + {required List transactions}) async { if (_restoreCompleter != null) { if (_restoredTransactions == null) { _restoredTransactions = []; @@ -233,19 +242,20 @@ class _TransactionObserver implements SKTransactionObserverWrapper { }).toList()); } - void removedTransactions({List transactions}) {} + void removedTransactions( + {required List transactions}) {} /// Triggered when there is an error while restoring transactions. - void restoreCompletedTransactionsFailed({SKError error}) { - _restoreCompleter.completeError(error); + void restoreCompletedTransactionsFailed({required SKError error}) { + _restoreCompleter!.completeError(error); } void paymentQueueRestoreCompletedTransactionsFinished() { - _restoreCompleter.complete(_restoredTransactions ?? []); + _restoreCompleter!.complete(_restoredTransactions); } bool shouldAddStorePayment( - {SKPaymentWrapper payment, SKProductWrapper product}) { + {required SKPaymentWrapper payment, required SKProductWrapper product}) { // In this unified API, we always return true to keep it consistent with the behavior on Google Play. return true; } @@ -254,7 +264,7 @@ class _TransactionObserver implements SKTransactionObserverWrapper { try { _receiptData = await SKReceiptManager.retrieveReceiptData(); } catch (e) { - _receiptData = null; + _receiptData = ''; } return _receiptData; } diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart b/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart index b980bbd77d85..ef0b7d2efa59 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart @@ -8,6 +8,7 @@ import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:in_app_purchase/src/in_app_purchase/purchase_details.dart'; import '../../billing_client_wrappers.dart'; +import '../../in_app_purchase.dart'; import 'in_app_purchase_connection.dart'; import 'product_details.dart'; @@ -28,26 +29,27 @@ class GooglePlayConnection billingClient.enablePendingPurchases(); } _readyFuture = _connect(); - WidgetsBinding.instance.addObserver(this); + WidgetsBinding.instance!.addObserver(this); _purchaseUpdatedController = StreamController.broadcast(); ; } /// Returns the singleton instance of the [GooglePlayConnection]. static GooglePlayConnection get instance => _getOrCreateInstance(); - static GooglePlayConnection _instance; + static GooglePlayConnection? _instance; Stream> get purchaseUpdatedStream => _purchaseUpdatedController.stream; - static StreamController> _purchaseUpdatedController; + static late StreamController> + _purchaseUpdatedController; /// The [BillingClient] that's abstracted by [GooglePlayConnection]. /// /// This field should not be used out of test code. @visibleForTesting - final BillingClient billingClient; + late final BillingClient billingClient; - Future _readyFuture; + late Future _readyFuture; static Set _productIdsToConsume = Set(); @override @@ -57,7 +59,7 @@ class GooglePlayConnection } @override - Future buyNonConsumable({@required PurchaseParam purchaseParam}) async { + Future buyNonConsumable({required PurchaseParam purchaseParam}) async { BillingResultWrapper billingResultWrapper = await billingClient.launchBillingFlow( sku: purchaseParam.productDetails.id, @@ -67,7 +69,7 @@ class GooglePlayConnection @override Future buyConsumable( - {@required PurchaseParam purchaseParam, bool autoConsume = true}) { + {required PurchaseParam purchaseParam, bool autoConsume = true}) { if (autoConsume) { _productIdsToConsume.add(purchaseParam.productDetails.id); } @@ -76,10 +78,14 @@ class GooglePlayConnection @override Future completePurchase(PurchaseDetails purchase, - {String developerPayload}) async { - if (purchase.billingClientPurchase.isAcknowledged) { + {String? developerPayload}) async { + if (purchase.billingClientPurchase!.isAcknowledged) { return BillingResultWrapper(responseCode: BillingResponse.ok); } + if (purchase.verificationData == null) { + throw ArgumentError( + 'completePurchase unsuccessful. The `purchase.verificationData` is not valid'); + } return await billingClient.acknowledgePurchase( purchase.verificationData.serverVerificationData, developerPayload: developerPayload); @@ -87,7 +93,11 @@ class GooglePlayConnection @override Future consumePurchase(PurchaseDetails purchase, - {String developerPayload}) { + {String? developerPayload}) { + if (purchase.verificationData == null) { + throw ArgumentError( + 'consumePurchase unsuccessful. The `purchase.verificationData` is not valid'); + } return billingClient.consumeAsync( purchase.verificationData.serverVerificationData, developerPayload: developerPayload); @@ -95,9 +105,9 @@ class GooglePlayConnection @override Future queryPastPurchases( - {String applicationUserName}) async { + {String? applicationUserName}) async { List responses; - PlatformException exception; + PlatformException? exception; try { responses = await Future.wait([ billingClient.queryPurchases(SkuType.inapp), @@ -133,7 +143,7 @@ class GooglePlayConnection .toSet(); String errorMessage = - errorCodeSet.isNotEmpty ? errorCodeSet.join(', ') : null; + errorCodeSet.isNotEmpty ? errorCodeSet.join(', ') : ''; List pastPurchases = responses.expand((PurchasesResultWrapper response) { @@ -142,14 +152,14 @@ class GooglePlayConnection return PurchaseDetails.fromPurchase(purchaseWrapper); }).toList(); - IAPError error; + IAPError? error; if (exception != null) { error = IAPError( source: IAPSource.GooglePlay, code: exception.code, - message: exception.message, + message: exception.message ?? '', details: exception.details); - } else if (errorMessage != null) { + } else if (errorMessage.isNotEmpty) { error = IAPError( source: IAPSource.GooglePlay, code: kRestoredPurchaseErrorCode, @@ -175,11 +185,11 @@ class GooglePlayConnection static GooglePlayConnection _getOrCreateInstance() { if (_instance != null) { - return _instance; + return _instance!; } _instance = GooglePlayConnection._(); - return _instance; + return _instance!; } Future _connect() => @@ -193,7 +203,7 @@ class GooglePlayConnection Future queryProductDetails( Set identifiers) async { List responses; - PlatformException exception; + PlatformException? exception; try { responses = await Future.wait([ billingClient.querySkuDetails( @@ -235,13 +245,13 @@ class GooglePlayConnection : IAPError( source: IAPSource.GooglePlay, code: exception.code, - message: exception.message, + message: exception.message ?? '', details: exception.details)); } static Future> _getPurchaseDetailsFromResult( PurchasesResultWrapper resultWrapper) async { - IAPError error; + IAPError? error; if (resultWrapper.responseCode != BillingResponse.ok) { error = IAPError( source: IAPSource.GooglePlay, @@ -260,10 +270,13 @@ class GooglePlayConnection } else { return [ PurchaseDetails( - purchaseID: null, - productID: null, + purchaseID: '', + productID: '', transactionDate: null, - verificationData: null) + verificationData: PurchaseVerificationData( + localVerificationData: '', + serverVerificationData: '', + source: IAPSource.GooglePlay)) ..status = PurchaseStatus.error ..error = error ]; diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart b/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart index f07ff96d4403..81a0e92cc591 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart @@ -7,7 +7,6 @@ import 'dart:io'; import 'app_store_connection.dart'; import 'google_play_connection.dart'; import 'product_details.dart'; -import 'package:flutter/foundation.dart'; import 'package:in_app_purchase/billing_client_wrappers.dart'; import './purchase_details.dart'; @@ -40,11 +39,11 @@ abstract class InAppPurchaseConnection { /// events after they start to listen. Stream> get purchaseUpdatedStream => _getStream(); - Stream> _purchaseUpdatedStream; + Stream>? _purchaseUpdatedStream; Stream> _getStream() { if (_purchaseUpdatedStream != null) { - return _purchaseUpdatedStream; + return _purchaseUpdatedStream!; } if (Platform.isAndroid) { @@ -57,7 +56,7 @@ abstract class InAppPurchaseConnection { throw UnsupportedError( 'InAppPurchase plugin only works on Android and iOS.'); } - return _purchaseUpdatedStream; + return _purchaseUpdatedStream!; } /// Whether pending purchase is enabled. @@ -133,7 +132,7 @@ abstract class InAppPurchaseConnection { /// * [queryPastPurchases], for restoring non consumable products. /// /// Calling this method for consumable items will cause unwanted behaviors! - Future buyNonConsumable({@required PurchaseParam purchaseParam}); + Future buyNonConsumable({required PurchaseParam purchaseParam}); /// Buy a consumable product. /// @@ -186,7 +185,7 @@ abstract class InAppPurchaseConnection { /// Calling this method for non consumable items will cause unwanted /// behaviors! Future buyConsumable( - {@required PurchaseParam purchaseParam, bool autoConsume = true}); + {required PurchaseParam purchaseParam, bool autoConsume = true}); /// Mark that purchased content has been delivered to the /// user. @@ -206,9 +205,9 @@ abstract class InAppPurchaseConnection { /// Warning! Failure to call this method and get a successful response within 3 days of the purchase will result a refund on Android. /// The [consumePurchase] acts as an implicit [completePurchase] on Android. /// - /// The optional parameter `developerPayload` only works on Android. + /// The optional parameter `developerPayload` (defaults to `null`) only works on Android. Future completePurchase(PurchaseDetails purchase, - {String developerPayload}); + {String? developerPayload}); /// (Play only) Mark that the user has consumed a product. /// @@ -216,16 +215,17 @@ abstract class InAppPurchaseConnection { /// delivered. The user won't be able to buy the same product again until the /// purchase of the product is consumed. /// - /// The `developerPayload` can be specified to be associated with this consumption. + /// The `developerPayload` (defaults to `null`) can be specified to be associated with this consumption. /// /// This throws an [UnsupportedError] on iOS. Future consumePurchase(PurchaseDetails purchase, - {String developerPayload}); + {String? developerPayload}); /// Query all previous purchases. /// /// The `applicationUserName` should match whatever was sent in the initial - /// `PurchaseParam`, if anything. + /// `PurchaseParam`, if anything. If no `applicationUserName` was specified in the initial + /// `PurchaseParam`, use `null`. /// /// This does not return consumed products. If you want to restore unused /// consumable products, you need to persist consumable product information @@ -236,23 +236,25 @@ abstract class InAppPurchaseConnection { /// * [refreshPurchaseVerificationData], for reloading failed /// [PurchaseDetails.verificationData]. Future queryPastPurchases( - {String applicationUserName}); + {String? applicationUserName}); /// (App Store only) retry loading purchase data after an initial failure. /// + /// If no results, a `null` value is returned. + /// /// Throws an [UnsupportedError] on Android. - Future refreshPurchaseVerificationData(); + Future refreshPurchaseVerificationData(); /// The [InAppPurchaseConnection] implemented for this platform. /// /// Throws an [UnsupportedError] when accessed on a platform other than /// Android or iOS. static InAppPurchaseConnection get instance => _getOrCreateInstance(); - static InAppPurchaseConnection _instance; + static InAppPurchaseConnection? _instance; static InAppPurchaseConnection _getOrCreateInstance() { if (_instance != null) { - return _instance; + return _instance!; } if (Platform.isAndroid) { @@ -264,7 +266,7 @@ abstract class InAppPurchaseConnection { 'InAppPurchase plugin only works on Android and iOS.'); } - return _instance; + return _instance!; } } @@ -287,9 +289,9 @@ enum IAPSource { class IAPError { /// Creates a new IAP error object with the given error details. IAPError( - {@required this.source, - @required this.code, - @required this.message, + {required this.source, + required this.code, + required this.message, this.details}); /// Which source is the error on. @@ -298,9 +300,9 @@ class IAPError { /// The error code. final String code; - /// A human-readable error message, possibly null. + /// A human-readable error message. final String message; /// Error details, possibly null. - final dynamic details; + final dynamic? details; } diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/product_details.dart b/packages/in_app_purchase/lib/src/in_app_purchase/product_details.dart index bb9e2682b9b7..a3eb79d9a450 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/product_details.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/product_details.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. -import 'package:flutter/foundation.dart'; import 'package:in_app_purchase/store_kit_wrappers.dart'; import 'package:in_app_purchase/billing_client_wrappers.dart'; import 'in_app_purchase_connection.dart'; @@ -14,10 +13,10 @@ import 'in_app_purchase_connection.dart'; class ProductDetails { /// Creates a new product details object with the provided details. ProductDetails( - {@required this.id, - @required this.title, - @required this.description, - @required this.price, + {required this.id, + required this.title, + required this.description, + required this.price, this.skProduct, this.skuDetail}); @@ -36,13 +35,13 @@ class ProductDetails { /// Points back to the `StoreKits`'s [SKProductWrapper] object that generated this [ProductDetails] object. /// - /// This is null on Android. - final SKProductWrapper skProduct; + /// This is `null` on Android. + final SKProductWrapper? skProduct; /// Points back to the `BillingClient1`'s [SkuDetailsWrapper] object that generated this [ProductDetails] object. /// - /// This is null on iOS. - final SkuDetailsWrapper skuDetail; + /// This is `null` on iOS. + final SkuDetailsWrapper? skuDetail; /// Generate a [ProductDetails] object based on an iOS [SKProductWrapper] object. ProductDetails.fromSKProduct(SKProductWrapper product) @@ -69,7 +68,7 @@ class ProductDetails { class ProductDetailsResponse { /// Creates a new [ProductDetailsResponse] with the provided response details. ProductDetailsResponse( - {@required this.productDetails, @required this.notFoundIDs, this.error}); + {required this.productDetails, required this.notFoundIDs, this.error}); /// Each [ProductDetails] uniquely matches one valid identifier in [identifiers] of [InAppPurchaseConnection.queryProductDetails]. final List productDetails; @@ -82,7 +81,9 @@ class ProductDetailsResponse { /// A caught platform exception thrown while querying the purchases. /// + /// The value is `null` if there is no error. + /// /// It's possible for this to be null but for there still to be notFoundIds in cases where the request itself was a success but the /// requested IDs could not be found. - final IAPError error; + final IAPError? error; } diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart b/packages/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart index 708b42c01623..c211d2a4cdb8 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/purchase_details.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. -import 'package:flutter/foundation.dart'; import 'package:in_app_purchase/src/billing_client_wrappers/enum_converters.dart'; import 'package:in_app_purchase/src/billing_client_wrappers/purchase_wrapper.dart'; import 'package:in_app_purchase/src/store_kit_wrappers/enum_converters.dart'; @@ -59,9 +58,9 @@ class PurchaseVerificationData { /// Creates a [PurchaseVerificationData] object with the provided information. PurchaseVerificationData( - {@required this.localVerificationData, - @required this.serverVerificationData, - @required this.source}); + {required this.localVerificationData, + required this.serverVerificationData, + required this.source}); } /// Status for a [PurchaseDetails]. @@ -88,9 +87,10 @@ enum PurchaseStatus { class PurchaseParam { /// Creates a new purchase parameter object with the given data. PurchaseParam( - {@required this.productDetails, + {required this.productDetails, this.applicationUserName, - this.sandboxTesting}); + this.sandboxTesting = false, + this.simulatesAskToBuyInSandbox = false}); /// The product to create payment for. /// @@ -103,10 +103,20 @@ class PurchaseParam { /// Do not pass in a clear text, your developer ID, the user’s Apple ID, or the /// user's Google ID for this field. /// For example, you can use a one-way hash of the user’s account name on your server. - final String applicationUserName; + final String? applicationUserName; - /// The 'sandboxTesting' is only available on iOS, set it to `true` for testing in AppStore's sandbox environment. The default value is `false`. + /// @deprecated Use [simulatesAskToBuyInSandbox] instead. + /// + /// Only available on iOS, set it to `true` to produce an "ask to buy" flow for this payment in the sandbox. + /// + /// See also [SKPaymentWrapper.simulatesAskToBuyInSandbox]. + @deprecated final bool sandboxTesting; + + /// Only available on iOS, set it to `true` to produce an "ask to buy" flow for this payment in the sandbox. + /// + /// See also [SKPaymentWrapper.simulatesAskToBuyInSandbox]. + final bool simulatesAskToBuyInSandbox; } /// Represents the transaction details of a purchase. @@ -115,7 +125,9 @@ class PurchaseParam { /// This class for simple operations. If you would like to see the detailed representation of the product, instead, use [PurchaseWrapper] on Android and [SKPaymentTransactionWrapper] on iOS. class PurchaseDetails { /// A unique identifier of the purchase. - final String purchaseID; + /// + /// The `value` is null on iOS if it is not a successful purchase. + final String? purchaseID; /// The product identifier of the purchase. final String productID; @@ -126,15 +138,16 @@ class PurchaseDetails { /// details on how to verify purchase use this data. You should never use any /// purchase data until verified. /// - /// On iOS, this may be null. Call - /// [InAppPurchaseConnection.refreshPurchaseVerificationData] to get a new + /// On iOS, [InAppPurchaseConnection.refreshPurchaseVerificationData] can be used to get a new /// [PurchaseVerificationData] object for further validation. final PurchaseVerificationData verificationData; /// The timestamp of the transaction. /// /// Milliseconds since epoch. - final String transactionDate; + /// + /// The value is `null` if [status] is not [PurchaseStatus.purchased]. + final String? transactionDate; /// The status that this [PurchaseDetails] is currently on. PurchaseStatus get status => _status; @@ -153,20 +166,22 @@ class PurchaseDetails { _status = status; } - PurchaseStatus _status; + late PurchaseStatus _status; - /// The error is only available when [status] is [PurchaseStatus.error]. - IAPError error; + /// The error details when the [status] is [PurchaseStatus.error]. + /// + /// The value is `null` if [status] is not [PurchaseStatus.error]. + IAPError? error; /// Points back to the `StoreKits`'s [SKPaymentTransactionWrapper] object that generated this [PurchaseDetails] object. /// - /// This is null on Android. - final SKPaymentTransactionWrapper skPaymentTransaction; + /// This is `null` on Android. + final SKPaymentTransactionWrapper? skPaymentTransaction; /// Points back to the `BillingClient`'s [PurchaseWrapper] object that generated this [PurchaseDetails] object. /// - /// This is null on iOS. - final PurchaseWrapper billingClientPurchase; + /// This is `null` on iOS. + final PurchaseWrapper? billingClientPurchase; /// The developer has to call [InAppPurchaseConnection.completePurchase] if the value is `true` /// and the product has been delivered to the user. @@ -179,14 +194,14 @@ class PurchaseDetails { // The platform that the object is created on. // // The value is either '_kPlatformIOS' or '_kPlatformAndroid'. - String _platform; + String? _platform; /// Creates a new PurchaseDetails object with the provided data. PurchaseDetails({ - @required this.purchaseID, - @required this.productID, - @required this.verificationData, - @required this.transactionDate, + this.purchaseID, + required this.productID, + required this.verificationData, + required this.transactionDate, this.skPaymentTransaction, this.billingClientPurchase, }); @@ -201,7 +216,7 @@ class PurchaseDetails { serverVerificationData: base64EncodedReceipt, source: IAPSource.AppStore), this.transactionDate = transaction.transactionTimeStamp != null - ? (transaction.transactionTimeStamp * 1000).toInt().toString() + ? (transaction.transactionTimeStamp! * 1000).toInt().toString() : null, this.skPaymentTransaction = transaction, this.billingClientPurchase = null, @@ -212,8 +227,8 @@ class PurchaseDetails { error = IAPError( source: IAPSource.AppStore, code: kPurchaseErrorCode, - message: transaction.error.domain, - details: transaction.error.userInfo, + message: transaction.error?.domain ?? '', + details: transaction.error?.userInfo, ); } } @@ -235,7 +250,7 @@ class PurchaseDetails { error = IAPError( source: IAPSource.GooglePlay, code: kPurchaseErrorCode, - message: null, + message: '', ); } } @@ -246,7 +261,7 @@ class PurchaseDetails { /// An instance of this class is returned in [InAppPurchaseConnection.queryPastPurchases]. class QueryPurchaseDetailsResponse { /// Creates a new [QueryPurchaseDetailsResponse] object with the provider information. - QueryPurchaseDetailsResponse({@required this.pastPurchases, this.error}); + QueryPurchaseDetailsResponse({required this.pastPurchases, this.error}); /// A list of successfully fetched past purchases. /// @@ -257,6 +272,6 @@ class QueryPurchaseDetailsResponse { /// The error when fetching past purchases. /// - /// If the fetch is successful, the value is null. - final IAPError error; + /// If the fetch is successful, the value is `null`. + final IAPError? error; } diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.dart index 62188705035a..ce2c1fad406f 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.dart @@ -13,16 +13,20 @@ part 'enum_converters.g.dart'; /// Use these in `@JsonSerializable()` classes by annotating them with /// `@SKTransactionStatusConverter()`. class SKTransactionStatusConverter - implements JsonConverter { + implements JsonConverter { /// Default const constructor. const SKTransactionStatusConverter(); @override - SKPaymentTransactionStateWrapper fromJson(int json) => - _$enumDecode( - _$SKPaymentTransactionStateWrapperEnumMap - .cast(), - json); + SKPaymentTransactionStateWrapper fromJson(int? json) { + if (json == null) { + return SKPaymentTransactionStateWrapper.unspecified; + } + return _$enumDecode( + _$SKPaymentTransactionStateWrapperEnumMap + .cast(), + json); + } /// Converts an [SKPaymentTransactionStateWrapper] to a [PurchaseStatus]. PurchaseStatus toPurchaseStatus(SKPaymentTransactionStateWrapper object) { @@ -34,19 +38,70 @@ class SKTransactionStatusConverter case SKPaymentTransactionStateWrapper.restored: return PurchaseStatus.purchased; case SKPaymentTransactionStateWrapper.failed: + case SKPaymentTransactionStateWrapper.unspecified: return PurchaseStatus.error; } - - throw ArgumentError('$object isn\'t mapped to PurchaseStatus'); } @override int toJson(SKPaymentTransactionStateWrapper object) => - _$SKPaymentTransactionStateWrapperEnumMap[object]; + _$SKPaymentTransactionStateWrapperEnumMap[object]!; +} + +/// Serializer for [SKSubscriptionPeriodUnit]. +/// +/// Use these in `@JsonSerializable()` classes by annotating them with +/// `@SKSubscriptionPeriodUnitConverter()`. +class SKSubscriptionPeriodUnitConverter + implements JsonConverter { + /// Default const constructor. + const SKSubscriptionPeriodUnitConverter(); + + @override + SKSubscriptionPeriodUnit fromJson(int? json) { + if (json == null) { + return SKSubscriptionPeriodUnit.day; + } + return _$enumDecode( + _$SKSubscriptionPeriodUnitEnumMap + .cast(), + json); + } + + @override + int toJson(SKSubscriptionPeriodUnit object) => + _$SKSubscriptionPeriodUnitEnumMap[object]!; +} + +/// Serializer for [SKProductDiscountPaymentMode]. +/// +/// Use these in `@JsonSerializable()` classes by annotating them with +/// `@SKProductDiscountPaymentModeConverter()`. +class SKProductDiscountPaymentModeConverter + implements JsonConverter { + /// Default const constructor. + const SKProductDiscountPaymentModeConverter(); + + @override + SKProductDiscountPaymentMode fromJson(int? json) { + if (json == null) { + return SKProductDiscountPaymentMode.payAsYouGo; + } + return _$enumDecode( + _$SKProductDiscountPaymentModeEnumMap + .cast(), + json); + } + + @override + int toJson(SKProductDiscountPaymentMode object) => + _$SKProductDiscountPaymentModeEnumMap[object]!; } // Define a class so we generate serializer helper methods for the enums @JsonSerializable() class _SerializedEnums { - SKPaymentTransactionStateWrapper response; + late SKPaymentTransactionStateWrapper response; + late SKSubscriptionPeriodUnit unit; + late SKProductDiscountPaymentMode discountPaymentMode; } diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.g.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.g.dart index f4f17df846a7..b003f435a800 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.g.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.g.dart @@ -9,33 +9,44 @@ part of 'enum_converters.dart'; _SerializedEnums _$_SerializedEnumsFromJson(Map json) { return _SerializedEnums() ..response = _$enumDecode( - _$SKPaymentTransactionStateWrapperEnumMap, json['response']); + _$SKPaymentTransactionStateWrapperEnumMap, json['response']) + ..unit = _$enumDecode(_$SKSubscriptionPeriodUnitEnumMap, json['unit']) + ..discountPaymentMode = _$enumDecode( + _$SKProductDiscountPaymentModeEnumMap, json['discountPaymentMode']); } Map _$_SerializedEnumsToJson(_SerializedEnums instance) => { 'response': _$SKPaymentTransactionStateWrapperEnumMap[instance.response], + 'unit': _$SKSubscriptionPeriodUnitEnumMap[instance.unit], + 'discountPaymentMode': + _$SKProductDiscountPaymentModeEnumMap[instance.discountPaymentMode], }; -T _$enumDecode( - Map enumValues, - dynamic source, { - T unknownValue, +K _$enumDecode( + Map enumValues, + Object? source, { + K? unknownValue, }) { if (source == null) { - throw ArgumentError('A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}'); + throw ArgumentError( + 'A value must be provided. Supported values: ' + '${enumValues.values.join(', ')}', + ); } - final value = enumValues.entries - .singleWhere((e) => e.value == source, orElse: () => null) - ?.key; - - if (value == null && unknownValue == null) { - throw ArgumentError('`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}'); - } - return value ?? unknownValue; + return enumValues.entries.singleWhere( + (e) => e.value == source, + orElse: () { + if (unknownValue == null) { + throw ArgumentError( + '`$source` is not one of the supported values: ' + '${enumValues.values.join(', ')}', + ); + } + return MapEntry(unknownValue, enumValues.values.first); + }, + ).key; } const _$SKPaymentTransactionStateWrapperEnumMap = { @@ -44,4 +55,19 @@ const _$SKPaymentTransactionStateWrapperEnumMap = { SKPaymentTransactionStateWrapper.failed: 2, SKPaymentTransactionStateWrapper.restored: 3, SKPaymentTransactionStateWrapper.deferred: 4, + SKPaymentTransactionStateWrapper.unspecified: -1, +}; + +const _$SKSubscriptionPeriodUnitEnumMap = { + SKSubscriptionPeriodUnit.day: 0, + SKSubscriptionPeriodUnit.week: 1, + SKSubscriptionPeriodUnit.month: 2, + SKSubscriptionPeriodUnit.year: 3, +}; + +const _$SKProductDiscountPaymentModeEnumMap = { + SKProductDiscountPaymentMode.payAsYouGo: 0, + SKProductDiscountPaymentMode.payUpFront: 1, + SKProductDiscountPaymentMode.freeTrail: 2, + SKProductDiscountPaymentMode.unspecified: -1, }; diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart index ce38759c74ec..d56fbd00c6fe 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart @@ -5,7 +5,6 @@ import 'dart:ui' show hashValues; import 'dart:async'; import 'package:collection/collection.dart'; -import 'package:flutter/foundation.dart'; import 'package:in_app_purchase/src/channel.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:flutter/services.dart'; @@ -25,7 +24,7 @@ part 'sk_payment_queue_wrapper.g.dart'; /// available at the [In-App Purchase Programming /// Guide](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Introduction.html#//apple_ref/doc/uid/TP40008267). class SKPaymentQueueWrapper { - SKTransactionObserverWrapper _observer; + SKTransactionObserverWrapper? _observer; /// Returns the default payment queue. /// @@ -41,13 +40,15 @@ class SKPaymentQueueWrapper { /// Calls [`-[SKPaymentQueue transactions]`](https://developer.apple.com/documentation/storekit/skpaymentqueue/1506026-transactions?language=objc) Future> transactions() async { - return _getTransactionList( - await channel.invokeListMethod('-[SKPaymentQueue transactions]')); + return _getTransactionList((await channel + .invokeListMethod('-[SKPaymentQueue transactions]'))!); } /// Calls [`-[SKPaymentQueue canMakePayments:]`](https://developer.apple.com/documentation/storekit/skpaymentqueue/1506139-canmakepayments?language=objc). static Future canMakePayments() async => - await channel.invokeMethod('-[SKPaymentQueue canMakePayments:]'); + (await channel + .invokeMethod('-[SKPaymentQueue canMakePayments:]')) ?? + false; /// Sets an observer to listen to all incoming transaction events. /// @@ -57,7 +58,7 @@ class SKPaymentQueueWrapper { /// addTransactionObserver:]`](https://developer.apple.com/documentation/storekit/skpaymentqueue/1506042-addtransactionobserver?language=objc). void setTransactionObserver(SKTransactionObserverWrapper observer) { _observer = observer; - callbackChannel.setMethodCallHandler(_handleObserverCallbacks); + channel.setMethodCallHandler(_handleObserverCallbacks); } /// Posts a payment to the queue. @@ -83,7 +84,7 @@ class SKPaymentQueueWrapper { Future addPayment(SKPaymentWrapper payment) async { assert(_observer != null, '[in_app_purchase]: Trying to add a payment without an observer. One must be set using `SkPaymentQueueWrapper.setTransactionObserver` before the app launches.'); - Map requestMap = payment.toMap(); + final Map requestMap = payment.toMap(); await channel.invokeMethod( '-[InAppPurchasePlugin addPayment:result:]', requestMap, @@ -103,7 +104,7 @@ class SKPaymentQueueWrapper { /// finishTransaction:]`](https://developer.apple.com/documentation/storekit/skpaymentqueue/1506003-finishtransaction?language=objc). Future finishTransaction( SKPaymentTransactionWrapper transaction) async { - Map requestMap = transaction.toFinishMap(); + Map requestMap = transaction.toFinishMap(); await channel.invokeMethod( '-[InAppPurchasePlugin finishTransaction:result:]', requestMap, @@ -124,28 +125,30 @@ class SKPaymentQueueWrapper { /// /// The `applicationUserName` should match the original /// [SKPaymentWrapper.applicationUsername] used in [addPayment]. + /// If no `applicationUserName` was used, `applicationUserName` should be null. /// /// This method either triggers [`-[SKPayment /// restoreCompletedTransactions]`](https://developer.apple.com/documentation/storekit/skpaymentqueue/1506123-restorecompletedtransactions?language=objc) /// or [`-[SKPayment restoreCompletedTransactionsWithApplicationUsername:]`](https://developer.apple.com/documentation/storekit/skpaymentqueue/1505992-restorecompletedtransactionswith?language=objc) /// depending on whether the `applicationUserName` is set. - Future restoreTransactions({String applicationUserName}) async { + Future restoreTransactions({String? applicationUserName}) async { await channel.invokeMethod( '-[InAppPurchasePlugin restoreTransactions:result:]', applicationUserName); } // Triage a method channel call from the platform and triggers the correct observer method. - Future _handleObserverCallbacks(MethodCall call) { + Future _handleObserverCallbacks(MethodCall call) async { assert(_observer != null, '[in_app_purchase]: (Fatal)The observer has not been set but we received a purchase transaction notification. Please ensure the observer has been set using `setTransactionObserver`. Make sure the observer is added right at the App Launch.'); + final SKTransactionObserverWrapper observer = _observer!; switch (call.method) { case 'updatedTransactions': { final List transactions = _getTransactionList(call.arguments); return Future(() { - _observer.updatedTransactions(transactions: transactions); + observer.updatedTransactions(transactions: transactions); }); } case 'removedTransactions': @@ -153,20 +156,20 @@ class SKPaymentQueueWrapper { final List transactions = _getTransactionList(call.arguments); return Future(() { - _observer.removedTransactions(transactions: transactions); + observer.removedTransactions(transactions: transactions); }); } case 'restoreCompletedTransactionsFailed': { SKError error = SKError.fromJson(call.arguments); return Future(() { - _observer.restoreCompletedTransactionsFailed(error: error); + observer.restoreCompletedTransactionsFailed(error: error); }); } case 'paymentQueueRestoreCompletedTransactionsFinished': { return Future(() { - _observer.paymentQueueRestoreCompletedTransactionsFinished(); + observer.paymentQueueRestoreCompletedTransactionsFinished(); }); } case 'shouldAddStorePayment': @@ -176,7 +179,7 @@ class SKPaymentQueueWrapper { SKProductWrapper product = SKProductWrapper.fromJson(call.arguments['product']); return Future(() { - if (_observer.shouldAddStorePayment( + if (observer.shouldAddStorePayment( payment: payment, product: product) == true) { SKPaymentQueueWrapper().addPayment(payment); @@ -186,49 +189,52 @@ class SKPaymentQueueWrapper { default: break; } - return null; + throw PlatformException( + code: 'no_such_callback', + message: 'Did not recognize the observer callback ${call.method}.'); } // Get transaction wrapper object list from arguments. - List _getTransactionList(dynamic arguments) { - final List transactions = arguments - .map( - (dynamic map) => SKPaymentTransactionWrapper.fromJson(map)) - .toList(); - return transactions; + List _getTransactionList( + List transactionsData) { + return transactionsData.map((dynamic map) { + return SKPaymentTransactionWrapper.fromJson( + Map.castFrom(map)); + }).toList(); } } /// Dart wrapper around StoreKit's /// [NSError](https://developer.apple.com/documentation/foundation/nserror?language=objc). -@JsonSerializable(nullable: true) +@JsonSerializable() class SKError { /// Creates a new [SKError] object with the provided information. - SKError( - {@required this.code, @required this.domain, @required this.userInfo}); + SKError({required this.code, required this.domain, required this.userInfo}); /// Constructs an instance of this from a key-value map of data. /// /// The map needs to have named string keys with values matching the names and /// types of all of the members on this class. The `map` parameter must not be /// null. - factory SKError.fromJson(Map map) { - assert(map != null); + factory SKError.fromJson(Map map) { return _$SKErrorFromJson(map); } /// Error [code](https://developer.apple.com/documentation/foundation/1448136-nserror_codes) /// as defined in the Cocoa Framework. + @JsonKey(defaultValue: 0) final int code; /// Error /// [domain](https://developer.apple.com/documentation/foundation/nscocoaerrordomain?language=objc) /// as defined in the Cocoa Framework. + @JsonKey(defaultValue: '') final String domain; /// A map that contains more detailed information about the error. /// /// Any key of the map must be a valid [NSErrorUserInfoKey](https://developer.apple.com/documentation/foundation/nserroruserinfokey?language=objc). + @JsonKey(defaultValue: {}) final Map userInfo; @override @@ -239,7 +245,7 @@ class SKError { if (other.runtimeType != runtimeType) { return false; } - final SKError typedOther = other; + final SKError typedOther = other as SKError; return typedOther.code == code && typedOther.domain == domain && DeepCollectionEquality.unordered() @@ -257,11 +263,11 @@ class SKError { /// not need to create the payment object explicitly; instead, use /// [SKPaymentQueueWrapper.addPayment] directly with a product identifier to /// initiate a payment. -@JsonSerializable(nullable: true) +@JsonSerializable() class SKPaymentWrapper { /// Creates a new [SKPaymentWrapper] with the provided information. SKPaymentWrapper( - {@required this.productIdentifier, + {required this.productIdentifier, this.applicationUsername, this.requestData, this.quantity = 1, @@ -272,7 +278,7 @@ class SKPaymentWrapper { /// The map needs to have named string keys with values matching the names and /// types of all of the members on this class. The `map` parameter must not be /// null. - factory SKPaymentWrapper.fromJson(Map map) { + factory SKPaymentWrapper.fromJson(Map map) { assert(map != null); return _$SKPaymentWrapperFromJson(map); } @@ -289,6 +295,7 @@ class SKPaymentWrapper { } /// The id for the product that the payment is for. + @JsonKey(defaultValue: '') final String productIdentifier; /// An opaque id for the user's account. @@ -299,7 +306,7 @@ class SKPaymentWrapper { /// account name on your server. Don’t use the Apple ID for your developer /// account, the user’s Apple ID, or the user’s plaintext account name on /// your server. - final String applicationUsername; + final String? applicationUsername; /// Reserved for future use. /// @@ -310,18 +317,26 @@ class SKPaymentWrapper { // We also provide this property to match the iOS platform. Converted to // String from NSData from ios platform using UTF8Encoding. The / default is // null. - final String requestData; + final String? requestData; /// The amount of the product this payment is for. /// /// The default is 1. The minimum is 1. The maximum is 10. + /// + /// If the object is invalid, the value could be 0. + @JsonKey(defaultValue: 0) final int quantity; - /// Produces an "ask to buy" flow in the sandbox if set to true. Default is - /// false. + /// Produces an "ask to buy" flow in the sandbox. + /// + /// Setting it to `true` will cause a transaction to be in the state [SKPaymentTransactionStateWrapper.deferred], + /// which produce an "ask to buy" prompt that interrupts the the payment flow. + /// + /// Default is `false`. /// /// See https://developer.apple.com/in-app-purchase/ for a guide on Sandbox /// testing. + @JsonKey(defaultValue: false) final bool simulatesAskToBuyInSandbox; @override @@ -332,7 +347,7 @@ class SKPaymentWrapper { if (other.runtimeType != runtimeType) { return false; } - final SKPaymentWrapper typedOther = other; + final SKPaymentWrapper typedOther = other as SKPaymentWrapper; return typedOther.productIdentifier == productIdentifier && typedOther.applicationUsername == applicationUsername && typedOther.quantity == quantity && diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.g.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.g.dart index 48a18e61d4d9..2b886597adc5 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.g.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.g.dart @@ -8,11 +8,12 @@ part of 'sk_payment_queue_wrapper.dart'; SKError _$SKErrorFromJson(Map json) { return SKError( - code: json['code'] as int, - domain: json['domain'] as String, - userInfo: (json['userInfo'] as Map)?.map( - (k, e) => MapEntry(k as String, e), - ), + code: json['code'] as int? ?? 0, + domain: json['domain'] as String? ?? '', + userInfo: (json['userInfo'] as Map?)?.map( + (k, e) => MapEntry(k as String, e), + ) ?? + {}, ); } @@ -24,11 +25,12 @@ Map _$SKErrorToJson(SKError instance) => { SKPaymentWrapper _$SKPaymentWrapperFromJson(Map json) { return SKPaymentWrapper( - productIdentifier: json['productIdentifier'] as String, - applicationUsername: json['applicationUsername'] as String, - requestData: json['requestData'] as String, - quantity: json['quantity'] as int, - simulatesAskToBuyInSandbox: json['simulatesAskToBuyInSandbox'] as bool, + productIdentifier: json['productIdentifier'] as String? ?? '', + applicationUsername: json['applicationUsername'] as String?, + requestData: json['requestData'] as String?, + quantity: json['quantity'] as int? ?? 0, + simulatesAskToBuyInSandbox: + json['simulatesAskToBuyInSandbox'] as bool? ?? false, ); } diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.dart index 65f6ff8871f8..9921380e6e96 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'dart:ui' show hashValues; -import 'package:flutter/foundation.dart'; import 'package:json_annotation/json_annotation.dart'; import 'sk_product_wrapper.dart'; import 'sk_payment_queue_wrapper.dart'; @@ -20,13 +19,15 @@ part 'sk_payment_transaction_wrappers.g.dart'; /// This class is a Dart wrapper around [SKTransactionObserver](https://developer.apple.com/documentation/storekit/skpaymenttransactionobserver?language=objc). abstract class SKTransactionObserverWrapper { /// Triggered when any transactions are updated. - void updatedTransactions({List transactions}); + void updatedTransactions( + {required List transactions}); /// Triggered when any transactions are removed from the payment queue. - void removedTransactions({List transactions}); + void removedTransactions( + {required List transactions}); /// Triggered when there is an error while restoring transactions. - void restoreCompletedTransactionsFailed({SKError error}); + void restoreCompletedTransactionsFailed({required SKError error}); /// Triggered when payment queue has finished sending restored transactions. void paymentQueueRestoreCompletedTransactionsFinished(); @@ -41,7 +42,7 @@ abstract class SKTransactionObserverWrapper { /// continue the transaction later by calling [addPayment] with the /// `payment` param from this method. bool shouldAddStorePayment( - {SKPaymentWrapper payment, SKProductWrapper product}); + {required SKPaymentWrapper payment, required SKProductWrapper product}); } /// The state of a transaction. @@ -85,6 +86,10 @@ enum SKPaymentTransactionStateWrapper { /// transaction to update to another state. @JsonValue(4) deferred, + + /// Indicates the transaction is in an unspecified state. + @JsonValue(-1) + unspecified, } /// Created when a payment is added to the [SKPaymentQueueWrapper]. @@ -96,16 +101,16 @@ enum SKPaymentTransactionStateWrapper { /// /// Dart wrapper around StoreKit's /// [SKPaymentTransaction](https://developer.apple.com/documentation/storekit/skpaymenttransaction?language=objc). -@JsonSerializable(nullable: true) +@JsonSerializable() class SKPaymentTransactionWrapper { /// Creates a new [SKPaymentTransactionWrapper] with the provided information. SKPaymentTransactionWrapper({ - @required this.payment, - @required this.transactionState, - @required this.originalTransaction, - @required this.transactionTimeStamp, - @required this.transactionIdentifier, - @required this.error, + required this.payment, + required this.transactionState, + this.originalTransaction, + this.transactionTimeStamp, + this.transactionIdentifier, + this.error, }); /// Constructs an instance of this from a key value map of data. @@ -113,10 +118,7 @@ class SKPaymentTransactionWrapper { /// The map needs to have named string keys with values matching the names and /// types of all of the members on this class. The `map` parameter must not be /// null. - factory SKPaymentTransactionWrapper.fromJson(Map map) { - if (map == null) { - return null; - } + factory SKPaymentTransactionWrapper.fromJson(Map map) { return _$SKPaymentTransactionWrapperFromJson(map); } @@ -130,18 +132,21 @@ class SKPaymentTransactionWrapper { /// The original Transaction. /// - /// Only available if the [transactionState] is - /// [SKPaymentTransactionStateWrapper.restored]. When the [transactionState] + /// Only available if the [transactionState] is [SKPaymentTransactionStateWrapper.restored]. + /// Otherwise the value is `null`. + /// + /// When the [transactionState] /// is [SKPaymentTransactionStateWrapper.restored], the current transaction /// object holds a new [transactionIdentifier]. - final SKPaymentTransactionWrapper originalTransaction; + final SKPaymentTransactionWrapper? originalTransaction; /// The timestamp of the transaction. /// /// Seconds since epoch. It is only defined when the [transactionState] is /// [SKPaymentTransactionStateWrapper.purchased] or /// [SKPaymentTransactionStateWrapper.restored]. - final double transactionTimeStamp; + /// Otherwise, the value is `null`. + final double? transactionTimeStamp; /// The unique string identifer of the transaction. /// @@ -150,13 +155,15 @@ class SKPaymentTransactionWrapper { /// [SKPaymentTransactionStateWrapper.restored]. You may wish to record this /// string as part of an audit trail for App Store purchases. The value of /// this string corresponds to the same property in the receipt. - final String transactionIdentifier; + /// + /// The value is `null` if it is an unsuccessful transaction. + final String? transactionIdentifier; /// The error object /// /// Only available if the [transactionState] is /// [SKPaymentTransactionStateWrapper.failed]. - final SKError error; + final SKError? error; @override bool operator ==(Object other) { @@ -166,7 +173,8 @@ class SKPaymentTransactionWrapper { if (other.runtimeType != runtimeType) { return false; } - final SKPaymentTransactionWrapper typedOther = other; + final SKPaymentTransactionWrapper typedOther = + other as SKPaymentTransactionWrapper; return typedOther.payment == payment && typedOther.transactionState == transactionState && typedOther.originalTransaction == originalTransaction && @@ -188,8 +196,8 @@ class SKPaymentTransactionWrapper { String toString() => _$SKPaymentTransactionWrapperToJson(this).toString(); /// The payload that is used to finish this transaction. - Map toFinishMap() => { + Map toFinishMap() => { "transactionIdentifier": this.transactionIdentifier, - "productIdentifier": this.payment?.productIdentifier, + "productIdentifier": this.payment.productIdentifier, }; } diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.g.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.g.dart index bc520826d9fe..4c7af21bc151 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.g.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.g.dart @@ -8,19 +8,19 @@ part of 'sk_payment_transaction_wrappers.dart'; SKPaymentTransactionWrapper _$SKPaymentTransactionWrapperFromJson(Map json) { return SKPaymentTransactionWrapper( - payment: json['payment'] == null - ? null - : SKPaymentWrapper.fromJson(json['payment'] as Map), + payment: SKPaymentWrapper.fromJson( + Map.from(json['payment'] as Map)), transactionState: const SKTransactionStatusConverter() - .fromJson(json['transactionState'] as int), + .fromJson(json['transactionState'] as int?), originalTransaction: json['originalTransaction'] == null ? null : SKPaymentTransactionWrapper.fromJson( - json['originalTransaction'] as Map), - transactionTimeStamp: (json['transactionTimeStamp'] as num)?.toDouble(), - transactionIdentifier: json['transactionIdentifier'] as String, - error: - json['error'] == null ? null : SKError.fromJson(json['error'] as Map), + Map.from(json['originalTransaction'] as Map)), + transactionTimeStamp: (json['transactionTimeStamp'] as num?)?.toDouble(), + transactionIdentifier: json['transactionIdentifier'] as String?, + error: json['error'] == null + ? null + : SKError.fromJson(Map.from(json['error'] as Map)), ); } diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.dart index aa76971102cf..d77ea81c2d38 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.dart @@ -3,9 +3,9 @@ // found in the LICENSE file. import 'dart:ui' show hashValues; -import 'package:flutter/foundation.dart'; import 'package:collection/collection.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'enum_converters.dart'; // WARNING: Changes to `@JsonSerializable` classes need to be reflected in the // below generated file. Run `flutter packages pub run build_runner watch` to @@ -20,14 +20,12 @@ part 'sk_product_wrapper.g.dart'; class SkProductResponseWrapper { /// Creates an [SkProductResponseWrapper] with the given product details. SkProductResponseWrapper( - {@required this.products, @required this.invalidProductIdentifiers}); + {required this.products, required this.invalidProductIdentifiers}); /// Constructing an instance from a map from the Objective-C layer. /// /// This method should only be used with `map` values returned by [SKRequestMaker.startProductRequest]. - /// The `map` parameter must not be null. factory SkProductResponseWrapper.fromJson(Map map) { - assert(map != null, 'Map must not be null.'); return _$SkProductResponseWrapperFromJson(map); } @@ -35,6 +33,7 @@ class SkProductResponseWrapper { /// /// One product in this list matches one valid product identifier passed to the [SKRequestMaker.startProductRequest]. /// Will be empty if the [SKRequestMaker.startProductRequest] method does not pass any correct product identifier. + @JsonKey(defaultValue: []) final List products; /// Stores product identifiers in the `productIdentifiers` from [SKRequestMaker.startProductRequest] that are not recognized by the App Store. @@ -42,6 +41,7 @@ class SkProductResponseWrapper { /// The App Store will not recognize a product identifier unless certain criteria are met. A detailed list of the criteria can be /// found here https://developer.apple.com/documentation/storekit/skproductsresponse/1505985-invalidproductidentifiers?language=objc. /// Will be empty if all the product identifiers are valid. + @JsonKey(defaultValue: []) final List invalidProductIdentifiers; @override @@ -52,7 +52,8 @@ class SkProductResponseWrapper { if (other.runtimeType != runtimeType) { return false; } - final SkProductResponseWrapper typedOther = other; + final SkProductResponseWrapper typedOther = + other as SkProductResponseWrapper; return DeepCollectionEquality().equals(typedOther.products, products) && DeepCollectionEquality().equals( typedOther.invalidProductIdentifiers, invalidProductIdentifiers); @@ -91,27 +92,32 @@ enum SKSubscriptionPeriodUnit { /// /// A period is defined by a [numberOfUnits] and a [unit], e.g for a 3 months period [numberOfUnits] is 3 and [unit] is a month. /// It is used as a property in [SKProductDiscountWrapper] and [SKProductWrapper]. -@JsonSerializable(nullable: true) +@JsonSerializable() class SKProductSubscriptionPeriodWrapper { /// Creates an [SKProductSubscriptionPeriodWrapper] for a `numberOfUnits`x`unit` period. SKProductSubscriptionPeriodWrapper( - {@required this.numberOfUnits, @required this.unit}); + {required this.numberOfUnits, required this.unit}); /// Constructing an instance from a map from the Objective-C layer. /// /// This method should only be used with `map` values returned by [SKProductDiscountWrapper.fromJson] or [SKProductWrapper.fromJson]. - /// The `map` parameter must not be null. - factory SKProductSubscriptionPeriodWrapper.fromJson(Map map) { - assert(map != null, 'Map must not be null.'); + factory SKProductSubscriptionPeriodWrapper.fromJson( + Map? map) { + if (map == null) { + return SKProductSubscriptionPeriodWrapper( + numberOfUnits: 0, unit: SKSubscriptionPeriodUnit.day); + } return _$SKProductSubscriptionPeriodWrapperFromJson(map); } /// The number of [unit] units in this period. /// - /// Must be greater than 0. + /// Must be greater than 0 if the object is valid. + @JsonKey(defaultValue: 0) final int numberOfUnits; /// The time unit used to specify the length of this period. + @SKSubscriptionPeriodUnitConverter() final SKSubscriptionPeriodUnit unit; @override @@ -122,7 +128,8 @@ class SKProductSubscriptionPeriodWrapper { if (other.runtimeType != runtimeType) { return false; } - final SKProductSubscriptionPeriodWrapper typedOther = other; + final SKProductSubscriptionPeriodWrapper typedOther = + other as SKProductSubscriptionPeriodWrapper; return typedOther.numberOfUnits == numberOfUnits && typedOther.unit == unit; } @@ -147,31 +154,34 @@ enum SKProductDiscountPaymentMode { /// User pays nothing during the discounted period. @JsonValue(2) freeTrail, + + /// Unspecified mode. + @JsonValue(-1) + unspecified, } /// Dart wrapper around StoreKit's [SKProductDiscount](https://developer.apple.com/documentation/storekit/skproductdiscount?language=objc). /// /// It is used as a property in [SKProductWrapper]. -@JsonSerializable(nullable: true) +@JsonSerializable() class SKProductDiscountWrapper { /// Creates an [SKProductDiscountWrapper] with the given discount details. SKProductDiscountWrapper( - {@required this.price, - @required this.priceLocale, - @required this.numberOfPeriods, - @required this.paymentMode, - @required this.subscriptionPeriod}); + {required this.price, + required this.priceLocale, + required this.numberOfPeriods, + required this.paymentMode, + required this.subscriptionPeriod}); /// Constructing an instance from a map from the Objective-C layer. /// /// This method should only be used with `map` values returned by [SKProductWrapper.fromJson]. - /// The `map` parameter must not be null. - factory SKProductDiscountWrapper.fromJson(Map map) { - assert(map != null, 'Map must not be null.'); + factory SKProductDiscountWrapper.fromJson(Map map) { return _$SKProductDiscountWrapperFromJson(map); } /// The discounted price, in the currency that is defined in [priceLocale]. + @JsonKey(defaultValue: '') final String price; /// Includes locale information about the price, e.g. `$` as the currency symbol for US locale. @@ -179,10 +189,12 @@ class SKProductDiscountWrapper { /// The object represent the discount period length. /// - /// The value must be >= 0. + /// The value must be >= 0 if the object is valid. + @JsonKey(defaultValue: 0) final int numberOfPeriods; /// The object indicates how the discount price is charged. + @SKProductDiscountPaymentModeConverter() final SKProductDiscountPaymentMode paymentMode; /// The object represents the duration of single subscription period for the discount. @@ -199,7 +211,8 @@ class SKProductDiscountWrapper { if (other.runtimeType != runtimeType) { return false; } - final SKProductDiscountWrapper typedOther = other; + final SKProductDiscountWrapper typedOther = + other as SKProductDiscountWrapper; return typedOther.price == price && typedOther.priceLocale == priceLocale && typedOther.numberOfPeriods == numberOfPeriods && @@ -216,40 +229,41 @@ class SKProductDiscountWrapper { /// /// A list of [SKProductWrapper] is returned in the [SKRequestMaker.startProductRequest] method, and /// should be stored for use when making a payment. -@JsonSerializable(nullable: true) +@JsonSerializable() class SKProductWrapper { /// Creates an [SKProductWrapper] with the given product details. SKProductWrapper({ - @required this.productIdentifier, - @required this.localizedTitle, - @required this.localizedDescription, - @required this.priceLocale, - @required this.subscriptionGroupIdentifier, - @required this.price, - @required this.subscriptionPeriod, - @required this.introductoryPrice, + required this.productIdentifier, + required this.localizedTitle, + required this.localizedDescription, + required this.priceLocale, + this.subscriptionGroupIdentifier, + required this.price, + this.subscriptionPeriod, + this.introductoryPrice, }); /// Constructing an instance from a map from the Objective-C layer. /// /// This method should only be used with `map` values returned by [SkProductResponseWrapper.fromJson]. - /// The `map` parameter must not be null. - factory SKProductWrapper.fromJson(Map map) { - assert(map != null, 'Map must not be null.'); + factory SKProductWrapper.fromJson(Map map) { return _$SKProductWrapperFromJson(map); } /// The unique identifier of the product. + @JsonKey(defaultValue: '') final String productIdentifier; /// The localizedTitle of the product. /// /// It is localized based on the current locale. + @JsonKey(defaultValue: '') final String localizedTitle; /// The localized description of the product. /// /// It is localized based on the current locale. + @JsonKey(defaultValue: '') final String localizedDescription; /// Includes locale information about the price, e.g. `$` as the currency symbol for US locale. @@ -257,26 +271,29 @@ class SKProductWrapper { /// The subscription group identifier. /// + /// If the product is not a subscription, the value is `null`. + /// /// A subscription group is a collection of subscription products. /// Check [SubscriptionGroup](https://developer.apple.com/app-store/subscriptions/) for more details about subscription group. - final String subscriptionGroupIdentifier; + final String? subscriptionGroupIdentifier; /// The price of the product, in the currency that is defined in [priceLocale]. + @JsonKey(defaultValue: '') final String price; /// The object represents the subscription period of the product. /// /// Can be [null] is the product is not a subscription. - final SKProductSubscriptionPeriodWrapper subscriptionPeriod; + final SKProductSubscriptionPeriodWrapper? subscriptionPeriod; /// The object represents the duration of single subscription period. /// - /// This is only available if you set up the introductory price in the App Store Connect, otherwise it will be null. + /// This is only available if you set up the introductory price in the App Store Connect, otherwise the value is `null`. /// Programmer is also responsible to determine if the user is eligible to receive it. See https://developer.apple.com/documentation/storekit/in-app_purchase/offering_introductory_pricing_in_your_app?language=objc /// for more details. /// The [subscriptionPeriod] of the discount is independent of the product's [subscriptionPeriod], /// and their units and duration do not have to be matched. - final SKProductDiscountWrapper introductoryPrice; + final SKProductDiscountWrapper? introductoryPrice; @override bool operator ==(Object other) { @@ -286,7 +303,7 @@ class SKProductWrapper { if (other.runtimeType != runtimeType) { return false; } - final SKProductWrapper typedOther = other; + final SKProductWrapper typedOther = other as SKProductWrapper; return typedOther.productIdentifier == productIdentifier && typedOther.localizedTitle == localizedTitle && typedOther.localizedDescription == localizedDescription && @@ -319,21 +336,24 @@ class SKProductWrapper { class SKPriceLocaleWrapper { /// Creates a new price locale for `currencySymbol` and `currencyCode`. SKPriceLocaleWrapper( - {@required this.currencySymbol, @required this.currencyCode}); + {required this.currencySymbol, required this.currencyCode}); /// Constructing an instance from a map from the Objective-C layer. /// /// This method should only be used with `map` values returned by [SKProductWrapper.fromJson] and [SKProductDiscountWrapper.fromJson]. - /// The `map` parameter must not be null. - factory SKPriceLocaleWrapper.fromJson(Map map) { - assert(map != null, 'Map must not be null.'); + factory SKPriceLocaleWrapper.fromJson(Map? map) { + if (map == null) { + return SKPriceLocaleWrapper(currencyCode: '', currencySymbol: ''); + } return _$SKPriceLocaleWrapperFromJson(map); } ///The currency symbol for the locale, e.g. $ for US locale. + @JsonKey(defaultValue: '') final String currencySymbol; ///The currency code for the locale, e.g. USD for US locale. + @JsonKey(defaultValue: '') final String currencyCode; @override @@ -344,7 +364,7 @@ class SKPriceLocaleWrapper { if (other.runtimeType != runtimeType) { return false; } - final SKPriceLocaleWrapper typedOther = other; + final SKPriceLocaleWrapper typedOther = other as SKPriceLocaleWrapper; return typedOther.currencySymbol == currencySymbol && typedOther.currencyCode == currencyCode; } diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.g.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.g.dart index cf27852263ba..8c2eed3d6070 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.g.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.g.dart @@ -8,12 +8,16 @@ part of 'sk_product_wrapper.dart'; SkProductResponseWrapper _$SkProductResponseWrapperFromJson(Map json) { return SkProductResponseWrapper( - products: (json['products'] as List) - .map((e) => SKProductWrapper.fromJson(e as Map)) - .toList(), - invalidProductIdentifiers: (json['invalidProductIdentifiers'] as List) - .map((e) => e as String) - .toList(), + products: (json['products'] as List?) + ?.map((e) => + SKProductWrapper.fromJson(Map.from(e as Map))) + .toList() ?? + [], + invalidProductIdentifiers: + (json['invalidProductIdentifiers'] as List?) + ?.map((e) => e as String) + .toList() ?? + [], ); } @@ -27,8 +31,9 @@ Map _$SkProductResponseWrapperToJson( SKProductSubscriptionPeriodWrapper _$SKProductSubscriptionPeriodWrapperFromJson( Map json) { return SKProductSubscriptionPeriodWrapper( - numberOfUnits: json['numberOfUnits'] as int, - unit: _$enumDecodeNullable(_$SKSubscriptionPeriodUnitEnumMap, json['unit']), + numberOfUnits: json['numberOfUnits'] as int? ?? 0, + unit: const SKSubscriptionPeriodUnitConverter() + .fromJson(json['unit'] as int?), ); } @@ -36,61 +41,23 @@ Map _$SKProductSubscriptionPeriodWrapperToJson( SKProductSubscriptionPeriodWrapper instance) => { 'numberOfUnits': instance.numberOfUnits, - 'unit': _$SKSubscriptionPeriodUnitEnumMap[instance.unit], + 'unit': const SKSubscriptionPeriodUnitConverter().toJson(instance.unit), }; -T _$enumDecode( - Map enumValues, - dynamic source, { - T unknownValue, -}) { - if (source == null) { - throw ArgumentError('A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}'); - } - - final value = enumValues.entries - .singleWhere((e) => e.value == source, orElse: () => null) - ?.key; - - if (value == null && unknownValue == null) { - throw ArgumentError('`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}'); - } - return value ?? unknownValue; -} - -T _$enumDecodeNullable( - Map enumValues, - dynamic source, { - T unknownValue, -}) { - if (source == null) { - return null; - } - return _$enumDecode(enumValues, source, unknownValue: unknownValue); -} - -const _$SKSubscriptionPeriodUnitEnumMap = { - SKSubscriptionPeriodUnit.day: 0, - SKSubscriptionPeriodUnit.week: 1, - SKSubscriptionPeriodUnit.month: 2, - SKSubscriptionPeriodUnit.year: 3, -}; - SKProductDiscountWrapper _$SKProductDiscountWrapperFromJson(Map json) { return SKProductDiscountWrapper( - price: json['price'] as String, - priceLocale: json['priceLocale'] == null - ? null - : SKPriceLocaleWrapper.fromJson(json['priceLocale'] as Map), - numberOfPeriods: json['numberOfPeriods'] as int, - paymentMode: _$enumDecodeNullable( - _$SKProductDiscountPaymentModeEnumMap, json['paymentMode']), - subscriptionPeriod: json['subscriptionPeriod'] == null - ? null - : SKProductSubscriptionPeriodWrapper.fromJson( - json['subscriptionPeriod'] as Map), + price: json['price'] as String? ?? '', + priceLocale: + SKPriceLocaleWrapper.fromJson((json['priceLocale'] as Map?)?.map( + (k, e) => MapEntry(k as String, e), + )), + numberOfPeriods: json['numberOfPeriods'] as int? ?? 0, + paymentMode: const SKProductDiscountPaymentModeConverter() + .fromJson(json['paymentMode'] as int?), + subscriptionPeriod: SKProductSubscriptionPeriodWrapper.fromJson( + (json['subscriptionPeriod'] as Map?)?.map( + (k, e) => MapEntry(k as String, e), + )), ); } @@ -100,34 +67,32 @@ Map _$SKProductDiscountWrapperToJson( 'price': instance.price, 'priceLocale': instance.priceLocale, 'numberOfPeriods': instance.numberOfPeriods, - 'paymentMode': - _$SKProductDiscountPaymentModeEnumMap[instance.paymentMode], + 'paymentMode': const SKProductDiscountPaymentModeConverter() + .toJson(instance.paymentMode), 'subscriptionPeriod': instance.subscriptionPeriod, }; -const _$SKProductDiscountPaymentModeEnumMap = { - SKProductDiscountPaymentMode.payAsYouGo: 0, - SKProductDiscountPaymentMode.payUpFront: 1, - SKProductDiscountPaymentMode.freeTrail: 2, -}; - SKProductWrapper _$SKProductWrapperFromJson(Map json) { return SKProductWrapper( - productIdentifier: json['productIdentifier'] as String, - localizedTitle: json['localizedTitle'] as String, - localizedDescription: json['localizedDescription'] as String, - priceLocale: json['priceLocale'] == null - ? null - : SKPriceLocaleWrapper.fromJson(json['priceLocale'] as Map), - subscriptionGroupIdentifier: json['subscriptionGroupIdentifier'] as String, - price: json['price'] as String, + productIdentifier: json['productIdentifier'] as String? ?? '', + localizedTitle: json['localizedTitle'] as String? ?? '', + localizedDescription: json['localizedDescription'] as String? ?? '', + priceLocale: + SKPriceLocaleWrapper.fromJson((json['priceLocale'] as Map?)?.map( + (k, e) => MapEntry(k as String, e), + )), + subscriptionGroupIdentifier: json['subscriptionGroupIdentifier'] as String?, + price: json['price'] as String? ?? '', subscriptionPeriod: json['subscriptionPeriod'] == null ? null : SKProductSubscriptionPeriodWrapper.fromJson( - json['subscriptionPeriod'] as Map), + (json['subscriptionPeriod'] as Map?)?.map( + (k, e) => MapEntry(k as String, e), + )), introductoryPrice: json['introductoryPrice'] == null ? null - : SKProductDiscountWrapper.fromJson(json['introductoryPrice'] as Map), + : SKProductDiscountWrapper.fromJson( + Map.from(json['introductoryPrice'] as Map)), ); } @@ -145,8 +110,8 @@ Map _$SKProductWrapperToJson(SKProductWrapper instance) => SKPriceLocaleWrapper _$SKPriceLocaleWrapperFromJson(Map json) { return SKPriceLocaleWrapper( - currencySymbol: json['currencySymbol'] as String, - currencyCode: json['currencyCode'] as String, + currencySymbol: json['currencySymbol'] as String? ?? '', + currencyCode: json['currencyCode'] as String? ?? '', ); } diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_receipt_manager.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_receipt_manager.dart index 85af9dedc7c3..16bcb77a2c70 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_receipt_manager.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_receipt_manager.dart @@ -14,8 +14,9 @@ class SKReceiptManager { /// There are 2 ways to do so. Either validate locally or validate with App Store. /// For more details on how to validate the receipt data, you can refer to Apple's document about [`About Receipt Validation`](https://developer.apple.com/library/archive/releasenotes/General/ValidateAppStoreReceipt/Introduction.html#//apple_ref/doc/uid/TP40010573-CH105-SW1). /// If the receipt is invalid or missing, you can use [SKRequestMaker.startRefreshReceiptRequest] to request a new receipt. - static Future retrieveReceiptData() { - return channel.invokeMethod( - '-[InAppPurchasePlugin retrieveReceiptData:result:]'); + static Future retrieveReceiptData() async { + return (await channel.invokeMethod( + '-[InAppPurchasePlugin retrieveReceiptData:result:]')) ?? + ''; } } diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_request_maker.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_request_maker.dart index 959113cd66d8..c22df0a9dbdd 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_request_maker.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_request_maker.dart @@ -24,7 +24,7 @@ class SKRequestMaker { /// A [PlatformException] is thrown if the platform code making the request fails. Future startProductRequest( List productIdentifiers) async { - final Map productResponseMap = + final Map? productResponseMap = await channel.invokeMapMethod( '-[InAppPurchasePlugin startProductRequest:result:]', productIdentifiers, @@ -47,7 +47,8 @@ class SKRequestMaker { /// * isExpired: whether the receipt is expired. /// * isRevoked: whether the receipt has been revoked. /// * isVolumePurchase: whether the receipt is a Volume Purchase Plan receipt. - Future startRefreshReceiptRequest({Map receiptProperties}) { + Future startRefreshReceiptRequest( + {Map? receiptProperties}) { return channel.invokeMethod( '-[InAppPurchasePlugin refreshReceipt:result:]', receiptProperties, diff --git a/packages/in_app_purchase/pubspec.yaml b/packages/in_app_purchase/pubspec.yaml index 6a6c525132da..f847a81291be 100644 --- a/packages/in_app_purchase/pubspec.yaml +++ b/packages/in_app_purchase/pubspec.yaml @@ -1,30 +1,26 @@ name: in_app_purchase description: A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases through the App Store and Google Play. homepage: https://github.com/flutter/plugins/tree/master/packages/in_app_purchase -version: 0.3.5+2 +version: 0.4.0 dependencies: - async: ^2.0.8 - collection: ^1.14.11 flutter: sdk: flutter - json_annotation: ^3.0.0 - meta: ^1.1.6 + json_annotation: ^4.0.0 + meta: ^1.3.0 + collection: ^1.15.0 dev_dependencies: - build_runner: ^1.0.0 - json_serializable: ^3.2.0 + build_runner: ^1.11.1 + json_serializable: ^4.0.0 flutter_test: sdk: flutter flutter_driver: sdk: flutter - in_app_purchase_example: - path: example/ - test: ^1.5.2 - shared_preferences: ^0.5.2 + test: ^1.16.0 integration_test: path: ../integration_test - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: plugin: @@ -36,5 +32,5 @@ flutter: pluginClass: InAppPurchasePlugin environment: - sdk: ">=2.3.0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart b/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart index eee33a698237..d415007284c8 100644 --- a/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart +++ b/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart @@ -16,7 +16,7 @@ void main() { TestWidgetsFlutterBinding.ensureInitialized(); final StubInAppPurchasePlatform stubPlatform = StubInAppPurchasePlatform(); - BillingClient billingClient; + late BillingClient billingClient; setUpAll(() => channel.setMockMethodCallHandler(stubPlatform.fakeMethodCallHandler)); @@ -96,6 +96,20 @@ void main() { equals( {'handle': 0, 'enablePendingPurchases': true})); }); + + test('handles method channel returning null', () async { + stubPlatform.addResponse( + name: methodName, + value: null, + ); + + expect( + await billingClient.startConnection( + onBillingServiceDisconnected: () {}), + equals(BillingResultWrapper( + responseCode: BillingResponse.error, + debugMessage: kInvalidBillingResultErrorMessage))); + }); }); test('endConnection', () async { @@ -151,6 +165,20 @@ void main() { expect(response.billingResult, equals(billingResult)); expect(response.skuDetailsList, contains(dummySkuDetails)); }); + + test('handles null method channel response', () async { + stubPlatform.addResponse(name: queryMethodName, value: null); + + final SkuDetailsResponseWrapper response = await billingClient + .querySkuDetails( + skuType: SkuType.inapp, skusList: ['invalid']); + + BillingResultWrapper billingResult = BillingResultWrapper( + responseCode: BillingResponse.error, + debugMessage: kInvalidBillingResultErrorMessage); + expect(response.billingResult, equals(billingResult)); + expect(response.skuDetailsList, isEmpty); + }); }); group('launchBillingFlow', () { @@ -197,6 +225,19 @@ void main() { expect(arguments['sku'], equals(skuDetails.sku)); expect(arguments['accountId'], isNull); }); + + test('handles method channel returning null', () async { + stubPlatform.addResponse( + name: launchMethodName, + value: null, + ); + final SkuDetailsWrapper skuDetails = dummySkuDetails; + expect( + await billingClient.launchBillingFlow(sku: skuDetails.sku), + equals(BillingResultWrapper( + responseCode: BillingResponse.error, + debugMessage: kInvalidBillingResultErrorMessage))); + }); }); group('queryPurchases', () { @@ -228,10 +269,6 @@ void main() { expect(response.purchasesList, equals(expectedList)); }); - test('checks for null params', () async { - expect(() => billingClient.queryPurchases(null), throwsAssertionError); - }); - test('handles empty purchases', () async { final BillingResponse expectedCode = BillingResponse.userCanceled; const String debugMessage = 'dummy message'; @@ -251,6 +288,23 @@ void main() { expect(response.responseCode, equals(expectedCode)); expect(response.purchasesList, isEmpty); }); + + test('handles method channel returning null', () async { + stubPlatform.addResponse( + name: queryPurchasesMethodName, + value: null, + ); + final PurchasesResultWrapper response = + await billingClient.queryPurchases(SkuType.inapp); + + expect( + response.billingResult, + equals(BillingResultWrapper( + responseCode: BillingResponse.error, + debugMessage: kInvalidBillingResultErrorMessage))); + expect(response.responseCode, BillingResponse.error); + expect(response.purchasesList, isEmpty); + }); }); group('queryPurchaseHistory', () { @@ -282,11 +336,6 @@ void main() { expect(response.purchaseHistoryRecordList, equals(expectedList)); }); - test('checks for null params', () async { - expect( - () => billingClient.queryPurchaseHistory(null), throwsAssertionError); - }); - test('handles empty purchases', () async { final BillingResponse expectedCode = BillingResponse.userCanceled; const String debugMessage = 'dummy message'; @@ -303,6 +352,22 @@ void main() { expect(response.billingResult, equals(expectedBillingResult)); expect(response.purchaseHistoryRecordList, isEmpty); }); + + test('handles method channel returning null', () async { + stubPlatform.addResponse( + name: queryPurchaseHistoryMethodName, + value: null, + ); + final PurchasesHistoryResult response = + await billingClient.queryPurchaseHistory(SkuType.inapp); + + expect( + response.billingResult, + equals(BillingResultWrapper( + responseCode: BillingResponse.error, + debugMessage: kInvalidBillingResultErrorMessage))); + expect(response.purchaseHistoryRecordList, isEmpty); + }); }); group('consume purchases', () { @@ -322,6 +387,21 @@ void main() { expect(billingResult, equals(expectedBillingResult)); }); + + test('handles method channel returning null', () async { + stubPlatform.addResponse( + name: consumeMethodName, + value: null, + ); + final BillingResultWrapper billingResult = await billingClient + .consumeAsync('dummy token', developerPayload: 'dummy payload'); + + expect( + billingResult, + equals(BillingResultWrapper( + responseCode: BillingResponse.error, + debugMessage: kInvalidBillingResultErrorMessage))); + }); }); group('acknowledge purchases', () { @@ -342,5 +422,20 @@ void main() { expect(billingResult, equals(expectedBillingResult)); }); + test('handles method channel returning null', () async { + stubPlatform.addResponse( + name: acknowledgeMethodName, + value: null, + ); + final BillingResultWrapper billingResult = + await billingClient.acknowledgePurchase('dummy token', + developerPayload: 'dummy payload'); + + expect( + billingResult, + equals(BillingResultWrapper( + responseCode: BillingResponse.error, + debugMessage: kInvalidBillingResultErrorMessage))); + }); }); } diff --git a/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart b/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart index 978252a3d118..7f3de2742603 100644 --- a/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart +++ b/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart @@ -62,6 +62,7 @@ void main() { expect(details.purchaseID, dummyPurchase.orderId); expect(details.productID, dummyPurchase.sku); expect(details.transactionDate, dummyPurchase.purchaseTime.toString()); + expect(details.verificationData, isNotNull); expect(details.verificationData.source, IAPSource.GooglePlay); expect(details.verificationData.localVerificationData, dummyPurchase.originalJson); @@ -111,6 +112,18 @@ void main() { expect(parsed.responseCode, equals(expected.responseCode)); expect(parsed.purchasesList, containsAll(expected.purchasesList)); }); + + test('parsed from empty map', () { + final PurchasesResultWrapper parsed = + PurchasesResultWrapper.fromJson({}); + expect( + parsed.billingResult, + equals(BillingResultWrapper( + responseCode: BillingResponse.error, + debugMessage: kInvalidBillingResultErrorMessage))); + expect(parsed.responseCode, BillingResponse.error); + expect(parsed.purchasesList, isEmpty); + }); }); group('PurchasesHistoryResult', () { @@ -139,6 +152,17 @@ void main() { expect(parsed.purchaseHistoryRecordList, containsAll(expected.purchaseHistoryRecordList)); }); + + test('parsed from empty map', () { + final PurchasesHistoryResult parsed = + PurchasesHistoryResult.fromJson({}); + expect( + parsed.billingResult, + equals(BillingResultWrapper( + responseCode: BillingResponse.error, + debugMessage: kInvalidBillingResultErrorMessage))); + expect(parsed.purchaseHistoryRecordList, isEmpty); + }); }); } diff --git a/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart b/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart index c305e6df88cc..13715eeb9fc0 100644 --- a/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart +++ b/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart @@ -99,6 +99,33 @@ void main() { expect(parsed.billingResult, equals(expected.billingResult)); expect(parsed.skuDetailsList, containsAll(expected.skuDetailsList)); }); + + test('fromJson creates an object with default values', () { + final SkuDetailsResponseWrapper skuDetails = + SkuDetailsResponseWrapper.fromJson({}); + expect( + skuDetails.billingResult, + equals(BillingResultWrapper( + responseCode: BillingResponse.error, + debugMessage: kInvalidBillingResultErrorMessage))); + expect(skuDetails.skuDetailsList, isEmpty); + }); + }); + + group('BillingResultWrapper', () { + test('fromJson on empty map creates an object with default values', () { + final BillingResultWrapper billingResult = + BillingResultWrapper.fromJson({}); + expect(billingResult.debugMessage, kInvalidBillingResultErrorMessage); + expect(billingResult.responseCode, BillingResponse.error); + }); + + test('fromJson on null creates an object with default values', () { + final BillingResultWrapper billingResult = + BillingResultWrapper.fromJson(null); + expect(billingResult.debugMessage, kInvalidBillingResultErrorMessage); + expect(billingResult.responseCode, BillingResponse.error); + }); }); } diff --git a/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart b/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart index b22737ca041b..bfcab085e26a 100644 --- a/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart +++ b/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart @@ -15,6 +15,7 @@ import 'package:in_app_purchase/src/in_app_purchase/app_store_connection.dart'; import 'package:in_app_purchase/src/in_app_purchase/in_app_purchase_connection.dart'; import 'package:in_app_purchase/src/in_app_purchase/product_details.dart'; import 'package:in_app_purchase/store_kit_wrappers.dart'; +import '../billing_client_wrappers/purchase_wrapper_test.dart'; import '../store_kit_wrappers/sk_test_stub_objects.dart'; void main() { @@ -61,10 +62,11 @@ void main() { .queryProductDetails(['123', '456', '789'].toSet()); expect(response.productDetails, []); expect(response.notFoundIDs, ['123', '456', '789']); - expect(response.error.source, IAPSource.AppStore); - expect(response.error.code, 'error_code'); - expect(response.error.message, 'error_message'); - expect(response.error.details, {'info': 'error_info'}); + expect(response.error, isNotNull); + expect(response.error!.source, IAPSource.AppStore); + expect(response.error!.code, 'error_code'); + expect(response.error!.message, 'error_message'); + expect(response.error!.details, {'info': 'error_info'}); }); }); @@ -81,6 +83,8 @@ void main() { fakeIOSPlatform.transactions.first.transactionIdentifier); expect(response.pastPurchases.last.purchaseID, fakeIOSPlatform.transactions.last.transactionIdentifier); + expect(response.pastPurchases, isNotEmpty); + expect(response.pastPurchases.first.verificationData, isNotNull); expect( response.pastPurchases.first.verificationData.localVerificationData, 'dummy base64data'); @@ -97,7 +101,7 @@ void main() { Stream> stream = AppStoreConnection.instance.purchaseUpdatedStream; - StreamSubscription subscription; + late StreamSubscription subscription; subscription = stream.listen((purchaseDetailsList) { if (purchaseDetailsList.first.status == PurchaseStatus.purchased) { completer.complete(purchaseDetailsList); @@ -130,9 +134,10 @@ void main() { QueryPurchaseDetailsResponse response = await AppStoreConnection.instance.queryPastPurchases(); expect(response.pastPurchases, isEmpty); - expect(response.error.source, IAPSource.AppStore); - expect(response.error.message, 'error_test'); - expect(response.error.details, {'message': 'errorMessage'}); + expect(response.error, isNotNull); + expect(response.error!.source, IAPSource.AppStore); + expect(response.error!.message, 'error_test'); + expect(response.error!.details, {'message': 'errorMessage'}); }); test('receipt error should populate null to verificationData.data', @@ -142,18 +147,19 @@ void main() { await AppStoreConnection.instance.queryPastPurchases(); expect( response.pastPurchases.first.verificationData.localVerificationData, - null); + isEmpty); expect( response.pastPurchases.first.verificationData.serverVerificationData, - null); + isEmpty); }); }); group('refresh receipt data', () { test('should refresh receipt data', () async { - PurchaseVerificationData receiptData = + PurchaseVerificationData? receiptData = await AppStoreConnection.instance.refreshPurchaseVerificationData(); - expect(receiptData.source, IAPSource.AppStore); + expect(receiptData, isNotNull); + expect(receiptData!.source, IAPSource.AppStore); expect(receiptData.localVerificationData, 'refreshed receipt data'); expect(receiptData.serverVerificationData, 'refreshed receipt data'); }); @@ -168,7 +174,7 @@ void main() { Stream> stream = AppStoreConnection.instance.purchaseUpdatedStream; - StreamSubscription subscription; + late StreamSubscription subscription; subscription = stream.listen((purchaseDetailsList) { details.addAll(purchaseDetailsList); if (purchaseDetailsList.first.status == PurchaseStatus.purchased) { @@ -195,7 +201,7 @@ void main() { Stream> stream = AppStoreConnection.instance.purchaseUpdatedStream; - StreamSubscription subscription; + late StreamSubscription subscription; subscription = stream.listen((purchaseDetailsList) { details.addAll(purchaseDetailsList); if (purchaseDetailsList.first.status == PurchaseStatus.purchased) { @@ -228,16 +234,16 @@ void main() { fakeIOSPlatform.testTransactionFail = true; List details = []; Completer completer = Completer(); - IAPError error; + late IAPError error; Stream> stream = AppStoreConnection.instance.purchaseUpdatedStream; - StreamSubscription subscription; + late StreamSubscription subscription; subscription = stream.listen((purchaseDetailsList) { details.addAll(purchaseDetailsList); purchaseDetailsList.forEach((purchaseDetails) { if (purchaseDetails.status == PurchaseStatus.error) { - error = purchaseDetails.error; + error = purchaseDetails.error!; completer.complete(error); subscription.cancel(); } @@ -263,7 +269,7 @@ void main() { Completer completer = Completer(); Stream> stream = AppStoreConnection.instance.purchaseUpdatedStream; - StreamSubscription subscription; + late StreamSubscription subscription; subscription = stream.listen((purchaseDetailsList) { details.addAll(purchaseDetailsList); purchaseDetailsList.forEach((purchaseDetails) { @@ -288,7 +294,9 @@ void main() { group('consume purchase', () { test('should throw when calling consume purchase on iOS', () async { - expect(() => AppStoreConnection.instance.consumePurchase(null), + expect( + () => AppStoreConnection.instance + .consumePurchase(PurchaseDetails.fromPurchase(dummyPurchase)), throwsUnsupportedError); }); }); @@ -300,16 +308,16 @@ class FakeIOSPlatform { } // pre-configured store informations - String receiptData; - Set validProductIDs; - Map validProducts; - List transactions; - List finishedTransactions; - bool testRestoredTransactionsNull; - bool testTransactionFail; - PlatformException queryProductException; - PlatformException restoreException; - SKError testRestoredError; + String? receiptData; + late Set validProductIDs; + late Map validProducts; + late List transactions; + late List finishedTransactions; + late bool testRestoredTransactionsNull; + late bool testTransactionFail; + PlatformException? queryProductException; + PlatformException? restoreException; + SKError? testRestoredError; void reset() { transactions = []; @@ -317,7 +325,8 @@ class FakeIOSPlatform { validProductIDs = ['123', '456'].toSet(); validProducts = Map(); for (String validID in validProductIDs) { - Map productWrapperMap = buildProductMap(dummyProductWrapper); + Map productWrapperMap = + buildProductMap(dummyProductWrapper); productWrapperMap['productIdentifier'] = validID; validProducts[validID] = SKProductWrapper.fromJson(productWrapperMap); } @@ -350,7 +359,7 @@ class FakeIOSPlatform { SKPaymentTransactionWrapper createPendingTransaction(String id) { return SKPaymentTransactionWrapper( - transactionIdentifier: null, + transactionIdentifier: '', payment: SKPaymentWrapper(productIdentifier: id), transactionState: SKPaymentTransactionStateWrapper.purchasing, transactionTimeStamp: 123123.121, @@ -371,7 +380,7 @@ class FakeIOSPlatform { SKPaymentTransactionWrapper createFailedTransaction(String productId) { return SKPaymentTransactionWrapper( - transactionIdentifier: null, + transactionIdentifier: '', payment: SKPaymentWrapper(productIdentifier: productId), transactionState: SKPaymentTransactionStateWrapper.failed, transactionTimeStamp: 123123.121, @@ -388,7 +397,7 @@ class FakeIOSPlatform { return Future.value(true); case '-[InAppPurchasePlugin startProductRequest:result:]': if (queryProductException != null) { - throw queryProductException; + throw queryProductException!; } List productIDS = List.castFrom(call.arguments); @@ -399,7 +408,7 @@ class FakeIOSPlatform { if (!validProductIDs.contains(productID)) { invalidFound.add(productID); } else { - products.add(validProducts[productID]); + products.add(validProducts[productID]!); } } SkProductResponseWrapper response = SkProductResponseWrapper( @@ -408,11 +417,11 @@ class FakeIOSPlatform { buildProductResponseMap(response)); case '-[InAppPurchasePlugin restoreTransactions:result:]': if (restoreException != null) { - throw restoreException; + throw restoreException!; } if (testRestoredError != null) { AppStoreConnection.observer - .restoreCompletedTransactionsFailed(error: testRestoredError); + .restoreCompletedTransactionsFailed(error: testRestoredError!); return Future.sync(() {}); } if (!testRestoredTransactionsNull) { @@ -428,7 +437,6 @@ class FakeIOSPlatform { } else { throw PlatformException(code: 'no_receipt_data'); } - break; case '-[InAppPurchasePlugin refreshReceipt:result:]': receiptData = 'refreshed receipt data'; return Future.sync(() {}); @@ -445,7 +453,8 @@ class FakeIOSPlatform { .updatedTransactions(transactions: [transaction_failed]); } else { SKPaymentTransactionWrapper transaction_finished = - createPurchasedTransaction(id, transaction.transactionIdentifier); + createPurchasedTransaction( + id, transaction.transactionIdentifier ?? ''); AppStoreConnection.observer .updatedTransactions(transactions: [transaction_finished]); } diff --git a/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart b/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart index 9294d2b60d1e..79c2ee436c5c 100644 --- a/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart +++ b/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart @@ -24,7 +24,7 @@ void main() { TestWidgetsFlutterBinding.ensureInitialized(); final StubInAppPurchasePlatform stubPlatform = StubInAppPurchasePlatform(); - GooglePlayConnection connection; + late GooglePlayConnection connection; const String startConnectionCall = 'BillingClient#startConnection(BillingClientStateListener)'; const String endConnectionCall = 'BillingClient#endConnection()'; @@ -149,10 +149,11 @@ void main() { await connection.queryProductDetails(['invalid'].toSet()); expect(response.notFoundIDs, ['invalid']); expect(response.productDetails, isEmpty); - expect(response.error.source, IAPSource.GooglePlay); - expect(response.error.code, 'error_code'); - expect(response.error.message, 'error_message'); - expect(response.error.details, {'info': 'error_info'}); + expect(response.error, isNotNull); + expect(response.error!.source, IAPSource.GooglePlay); + expect(response.error!.code, 'error_code'); + expect(response.error!.message, 'error_message'); + expect(response.error!.details, {'info': 'error_info'}); }); }); @@ -172,8 +173,10 @@ void main() { final QueryPurchaseDetailsResponse response = await connection.queryPastPurchases(); expect(response.pastPurchases, isEmpty); - expect(response.error.message, BillingResponse.developerError.toString()); - expect(response.error.source, IAPSource.GooglePlay); + expect(response.error, isNotNull); + expect( + response.error!.message, BillingResponse.developerError.toString()); + expect(response.error!.source, IAPSource.GooglePlay); }); test('returns SkuDetailsResponseWrapper', () async { @@ -221,9 +224,10 @@ void main() { final QueryPurchaseDetailsResponse response = await connection.queryPastPurchases(); expect(response.pastPurchases, isEmpty); - expect(response.error.code, 'error_code'); - expect(response.error.message, 'error_message'); - expect(response.error.details, {'info': 'error_info'}); + expect(response.error, isNotNull); + expect(response.error!.code, 'error_code'); + expect(response.error!.message, 'error_message'); + expect(response.error!.details, {'info': 'error_info'}); }); }); @@ -277,7 +281,7 @@ void main() { PurchaseDetails purchaseDetails; Stream purchaseStream = GooglePlayConnection.instance.purchaseUpdatedStream; - StreamSubscription subscription; + late StreamSubscription subscription; subscription = purchaseStream.listen((_) { purchaseDetails = _.first; completer.complete(purchaseDetails); @@ -320,7 +324,7 @@ void main() { PurchaseDetails purchaseDetails; Stream purchaseStream = GooglePlayConnection.instance.purchaseUpdatedStream; - StreamSubscription subscription; + late StreamSubscription subscription; subscription = purchaseStream.listen((_) { purchaseDetails = _.first; completer.complete(purchaseDetails); @@ -334,9 +338,9 @@ void main() { PurchaseDetails result = await completer.future; expect(result.error, isNotNull); - expect(result.error.source, IAPSource.GooglePlay); + expect(result.error!.source, IAPSource.GooglePlay); expect(result.status, PurchaseStatus.error); - expect(result.purchaseID, isNull); + expect(result.purchaseID, isEmpty); }); test('buy consumable with auto consume, serializes and deserializes data', @@ -392,7 +396,7 @@ void main() { PurchaseDetails purchaseDetails; Stream purchaseStream = GooglePlayConnection.instance.purchaseUpdatedStream; - StreamSubscription subscription; + late StreamSubscription subscription; subscription = purchaseStream.listen((_) { purchaseDetails = _.first; completer.complete(purchaseDetails); @@ -407,7 +411,8 @@ void main() { // Verify that the result has succeeded PurchaseDetails result = await completer.future; expect(launchResult, isTrue); - expect(result.billingClientPurchase.purchaseToken, + expect(result.billingClientPurchase, isNotNull); + expect(result.billingClientPurchase!.purchaseToken, await consumeCompleter.future); expect(result.status, PurchaseStatus.purchased); expect(result.error, isNull); @@ -501,7 +506,7 @@ void main() { PurchaseDetails purchaseDetails; Stream purchaseStream = GooglePlayConnection.instance.purchaseUpdatedStream; - StreamSubscription subscription; + late StreamSubscription subscription; subscription = purchaseStream.listen((_) { purchaseDetails = _.first; completer.complete(purchaseDetails); @@ -515,11 +520,12 @@ void main() { // Verify that the result has an error for the failed consumption PurchaseDetails result = await completer.future; - expect(result.billingClientPurchase.purchaseToken, + expect(result.billingClientPurchase, isNotNull); + expect(result.billingClientPurchase!.purchaseToken, await consumeCompleter.future); expect(result.status, PurchaseStatus.error); expect(result.error, isNotNull); - expect(result.error.code, kConsumptionFailedErrorCode); + expect(result.error!.code, kConsumptionFailedErrorCode); }); test( @@ -574,7 +580,7 @@ void main() { Stream purchaseStream = GooglePlayConnection.instance.purchaseUpdatedStream; - StreamSubscription subscription; + late StreamSubscription subscription; subscription = purchaseStream.listen((_) { consumeCompleter.complete(null); subscription.cancel(); @@ -629,10 +635,6 @@ void main() { await GooglePlayConnection.instance.completePurchase( purchaseDetails, developerPayload: 'dummy payload'); - print('pending ${billingResultWrapper.responseCode}'); - print('expectedBillingResult ${expectedBillingResult.responseCode}'); - print('pending ${billingResultWrapper.debugMessage}'); - print('expectedBillingResult ${expectedBillingResult.debugMessage}'); expect(billingResultWrapper, equals(expectedBillingResult)); completer.complete(billingResultWrapper); } diff --git a/packages/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart b/packages/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart index 92ffbc5797e3..d41a1269d6c9 100644 --- a/packages/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart +++ b/packages/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart @@ -20,6 +20,10 @@ void main() { setUp(() {}); + tearDown(() { + fakeIOSPlatform.testReturnNull = false; + }); + group('sk_request_maker', () { test('get products method channel', () async { SkProductResponseWrapper productResponseWrapper = @@ -55,7 +59,7 @@ void main() { test('get products method channel should throw exception', () async { fakeIOSPlatform.getProductRequestFailTest = true; expect( - SKRequestMaker().startProductRequest(['xxx']), + SKRequestMaker().startProductRequest(['xxx']), throwsException, ); fakeIOSPlatform.getProductRequestFailTest = false; @@ -63,10 +67,11 @@ void main() { test('refreshed receipt', () async { int receiptCountBefore = fakeIOSPlatform.refreshReceipt; - await SKRequestMaker() - .startRefreshReceiptRequest(receiptProperties: {"isExpired": true}); + await SKRequestMaker().startRefreshReceiptRequest( + receiptProperties: {"isExpired": true}); expect(fakeIOSPlatform.refreshReceipt, receiptCountBefore + 1); - expect(fakeIOSPlatform.refreshReceiptParam, {"isExpired": true}); + expect(fakeIOSPlatform.refreshReceiptParam, + {"isExpired": true}); }); }); @@ -83,6 +88,12 @@ void main() { expect(await SKPaymentQueueWrapper.canMakePayments(), true); }); + test('canMakePayment returns false if method channel returns null', + () async { + fakeIOSPlatform.testReturnNull = true; + expect(await SKPaymentQueueWrapper.canMakePayments(), false); + }); + test('transactions should return a valid list of transactions', () async { expect(await SKPaymentQueueWrapper().transactions(), isNotEmpty); }); @@ -127,20 +138,20 @@ void main() { class FakeIOSPlatform { FakeIOSPlatform() { channel.setMockMethodCallHandler(onMethodCall); - getProductRequestFailTest = false; } // get product request - List startProductRequestParam; - bool getProductRequestFailTest; + List startProductRequestParam = []; + bool getProductRequestFailTest = false; + bool testReturnNull = false; // refresh receipt request int refreshReceipt = 0; - Map refreshReceiptParam; + late Map refreshReceiptParam; // payment queue List payments = []; List> transactionsFinished = []; - String applicationNameHasTransactionRestored; + String applicationNameHasTransactionRestored = ''; Future onMethodCall(MethodCall call) { switch (call.method) { @@ -157,18 +168,24 @@ class FakeIOSPlatform { buildProductResponseMap(dummyProductResponseWrapper)); case '-[InAppPurchasePlugin refreshReceipt:result:]': refreshReceipt++; - refreshReceiptParam = call.arguments; + refreshReceiptParam = + Map.castFrom(call.arguments); return Future.sync(() {}); // receipt manager case '-[InAppPurchasePlugin retrieveReceiptData:result:]': return Future.value('receipt data'); // payment queue case '-[SKPaymentQueue canMakePayments:]': + if (testReturnNull) { + return Future.value(null); + } return Future.value(true); case '-[SKPaymentQueue transactions]': - return Future>.value([buildTransactionMap(dummyTransaction)]); + return Future>.value( + [buildTransactionMap(dummyTransaction)]); case '-[InAppPurchasePlugin addPayment:result:]': - payments.add(SKPaymentWrapper.fromJson(call.arguments)); + payments.add(SKPaymentWrapper.fromJson( + Map.from(call.arguments))); return Future.sync(() {}); case '-[InAppPurchasePlugin finishTransaction:result:]': transactionsFinished.add(Map.from(call.arguments)); @@ -182,16 +199,18 @@ class FakeIOSPlatform { } class TestPaymentTransactionObserver extends SKTransactionObserverWrapper { - void updatedTransactions({List transactions}) {} + void updatedTransactions( + {required List transactions}) {} - void removedTransactions({List transactions}) {} + void removedTransactions( + {required List transactions}) {} - void restoreCompletedTransactionsFailed({SKError error}) {} + void restoreCompletedTransactionsFailed({required SKError error}) {} void paymentQueueRestoreCompletedTransactionsFinished() {} bool shouldAddStorePayment( - {SKPaymentWrapper payment, SKProductWrapper product}) { + {required SKPaymentWrapper payment, required SKProductWrapper product}) { return true; } } diff --git a/packages/in_app_purchase/test/store_kit_wrappers/sk_product_test.dart b/packages/in_app_purchase/test/store_kit_wrappers/sk_product_test.dart index 2a9066f05c53..6e1f59bf377e 100644 --- a/packages/in_app_purchase/test/store_kit_wrappers/sk_product_test.dart +++ b/packages/in_app_purchase/test/store_kit_wrappers/sk_product_test.dart @@ -3,11 +3,11 @@ // found in the LICENSE file. import 'package:in_app_purchase/src/in_app_purchase/purchase_details.dart'; +import 'package:in_app_purchase/store_kit_wrappers.dart'; import 'package:test/test.dart'; import 'package:in_app_purchase/src/store_kit_wrappers/sk_product_wrapper.dart'; import 'package:in_app_purchase/src/in_app_purchase/in_app_purchase_connection.dart'; import 'package:in_app_purchase/src/in_app_purchase/product_details.dart'; -import 'package:in_app_purchase/store_kit_wrappers.dart'; import 'sk_test_stub_objects.dart'; void main() { @@ -17,17 +17,17 @@ void main() { () { final SKProductSubscriptionPeriodWrapper wrapper = SKProductSubscriptionPeriodWrapper.fromJson( - buildSubscriptionPeriodMap(dummySubscription)); + buildSubscriptionPeriodMap(dummySubscription)!); expect(wrapper, equals(dummySubscription)); }); test( - 'SKProductSubscriptionPeriodWrapper should have properties to be null if map is empty', + 'SKProductSubscriptionPeriodWrapper should have properties to be default values if map is empty', () { final SKProductSubscriptionPeriodWrapper wrapper = SKProductSubscriptionPeriodWrapper.fromJson({}); - expect(wrapper.numberOfUnits, null); - expect(wrapper.unit, null); + expect(wrapper.numberOfUnits, 0); + expect(wrapper.unit, SKSubscriptionPeriodUnit.day); }); test( @@ -39,15 +39,19 @@ void main() { }); test( - 'SKProductDiscountWrapper should have properties to be null if map is empty', + 'SKProductDiscountWrapper should have properties to be default if map is empty', () { final SKProductDiscountWrapper wrapper = SKProductDiscountWrapper.fromJson({}); - expect(wrapper.price, null); - expect(wrapper.priceLocale, null); - expect(wrapper.numberOfPeriods, null); - expect(wrapper.paymentMode, null); - expect(wrapper.subscriptionPeriod, null); + expect(wrapper.price, ''); + expect(wrapper.priceLocale, + SKPriceLocaleWrapper(currencyCode: '', currencySymbol: '')); + expect(wrapper.numberOfPeriods, 0); + expect(wrapper.paymentMode, SKProductDiscountPaymentMode.payAsYouGo); + expect( + wrapper.subscriptionPeriod, + SKProductSubscriptionPeriodWrapper( + numberOfUnits: 0, unit: SKSubscriptionPeriodUnit.day)); }); test('SKProductWrapper should have property values consistent with map', @@ -57,16 +61,18 @@ void main() { expect(wrapper, equals(dummyProductWrapper)); }); - test('SKProductWrapper should have properties to be null if map is empty', + test( + 'SKProductWrapper should have properties to be default if map is empty', () { final SKProductWrapper wrapper = SKProductWrapper.fromJson({}); - expect(wrapper.productIdentifier, null); - expect(wrapper.localizedTitle, null); - expect(wrapper.localizedDescription, null); - expect(wrapper.priceLocale, null); + expect(wrapper.productIdentifier, ''); + expect(wrapper.localizedTitle, ''); + expect(wrapper.localizedDescription, ''); + expect(wrapper.priceLocale, + SKPriceLocaleWrapper(currencyCode: '', currencySymbol: '')); expect(wrapper.subscriptionGroupIdentifier, null); - expect(wrapper.price, null); + expect(wrapper.price, ''); expect(wrapper.subscriptionPeriod, null); }); @@ -132,7 +138,8 @@ void main() { PurchaseDetails.fromSKTransaction(dummyTransaction, 'receipt data'); expect(dummyTransaction.transactionIdentifier, details.purchaseID); expect(dummyTransaction.payment.productIdentifier, details.productID); - expect((dummyTransaction.transactionTimeStamp * 1000).toInt().toString(), + expect(dummyTransaction.transactionTimeStamp, isNotNull); + expect((dummyTransaction.transactionTimeStamp! * 1000).toInt().toString(), details.transactionDate); expect(details.verificationData.localVerificationData, 'receipt data'); expect(details.verificationData.serverVerificationData, 'receipt data'); @@ -141,6 +148,29 @@ void main() { expect(details.billingClientPurchase, null); expect(details.pendingCompletePurchase, true); }); + + test('SKPaymentTransactionWrapper.toFinishMap set correct value', () { + final SKPaymentTransactionWrapper transactionWrapper = + SKPaymentTransactionWrapper( + payment: dummyPayment, + transactionState: SKPaymentTransactionStateWrapper.failed, + transactionIdentifier: 'abcd'); + final Map finishMap = transactionWrapper.toFinishMap(); + expect(finishMap['transactionIdentifier'], 'abcd'); + expect(finishMap['productIdentifier'], dummyPayment.productIdentifier); + }); + + test( + 'SKPaymentTransactionWrapper.toFinishMap should set transactionIdentifier to null when necessary', + () { + final SKPaymentTransactionWrapper transactionWrapper = + SKPaymentTransactionWrapper( + payment: dummyPayment, + transactionState: SKPaymentTransactionStateWrapper.failed); + final Map finishMap = transactionWrapper.toFinishMap(); + expect(finishMap['transactionIdentifier'], null); + }); + test('Should generate correct map of the payment object', () { Map map = dummyPayment.toMap(); expect(map['productIdentifier'], dummyPayment.productIdentifier); diff --git a/packages/in_app_purchase/test/store_kit_wrappers/sk_test_stub_objects.dart b/packages/in_app_purchase/test/store_kit_wrappers/sk_test_stub_objects.dart index c976e80a90a5..f7d86f5cf59b 100644 --- a/packages/in_app_purchase/test/store_kit_wrappers/sk_test_stub_objects.dart +++ b/packages/in_app_purchase/test/store_kit_wrappers/sk_test_stub_objects.dart @@ -74,8 +74,11 @@ Map buildLocaleMap(SKPriceLocaleWrapper local) { }; } -Map buildSubscriptionPeriodMap( - SKProductSubscriptionPeriodWrapper sub) { +Map? buildSubscriptionPeriodMap( + SKProductSubscriptionPeriodWrapper? sub) { + if (sub == null) { + return null; + } return { 'numberOfUnits': sub.numberOfUnits, 'unit': SKSubscriptionPeriodUnit.values.indexOf(sub.unit), @@ -104,7 +107,7 @@ Map buildProductMap(SKProductWrapper product) { 'price': product.price, 'subscriptionPeriod': buildSubscriptionPeriodMap(product.subscriptionPeriod), - 'introductoryPrice': buildDiscountMap(product.introductoryPrice), + 'introductoryPrice': buildDiscountMap(product.introductoryPrice!), }; } @@ -129,17 +132,16 @@ Map buildErrorMap(SKError error) { Map buildTransactionMap( SKPaymentTransactionWrapper transaction) { - if (transaction == null) { - return null; - } - Map map = { + Map map = { 'transactionState': SKPaymentTransactionStateWrapper.values .indexOf(SKPaymentTransactionStateWrapper.purchased), 'payment': transaction.payment.toMap(), - 'originalTransaction': buildTransactionMap(transaction.originalTransaction), + 'originalTransaction': transaction.originalTransaction == null + ? null + : buildTransactionMap(transaction.originalTransaction!), 'transactionTimeStamp': transaction.transactionTimeStamp, 'transactionIdentifier': transaction.transactionIdentifier, - 'error': buildErrorMap(transaction.error), + 'error': buildErrorMap(transaction.error!), }; return map; } diff --git a/packages/in_app_purchase/test/stub_in_app_purchase_platform.dart b/packages/in_app_purchase/test/stub_in_app_purchase_platform.dart index 312479573a68..431d8859d44d 100644 --- a/packages/in_app_purchase/test/stub_in_app_purchase_platform.dart +++ b/packages/in_app_purchase/test/stub_in_app_purchase_platform.dart @@ -9,19 +9,19 @@ typedef void AdditionalSteps(dynamic args); class StubInAppPurchasePlatform { Map _expectedCalls = {}; - Map _additionalSteps = {}; + Map _additionalSteps = {}; void addResponse( - {String name, + {required String name, dynamic value, - AdditionalSteps additionalStepBeforeReturn}) { + AdditionalSteps? additionalStepBeforeReturn}) { _additionalSteps[name] = additionalStepBeforeReturn; _expectedCalls[name] = value; } List _previousCalls = []; List get previousCalls => _previousCalls; - MethodCall previousCallMatching(String name) => _previousCalls - .firstWhere((MethodCall call) => call.method == name, orElse: () => null); + MethodCall previousCallMatching(String name) => + _previousCalls.firstWhere((MethodCall call) => call.method == name); int countPreviousCalls(String name) => _previousCalls.where((MethodCall call) => call.method == name).length; @@ -35,7 +35,7 @@ class StubInAppPurchasePlatform { _previousCalls.add(call); if (_expectedCalls.containsKey(call.method)) { if (_additionalSteps[call.method] != null) { - _additionalSteps[call.method](call.arguments); + _additionalSteps[call.method]!(call.arguments); } return Future.sync(() => _expectedCalls[call.method]); } else { diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index 3e9e50ebd0f4..eceb78cc970c 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -32,6 +32,7 @@ readonly NNBD_PLUGINS_LIST=( "video_player" "webview_flutter" "wifi_info_flutter" + "in_app_purchase" ) # This list contains the list of plugins that have *not* been diff --git a/script/tool/lib/src/publish_check_command.dart b/script/tool/lib/src/publish_check_command.dart index af009952856e..670fedaf2fa1 100644 --- a/script/tool/lib/src/publish_check_command.dart +++ b/script/tool/lib/src/publish_check_command.dart @@ -97,7 +97,7 @@ class PublishCheckCommand extends PluginCommand { await stdInCompleter.future; final String output = outputBuffer.toString(); - return output.contains('Package has 1 warning.') && + return output.contains('Package has 1 warning') && output.contains( 'Packages with an SDK constraint on a pre-release of the Dart SDK should themselves be published as a pre-release version.'); } From 6c10217bb166b510a9fb17f7260a55ed14c1bdfd Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 19 Feb 2021 11:59:35 -0800 Subject: [PATCH 0158/1565] [path_provider] Bump platform interface package to stable NNBD (#3568) --- .../path_provider_platform_interface/CHANGELOG.md | 2 +- .../path_provider_platform_interface/pubspec.yaml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/path_provider/path_provider_platform_interface/CHANGELOG.md b/packages/path_provider/path_provider_platform_interface/CHANGELOG.md index 97121268c790..08dc9f69c7df 100644 --- a/packages/path_provider/path_provider_platform_interface/CHANGELOG.md +++ b/packages/path_provider/path_provider_platform_interface/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.0.0-nullsafety +## 2.0.0 * Migrate to null safety. diff --git a/packages/path_provider/path_provider_platform_interface/pubspec.yaml b/packages/path_provider/path_provider_platform_interface/pubspec.yaml index 946d2ed4b4fd..68b790301270 100644 --- a/packages/path_provider/path_provider_platform_interface/pubspec.yaml +++ b/packages/path_provider/path_provider_platform_interface/pubspec.yaml @@ -3,20 +3,20 @@ description: A common platform interface for the path_provider plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0-nullsafety +version: 2.0.0 dependencies: flutter: sdk: flutter - meta: ^1.3.0-nullsafety.3 - platform: ^3.0.0-nullsafety.4 - plugin_platform_interface: ^1.1.0-nullsafety + meta: ^1.3.0 + platform: ^3.0.0 + plugin_platform_interface: ">=1.0.0 <3.0.0" dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.10.0-nullsafety.1 + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.10.0" From 51c6eac1af9e3a3386de39027b63561e040e2e3c Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 19 Feb 2021 12:38:11 -0800 Subject: [PATCH 0159/1565] [flutter_plugin_android_lifecycle] Bump version for NNBD stable (#3569) --- .../flutter_plugin_android_lifecycle/CHANGELOG.md | 11 ++--------- .../flutter_plugin_android_lifecycle/pubspec.yaml | 4 ++-- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/packages/flutter_plugin_android_lifecycle/CHANGELOG.md b/packages/flutter_plugin_android_lifecycle/CHANGELOG.md index e1804c5cc7f5..08f137c09434 100644 --- a/packages/flutter_plugin_android_lifecycle/CHANGELOG.md +++ b/packages/flutter_plugin_android_lifecycle/CHANGELOG.md @@ -1,15 +1,8 @@ -## 2.0.0-nullsafety.2 +## 2.0.0 +* Bump Dart SDK for null-safety compatibility. * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) -## 2.0.0-nullsafety.1 - -* Fix example app SDK. - -## 2.0.0-nullsafety - -* Bump Dart SDK. - ## 1.0.12 * Update Flutter SDK constraint. diff --git a/packages/flutter_plugin_android_lifecycle/pubspec.yaml b/packages/flutter_plugin_android_lifecycle/pubspec.yaml index d94237c2101a..3f6ccb089f44 100644 --- a/packages/flutter_plugin_android_lifecycle/pubspec.yaml +++ b/packages/flutter_plugin_android_lifecycle/pubspec.yaml @@ -1,10 +1,10 @@ name: flutter_plugin_android_lifecycle description: Flutter plugin for accessing an Android Lifecycle within other plugins. -version: 2.0.0-nullsafety.2 +version: 2.0.0 homepage: https://github.com/flutter/plugins/tree/master/packages/flutter_plugin_android_lifecycle environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13" dependencies: From 72cbcacfefc20567678264731602875addc0a62b Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 19 Feb 2021 12:59:16 -0800 Subject: [PATCH 0160/1565] [package_info] Bump version for NNBD stable (#3571) Includes: - Migrating the example to NNBD - Bullet-proofing against null values from the native code; at least the ObjC code can theoretically return nulls. --- packages/package_info/CHANGELOG.md | 6 +----- .../integration_test/package_info_test.dart | 2 ++ packages/package_info/example/lib/main.dart | 4 ++-- .../macos/Runner.xcodeproj/project.pbxproj | 21 ++++++------------- packages/package_info/example/pubspec.yaml | 4 ++-- .../example/test_driver/integration_test.dart | 2 ++ packages/package_info/lib/package_info.dart | 8 +++---- packages/package_info/pubspec.yaml | 6 +++--- 8 files changed, 22 insertions(+), 31 deletions(-) diff --git a/packages/package_info/CHANGELOG.md b/packages/package_info/CHANGELOG.md index ddf01f0f3999..14a9e26639d9 100644 --- a/packages/package_info/CHANGELOG.md +++ b/packages/package_info/CHANGELOG.md @@ -1,8 +1,4 @@ -## 2.0.0-nullsafety - -* Update version to (semi-belatedly) meet 1.0-consistency promise. - -## 0.5.0-nullsafety +## 2.0.0 * Migrate to null safety. diff --git a/packages/package_info/example/integration_test/package_info_test.dart b/packages/package_info/example/integration_test/package_info_test.dart index 5038509ec84f..e70c8a5f0eca 100644 --- a/packages/package_info/example/integration_test/package_info_test.dart +++ b/packages/package_info/example/integration_test/package_info_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:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; diff --git a/packages/package_info/example/lib/main.dart b/packages/package_info/example/lib/main.dart index 91ed910ef21d..18620617d558 100644 --- a/packages/package_info/example/lib/main.dart +++ b/packages/package_info/example/lib/main.dart @@ -25,7 +25,7 @@ class MyApp extends StatelessWidget { } class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); + MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @@ -57,7 +57,7 @@ class _MyHomePageState extends State { Widget _infoTile(String title, String subtitle) { return ListTile( title: Text(title), - subtitle: Text(subtitle ?? 'Not set'), + subtitle: Text(subtitle.isNotEmpty ? subtitle : 'Not set'), ); } diff --git a/packages/package_info/example/macos/Runner.xcodeproj/project.pbxproj b/packages/package_info/example/macos/Runner.xcodeproj/project.pbxproj index 6e63b7eb69ae..3525d85d6678 100644 --- a/packages/package_info/example/macos/Runner.xcodeproj/project.pbxproj +++ b/packages/package_info/example/macos/Runner.xcodeproj/project.pbxproj @@ -26,11 +26,7 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; - 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; }; - 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9A0CC0B8F23AFE5DF719BADB /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CED91D820ABAEDEBEFEBDBDA /* Pods_Runner.framework */; }; - D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; }; - D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -50,8 +46,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */, - 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */, ); name = "Bundle Framework"; runOnlyForDeploymentPostprocessing = 0; @@ -72,7 +66,6 @@ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; - 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; }; 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; @@ -80,7 +73,6 @@ 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; B3868D4F5169B9990BB5D1F5 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; CED91D820ABAEDEBEFEBDBDA /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -88,8 +80,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D73912F022F37F9E000D13A0 /* App.framework in Frameworks */, - 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */, 9A0CC0B8F23AFE5DF719BADB /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -145,8 +135,6 @@ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, - D73912EF22F37F9E000D13A0 /* App.framework */, - 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */, ); path = Flutter; sourceTree = ""; @@ -280,7 +268,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n"; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; }; 33CC111E2044C6BF0003C045 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; @@ -329,10 +317,13 @@ buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/package_info/package_info.framework", ); name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; diff --git a/packages/package_info/example/pubspec.yaml b/packages/package_info/example/pubspec.yaml index 0d0e1bae3c1f..a4691fcba518 100644 --- a/packages/package_info/example/pubspec.yaml +++ b/packages/package_info/example/pubspec.yaml @@ -17,11 +17,11 @@ dependencies: dev_dependencies: flutter_driver: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/package_info/example/test_driver/integration_test.dart b/packages/package_info/example/test_driver/integration_test.dart index f532c389a02b..437b3609d119 100644 --- a/packages/package_info/example/test_driver/integration_test.dart +++ b/packages/package_info/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:convert'; import 'dart:io'; diff --git a/packages/package_info/lib/package_info.dart b/packages/package_info/lib/package_info.dart index 51348978ffa5..5b7f4e573aa0 100644 --- a/packages/package_info/lib/package_info.dart +++ b/packages/package_info/lib/package_info.dart @@ -42,10 +42,10 @@ class PackageInfo { (await _kChannel.invokeMapMethod('getAll'))!; packageInfo = PackageInfo( - appName: map["appName"], - packageName: map["packageName"], - version: map["version"], - buildNumber: map["buildNumber"], + appName: map["appName"] ?? '', + packageName: map["packageName"] ?? '', + version: map["version"] ?? '', + buildNumber: map["buildNumber"] ?? '', ); _fromPlatform = packageInfo; return packageInfo; diff --git a/packages/package_info/pubspec.yaml b/packages/package_info/pubspec.yaml index 67fbc5f626db..2769af1f83d5 100644 --- a/packages/package_info/pubspec.yaml +++ b/packages/package_info/pubspec.yaml @@ -2,7 +2,7 @@ name: package_info description: Flutter plugin for querying information about the application package, such as CFBundleVersion on iOS or versionCode on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/package_info -version: 2.0.0-nullsafety +version: 2.0.0 flutter: plugin: @@ -26,8 +26,8 @@ dev_dependencies: sdk: flutter integration_test: path: ../integration_test - pedantic: ^1.10.0-nullsafety + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" From 4f31f3fa66425ba10e9489016384218a6337f755 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Fri, 19 Feb 2021 14:20:24 -0800 Subject: [PATCH 0161/1565] [image_picker_platform_interface] Bump NNBD version to stable (#3573) --- .../image_picker_platform_interface/CHANGELOG.md | 2 +- .../image_picker_platform_interface/pubspec.yaml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/image_picker/image_picker_platform_interface/CHANGELOG.md b/packages/image_picker/image_picker_platform_interface/CHANGELOG.md index fc953e4e6333..f2e017e190c5 100644 --- a/packages/image_picker/image_picker_platform_interface/CHANGELOG.md +++ b/packages/image_picker/image_picker_platform_interface/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.0.0-nullsafety +## 2.0.0 * Migrate to null safety. * Breaking Changes: diff --git a/packages/image_picker/image_picker_platform_interface/pubspec.yaml b/packages/image_picker/image_picker_platform_interface/pubspec.yaml index d5f5ce93016b..9befba90215a 100644 --- a/packages/image_picker/image_picker_platform_interface/pubspec.yaml +++ b/packages/image_picker/image_picker_platform_interface/pubspec.yaml @@ -3,20 +3,20 @@ description: A common platform interface for the image_picker plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0-nullsafety +version: 2.0.0 dependencies: flutter: sdk: flutter - meta: ^1.3.0-nullsafety.6 - http: ^0.13.0-nullsafety.0 - plugin_platform_interface: ^1.1.0-nullsafety.2 + meta: ^1.3.0 + http: ^0.13.0 + plugin_platform_interface: ">=1.0.0 <3.0.0" dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.10.0-nullsafety.3 + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.10.0" From 5817241b8b8023ccc8d6e841a8b1cd777cb170be Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 19 Feb 2021 14:45:39 -0800 Subject: [PATCH 0162/1565] [flutter_plugin_android_lifecycle-sdk] Update Flutter SDK constraint --- packages/flutter_plugin_android_lifecycle/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/flutter_plugin_android_lifecycle/pubspec.yaml b/packages/flutter_plugin_android_lifecycle/pubspec.yaml index 3f6ccb089f44..fc2805ef814b 100644 --- a/packages/flutter_plugin_android_lifecycle/pubspec.yaml +++ b/packages/flutter_plugin_android_lifecycle/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/flutter_plugin environment: sdk: ">=2.12.0-259.9.beta <3.0.0" - flutter: ">=1.12.13" + flutter: ">=1.20.0" dependencies: flutter: From 8e389350225301fdfe51d1a13678fbef17415e11 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 19 Feb 2021 14:47:48 -0800 Subject: [PATCH 0163/1565] [path_provider] Bump platform packages to NNBD stable (#3575) Makes all platform packages stable null-safe releases. --- .../path_provider_linux/CHANGELOG.md | 6 +----- .../path_provider_linux/example/pubspec.yaml | 4 ++-- .../path_provider_linux/pubspec.yaml | 14 +++++++------- .../path_provider_macos/CHANGELOG.md | 8 ++------ .../path_provider_macos/example/pubspec.yaml | 6 +++--- .../path_provider_macos/pubspec.yaml | 8 ++++---- .../pubspec.yaml | 2 +- .../path_provider_windows/CHANGELOG.md | 19 +------------------ .../example/pubspec.yaml | 6 +++--- .../path_provider_windows/pubspec.yaml | 16 ++++++++-------- 10 files changed, 32 insertions(+), 57 deletions(-) diff --git a/packages/path_provider/path_provider_linux/CHANGELOG.md b/packages/path_provider/path_provider_linux/CHANGELOG.md index 126aadcffeb4..a85c6bbb4ef3 100644 --- a/packages/path_provider/path_provider_linux/CHANGELOG.md +++ b/packages/path_provider/path_provider_linux/CHANGELOG.md @@ -1,8 +1,4 @@ -## 2.0.0-nullsafety - -* Update version to (semi-belatedly) meet 1.0-consistency promise. - -## 0.2.0-nullsafety +## 2.0.0 * Migrate to null safety. diff --git a/packages/path_provider/path_provider_linux/example/pubspec.yaml b/packages/path_provider/path_provider_linux/example/pubspec.yaml index 1fd55712ee44..cb778ef6ac57 100644 --- a/packages/path_provider/path_provider_linux/example/pubspec.yaml +++ b/packages/path_provider/path_provider_linux/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the path_provider_linux plugin. publish_to: "none" environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.10.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" dependencies: flutter: diff --git a/packages/path_provider/path_provider_linux/pubspec.yaml b/packages/path_provider/path_provider_linux/pubspec.yaml index c6940b1158ee..a3cdff34b6cc 100644 --- a/packages/path_provider/path_provider_linux/pubspec.yaml +++ b/packages/path_provider/path_provider_linux/pubspec.yaml @@ -1,6 +1,6 @@ name: path_provider_linux description: linux implementation of the path_provider plugin -version: 2.0.0-nullsafety +version: 2.0.0 homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_linux flutter: @@ -11,17 +11,17 @@ flutter: pluginClass: none environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.10.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" dependencies: - path: ^1.8.0-nullsafety.3 - xdg_directories: ^0.2.0-nullsafety.1 - path_provider_platform_interface: ^2.0.0-nullsafety + path: ^1.8.0 + xdg_directories: ^0.2.0 + path_provider_platform_interface: ^2.0.0 flutter: sdk: flutter dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.10.0-nullsafety.3 + pedantic: ^1.10.0 diff --git a/packages/path_provider/path_provider_macos/CHANGELOG.md b/packages/path_provider/path_provider_macos/CHANGELOG.md index de7ab3e94f9d..f989efbe2a98 100644 --- a/packages/path_provider/path_provider_macos/CHANGELOG.md +++ b/packages/path_provider/path_provider_macos/CHANGELOG.md @@ -1,10 +1,6 @@ -## 2.0.0-nullsafety +## 2.0.0 -* Update version to (semi-belatedly) meet 1.0-consistency promise. - -## 0.0.5-nullsafety - -* Update Dart SDK constraint for null safety. +* Update Dart SDK constraint for null safety compatibility. ## 0.0.4+9 diff --git a/packages/path_provider/path_provider_macos/example/pubspec.yaml b/packages/path_provider/path_provider_macos/example/pubspec.yaml index 495459319ca4..db7fd9a0dea6 100644 --- a/packages/path_provider/path_provider_macos/example/pubspec.yaml +++ b/packages/path_provider/path_provider_macos/example/pubspec.yaml @@ -11,7 +11,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - path_provider_platform_interface: 2.0.0-nullsafety + path_provider_platform_interface: ^2.0.0 dev_dependencies: integration_test: @@ -24,5 +24,5 @@ flutter: uses-material-design: true environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.10.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" diff --git a/packages/path_provider/path_provider_macos/pubspec.yaml b/packages/path_provider/path_provider_macos/pubspec.yaml index bab79c27a94c..14f0b9556a6a 100644 --- a/packages/path_provider/path_provider_macos/pubspec.yaml +++ b/packages/path_provider/path_provider_macos/pubspec.yaml @@ -1,6 +1,6 @@ name: path_provider_macos description: macOS implementation of the path_provider plugin -version: 2.0.0-nullsafety +version: 2.0.0 homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_macos flutter: @@ -10,12 +10,12 @@ flutter: pluginClass: PathProviderPlugin environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.10.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" dependencies: flutter: sdk: flutter dev_dependencies: - pedantic: ^1.8.0 + pedantic: ^1.10.0 diff --git a/packages/path_provider/path_provider_platform_interface/pubspec.yaml b/packages/path_provider/path_provider_platform_interface/pubspec.yaml index 68b790301270..3feb4e0a8ebd 100644 --- a/packages/path_provider/path_provider_platform_interface/pubspec.yaml +++ b/packages/path_provider/path_provider_platform_interface/pubspec.yaml @@ -19,4 +19,4 @@ dev_dependencies: environment: sdk: ">=2.12.0-259.9.beta <3.0.0" - flutter: ">=1.10.0" + flutter: ">=1.20.0" diff --git a/packages/path_provider/path_provider_windows/CHANGELOG.md b/packages/path_provider/path_provider_windows/CHANGELOG.md index 2e1701cc53bf..ca4621471891 100644 --- a/packages/path_provider/path_provider_windows/CHANGELOG.md +++ b/packages/path_provider/path_provider_windows/CHANGELOG.md @@ -1,21 +1,4 @@ -## 2.0.0-nullsafety - -* Update version to (semi-belatedly) meet 1.0-consistency promise. - -## 0.1.0-nullsafety.3 - -* Bump ffi dependency to 1.0.0 -* Bump win32 dependency to 2.0.0-nullsafety.12 - -## 0.1.0-nullsafety.2 - -* Bump ffi dependency to 0.3.0-nullsafety.1 - -## 0.1.0-nullsafety.1 - -* Bump win32 dependency to latest version. - -## 0.1.0-nullsafety +## 2.0.0 * Migrate to null safety diff --git a/packages/path_provider/path_provider_windows/example/pubspec.yaml b/packages/path_provider/path_provider_windows/example/pubspec.yaml index 5704502528f7..8c1f88b89cb0 100644 --- a/packages/path_provider/path_provider_windows/example/pubspec.yaml +++ b/packages/path_provider/path_provider_windows/example/pubspec.yaml @@ -17,11 +17,11 @@ dev_dependencies: path: ../../../integration_test flutter_driver: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.12.13+hotfix.4" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" diff --git a/packages/path_provider/path_provider_windows/pubspec.yaml b/packages/path_provider/path_provider_windows/pubspec.yaml index eb7d1087d5f5..d152869f197d 100644 --- a/packages/path_provider/path_provider_windows/pubspec.yaml +++ b/packages/path_provider/path_provider_windows/pubspec.yaml @@ -1,7 +1,7 @@ name: path_provider_windows description: Windows implementation of the path_provider plugin homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_windows -version: 2.0.0-nullsafety +version: 2.0.0 flutter: plugin: @@ -11,19 +11,19 @@ flutter: pluginClass: none dependencies: - path_provider_platform_interface: ^2.0.0-nullsafety - meta: ^1.3.0-nullsafety.6 - path: ^1.8.0-nullsafety.3 + path_provider_platform_interface: ^2.0.0 + meta: ^1.3.0 + path: ^1.8.0 flutter: sdk: flutter ffi: ^1.0.0 - win32: ^2.0.0-nullsafety.12 + win32: ^2.0.0 dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.10.0-nullsafety.3 + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.12.13+hotfix.4" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" From f6c2ed4f3c5aa0c4b3ede148c51e2760bd376dea Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Fri, 19 Feb 2021 15:57:25 -0800 Subject: [PATCH 0164/1565] [image_picker] use nnbd version of deps to resolve ci failure (#3580) --- packages/image_picker/image_picker/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index 75f9dca4e0ca..eab7f7c20974 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -26,8 +26,8 @@ dev_dependencies: integration_test: path: ../../integration_test mockito: ^5.0.0-nullsafety.7 - pedantic: ^1.8.0 - plugin_platform_interface: ^1.0.3 + pedantic: ^1.10.0 + plugin_platform_interface: ">=1.0.0 <3.0.0" environment: sdk: ">=2.12.0-0 <3.0.0" From 127c772287608e46a034f43a1e373171bb750fa6 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Fri, 19 Feb 2021 17:46:03 -0800 Subject: [PATCH 0165/1565] [image_picker] NNBD stable (#3579) --- packages/image_picker/image_picker/CHANGELOG.md | 3 ++- packages/image_picker/image_picker/example/pubspec.yaml | 4 ++-- packages/image_picker/image_picker/pubspec.yaml | 9 ++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md index c6b29f277ec3..97aba4536000 100644 --- a/packages/image_picker/image_picker/CHANGELOG.md +++ b/packages/image_picker/image_picker/CHANGELOG.md @@ -1,4 +1,5 @@ -## 0.7.0-nullsafety +## 0.7.0 + * Migrate to nullsafety * Breaking Changes: * Removed the deprecated methods: `ImagePicker.pickImage`, `ImagePicker.pickVideo`, diff --git a/packages/image_picker/image_picker/example/pubspec.yaml b/packages/image_picker/image_picker/example/pubspec.yaml index eed223c1ade7..ceafc317fa82 100755 --- a/packages/image_picker/image_picker/example/pubspec.yaml +++ b/packages/image_picker/image_picker/example/pubspec.yaml @@ -6,7 +6,7 @@ dependencies: video_player: ^2.0.0-nullsafety.7 flutter: sdk: flutter - flutter_plugin_android_lifecycle: ^2.0.0-nullsafety.2 + flutter_plugin_android_lifecycle: ^2.0.0 image_picker: # When depending on this package from a real application you should use: # image_picker: ^x.y.z @@ -26,5 +26,5 @@ flutter: uses-material-design: true environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.10.0" diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index eab7f7c20974..96881e6f2c65 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker description: Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker -version: 0.7.0-nullsafety +version: 0.7.0 flutter: plugin: @@ -16,11 +16,10 @@ flutter: dependencies: flutter: sdk: flutter - flutter_plugin_android_lifecycle: ^2.0.0-nullsafety.2 - image_picker_platform_interface: ^2.0.0-nullsafety + flutter_plugin_android_lifecycle: ^2.0.0 + image_picker_platform_interface: ^2.0.0 dev_dependencies: - video_player: ^2.0.0-nullsafety.7 flutter_test: sdk: flutter integration_test: @@ -30,5 +29,5 @@ dev_dependencies: plugin_platform_interface: ">=1.0.0 <3.0.0" environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.10.0" From f69e7ddce405462b462b482a2f1ad1e2b94c2ee2 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 19 Feb 2021 20:30:51 -0800 Subject: [PATCH 0166/1565] [url_launcher] Fix SDK copypasta (#3583) The lower end of the SDK range was wrong due to a bad copy/paste. --- .../url_launcher/url_launcher_platform_interface/CHANGELOG.md | 4 ++++ .../url_launcher/url_launcher_platform_interface/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md b/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md index 5cd56432ece4..d617e514035e 100644 --- a/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +* Fix SDK range. + ## 2.0.0 * Migrate to null safety. diff --git a/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml b/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml index a8761c3594ea..d3ec0aafd126 100644 --- a/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml +++ b/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the url_launcher plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0 +version: 2.0.1 dependencies: flutter: @@ -17,5 +17,5 @@ dev_dependencies: pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-2.12.0-259.9.beta <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.22.0" From 29c9d1cb48206abba87a30a978271143acb4a15a Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Sat, 20 Feb 2021 11:45:26 +0100 Subject: [PATCH 0167/1565] [camera] Solves delay when using the zoom feature on iOS. (#3562) --- packages/camera/camera/CHANGELOG.md | 4 ++++ packages/camera/camera/ios/Classes/CameraPlugin.m | 2 +- packages/camera/camera/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 7391f3090565..29774748a32b 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.8.0-nullsafety.2 + +* Solved delay when using the zoom feature on iOS. + ## 0.8.0-nullsafety.1 * Added a timeout to the pre-capture sequence on Android to prevent crashes when the camera cannot get a focus. diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index d97ce88a58d8..c1770ff6d40b 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -1068,7 +1068,7 @@ - (void)setZoomLevel:(CGFloat)zoom Result:(FlutterResult)result { result(getFlutterError(error)); return; } - [_captureDevice rampToVideoZoomFactor:zoom withRate:1]; + _captureDevice.videoZoomFactor = zoom; [_captureDevice unlockForConfiguration]; result(nil); diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 5b98c39acd99..4b820b8b64cf 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.8.0-nullsafety.1 +version: 0.8.0-nullsafety.2 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From 0e3e17728a5c313e0a068f70bfa612b9bd6ba94d Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Sat, 20 Feb 2021 10:01:03 -0800 Subject: [PATCH 0168/1565] migrate connectivity platform interface to stable (#3585) --- .../connectivity_platform_interface/CHANGELOG.md | 6 +----- .../connectivity_platform_interface/pubspec.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/connectivity/connectivity_platform_interface/CHANGELOG.md b/packages/connectivity/connectivity_platform_interface/CHANGELOG.md index 8e38341be42f..0b26cd52c9e9 100644 --- a/packages/connectivity/connectivity_platform_interface/CHANGELOG.md +++ b/packages/connectivity/connectivity_platform_interface/CHANGELOG.md @@ -1,8 +1,4 @@ -## 2.0.0-nullsafety.1 - -* Bump Dart SDK to support null safety. - -## 2.0.0-nullsafety +## 2.0.0 * Migrate to null safety. diff --git a/packages/connectivity/connectivity_platform_interface/pubspec.yaml b/packages/connectivity/connectivity_platform_interface/pubspec.yaml index 114915a10b60..1e89972dd816 100644 --- a/packages/connectivity/connectivity_platform_interface/pubspec.yaml +++ b/packages/connectivity/connectivity_platform_interface/pubspec.yaml @@ -3,19 +3,19 @@ description: A common platform interface for the connectivity plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0-nullsafety.1 +version: 2.0.0 dependencies: flutter: sdk: flutter - meta: ^1.3.0-nullsafety.3 - plugin_platform_interface: ^1.1.0-nullsafety.1 + meta: ^1.3.0 + plugin_platform_interface: ">=1.0.0 <3.0.0" dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.10.0-nullsafety.1 + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" From a8d1a3a98509b7f79c54f0f618d55280fbfe8bf1 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Sat, 20 Feb 2021 10:26:39 -0800 Subject: [PATCH 0169/1565] [shared_preferences] Bump version for NNBD stable (#3586) --- .../shared_preferences_platform_interface/CHANGELOG.md | 2 +- .../shared_preferences_platform_interface/pubspec.yaml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md b/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md index 6661e2757326..b402f6e57e88 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.0.0-nullsafety +## 2.0.0 * Migrate to null safety. diff --git a/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml b/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml index 9e5d57230761..85c64a030036 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml @@ -1,7 +1,7 @@ name: shared_preferences_platform_interface description: A common platform interface for the shared_preferences plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_platform_interface -version: 2.0.0-nullsafety +version: 2.0.0 dependencies: flutter: @@ -10,8 +10,8 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.10.0-nullsafety + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.8" From 90c0e90694a9567d65334286cda09713de6ef3b4 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Sat, 20 Feb 2021 11:34:30 -0800 Subject: [PATCH 0170/1565] [battery] Bump platform version to NNBD stable (#3587) --- .../battery/battery_platform_interface/CHANGELOG.md | 2 +- .../battery/battery_platform_interface/pubspec.yaml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/battery/battery_platform_interface/CHANGELOG.md b/packages/battery/battery_platform_interface/CHANGELOG.md index 6fc7228a89f9..2c51f2c2d352 100644 --- a/packages/battery/battery_platform_interface/CHANGELOG.md +++ b/packages/battery/battery_platform_interface/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.0.0-nullsafety +## 2.0.0 * Migrate to null safety. diff --git a/packages/battery/battery_platform_interface/pubspec.yaml b/packages/battery/battery_platform_interface/pubspec.yaml index c7c4f5e8395e..61edad6cc04b 100644 --- a/packages/battery/battery_platform_interface/pubspec.yaml +++ b/packages/battery/battery_platform_interface/pubspec.yaml @@ -3,20 +3,20 @@ description: A common platform interface for the battery plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/battery # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0-nullsafety +version: 2.0.0 dependencies: flutter: sdk: flutter - meta: ^1.3.0-nullsafety - plugin_platform_interface: ^1.1.0-nullsafety.1 + meta: ^1.3.0 + plugin_platform_interface: ">=1.0.0 <3.0.0" dev_dependencies: flutter_test: sdk: flutter mockito: ^5.0.0-nullsafety.0 - pedantic: ^1.10.0-nullsafety + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.9.1+hotfix.4" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" From 9d00dd22b868f4ed98de8170f25e2a508a44b93a Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Sat, 20 Feb 2021 12:25:40 -0800 Subject: [PATCH 0171/1565] [sensors] Update to NNBD stable (#3589) Includes migrating example to null-safety. --- packages/sensors/CHANGELOG.md | 6 +--- packages/sensors/example/lib/main.dart | 20 ++++++------- packages/sensors/example/lib/snake.dart | 29 +++++++++---------- packages/sensors/example/pubspec.yaml | 7 ++--- .../test_driver/test/integration_test.dart | 2 ++ packages/sensors/pubspec.yaml | 8 ++--- 6 files changed, 34 insertions(+), 38 deletions(-) diff --git a/packages/sensors/CHANGELOG.md b/packages/sensors/CHANGELOG.md index 8ff904bf3943..295c32ad2127 100644 --- a/packages/sensors/CHANGELOG.md +++ b/packages/sensors/CHANGELOG.md @@ -1,8 +1,4 @@ -## 2.0.0-nullsafety - -* * Update version to (semi-belatedly) meet 1.0-consistency promise. - -## 0.5.0-nullsafety +## 2.0.0 * Migrate to null safety. diff --git a/packages/sensors/example/lib/main.dart b/packages/sensors/example/lib/main.dart index 575e0493742f..d6f01380c534 100644 --- a/packages/sensors/example/lib/main.dart +++ b/packages/sensors/example/lib/main.dart @@ -28,7 +28,7 @@ class MyApp extends StatelessWidget { } class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); + MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @@ -41,21 +41,21 @@ class _MyHomePageState extends State { static const int _snakeColumns = 20; static const double _snakeCellSize = 10.0; - List _accelerometerValues; - List _userAccelerometerValues; - List _gyroscopeValues; + List? _accelerometerValues; + List? _userAccelerometerValues; + List? _gyroscopeValues; List> _streamSubscriptions = >[]; @override Widget build(BuildContext context) { - final List accelerometer = - _accelerometerValues?.map((double v) => v.toStringAsFixed(1))?.toList(); - final List gyroscope = - _gyroscopeValues?.map((double v) => v.toStringAsFixed(1))?.toList(); - final List userAccelerometer = _userAccelerometerValues + final List? accelerometer = + _accelerometerValues?.map((double v) => v.toStringAsFixed(1)).toList(); + final List? gyroscope = + _gyroscopeValues?.map((double v) => v.toStringAsFixed(1)).toList(); + final List? userAccelerometer = _userAccelerometerValues ?.map((double v) => v.toStringAsFixed(1)) - ?.toList(); + .toList(); return Scaffold( appBar: AppBar( diff --git a/packages/sensors/example/lib/snake.dart b/packages/sensors/example/lib/snake.dart index d6b2f9b48a23..72f27472dd5b 100644 --- a/packages/sensors/example/lib/snake.dart +++ b/packages/sensors/example/lib/snake.dart @@ -56,15 +56,14 @@ class SnakeBoardPainter extends CustomPainter { } class SnakeState extends State { - SnakeState(int rows, int columns, this.cellSize) { - state = GameState(rows, columns); - } + SnakeState(int rows, int columns, this.cellSize) + : state = GameState(rows, columns); double cellSize; GameState state; - AccelerometerEvent acceleration; - StreamSubscription _streamSubscription; - Timer _timer; + AccelerometerEvent? acceleration; + late StreamSubscription _streamSubscription; + late Timer _timer; @override Widget build(BuildContext context) { @@ -96,21 +95,21 @@ class SnakeState extends State { } void _step() { - final math.Point newDirection = acceleration == null + final AccelerometerEvent? currentAcceleration = acceleration; + final math.Point? newDirection = currentAcceleration == null ? null - : acceleration.x.abs() < 1.0 && acceleration.y.abs() < 1.0 + : currentAcceleration.x.abs() < 1.0 && currentAcceleration.y.abs() < 1.0 ? null - : (acceleration.x.abs() < acceleration.y.abs()) - ? math.Point(0, acceleration.y.sign.toInt()) - : math.Point(-acceleration.x.sign.toInt(), 0); + : (currentAcceleration.x.abs() < currentAcceleration.y.abs()) + ? math.Point(0, currentAcceleration.y.sign.toInt()) + : math.Point(-currentAcceleration.x.sign.toInt(), 0); state.step(newDirection); } } class GameState { - GameState(this.rows, this.columns) { - snakeLength = math.min(rows, columns) - 5; - } + GameState(this.rows, this.columns) + : snakeLength = math.min(rows, columns) - 5; int rows; int columns; @@ -119,7 +118,7 @@ class GameState { List> body = >[const math.Point(0, 0)]; math.Point direction = const math.Point(1, 0); - void step(math.Point newDirection) { + void step(math.Point? newDirection) { math.Point next = body.last + direction; next = math.Point(next.x % columns, next.y % rows); diff --git a/packages/sensors/example/pubspec.yaml b/packages/sensors/example/pubspec.yaml index d4702ac3aabe..0cd30b12df2b 100644 --- a/packages/sensors/example/pubspec.yaml +++ b/packages/sensors/example/pubspec.yaml @@ -17,12 +17,11 @@ dev_dependencies: sdk: flutter integration_test: path: ../../integration_test - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.0.0-dev.28.0 <3.0.0" - flutter: ">=1.9.1+hotfix.2" - + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" diff --git a/packages/sensors/example/test_driver/test/integration_test.dart b/packages/sensors/example/test_driver/test/integration_test.dart index 7a2c21338786..a8a56aa90f6a 100644 --- a/packages/sensors/example/test_driver/test/integration_test.dart +++ b/packages/sensors/example/test_driver/test/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/sensors/pubspec.yaml b/packages/sensors/pubspec.yaml index 0416779f1292..da45c82b7dd7 100644 --- a/packages/sensors/pubspec.yaml +++ b/packages/sensors/pubspec.yaml @@ -2,7 +2,7 @@ name: sensors description: Flutter plugin for accessing the Android and iOS accelerometer and gyroscope sensors. homepage: https://github.com/flutter/plugins/tree/master/packages/sensors -version: 2.0.0-nullsafety +version: 2.0.0 flutter: plugin: @@ -18,14 +18,14 @@ dependencies: sdk: flutter dev_dependencies: - test: ^1.16.0-nullsafety + test: ^1.16.0 flutter_test: sdk: flutter integration_test: path: ../integration_test mockito: ^5.0.0-nullsafety.0 - pedantic: ^1.10.0-nullsafety + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" From e8c8cf679e1039596b4b9d1bc4f6b8308dd0a47f Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 22 Feb 2021 10:44:33 -0800 Subject: [PATCH 0172/1565] [connectivity_macos] move NNBD to stable (#3588) --- .../connectivity/connectivity_macos/CHANGELOG.md | 11 ++--------- .../connectivity_macos/example/lib/main.dart | 14 +++++++------- .../connectivity_macos/example/pubspec.yaml | 6 +++--- .../integration_test/connectivity_test.dart | 7 ++++--- .../connectivity/connectivity_macos/pubspec.yaml | 6 +++--- 5 files changed, 19 insertions(+), 25 deletions(-) diff --git a/packages/connectivity/connectivity_macos/CHANGELOG.md b/packages/connectivity/connectivity_macos/CHANGELOG.md index 8547db3441c3..b3ad35a03281 100644 --- a/packages/connectivity/connectivity_macos/CHANGELOG.md +++ b/packages/connectivity/connectivity_macos/CHANGELOG.md @@ -1,14 +1,7 @@ -## 2.0.0-nullsafety - -* Update version to (semi-belatedly) meet 1.0-consistency promise. - -## 0.2.0-nullsafety.1 +## 2.0.0 * Remove placeholder Dart file. - -## 0.2.0-nullsafety - -* Update Dart SDK constraint. +* Update Dart SDK constraint for compatibility with null safety. ## 0.1.0+8 diff --git a/packages/connectivity/connectivity_macos/example/lib/main.dart b/packages/connectivity/connectivity_macos/example/lib/main.dart index 4ad30972679a..07746ed0f722 100644 --- a/packages/connectivity/connectivity_macos/example/lib/main.dart +++ b/packages/connectivity/connectivity_macos/example/lib/main.dart @@ -7,7 +7,7 @@ import 'dart:async'; import 'dart:io'; -import 'package:connectivity/connectivity.dart'; +import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -40,9 +40,9 @@ class MyApp extends StatelessWidget { } class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); + MyHomePage({Key? key, this.title}) : super(key: key); - final String title; + final String? title; @override _MyHomePageState createState() => _MyHomePageState(); @@ -50,8 +50,8 @@ class MyHomePage extends StatefulWidget { class _MyHomePageState extends State { String _connectionStatus = 'Unknown'; - final Connectivity _connectivity = Connectivity(); - StreamSubscription _connectivitySubscription; + final ConnectivityPlatform _connectivity = ConnectivityPlatform.instance; + late StreamSubscription _connectivitySubscription; @override void initState() { @@ -69,7 +69,7 @@ class _MyHomePageState extends State { // Platform messages are asynchronous, so we initialize in an async method. Future initConnectivity() async { - ConnectivityResult result; + late ConnectivityResult result; // Platform messages may fail, so we use a try/catch PlatformException. try { result = await _connectivity.checkConnectivity(); @@ -100,7 +100,7 @@ class _MyHomePageState extends State { Future _updateConnectionStatus(ConnectivityResult result) async { switch (result) { case ConnectivityResult.wifi: - String wifiName, wifiBSSID, wifiIP; + String? wifiName, wifiBSSID, wifiIP; try { if (Platform.isIOS) { diff --git a/packages/connectivity/connectivity_macos/example/pubspec.yaml b/packages/connectivity/connectivity_macos/example/pubspec.yaml index 49d24e76b717..61cf16854d8b 100644 --- a/packages/connectivity/connectivity_macos/example/pubspec.yaml +++ b/packages/connectivity/connectivity_macos/example/pubspec.yaml @@ -4,7 +4,7 @@ description: Demonstrates how to use the connectivity plugin. dependencies: flutter: sdk: flutter - connectivity: any + connectivity_platform_interface: ^2.0.0 connectivity_macos: # When depending on this package from a real application you should use: # connectivity_macos: ^x.y.z @@ -18,11 +18,11 @@ dev_dependencies: sdk: flutter integration_test: path: ../../../integration_test - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.10.0" diff --git a/packages/connectivity/connectivity_macos/example/test_driver/integration_test/connectivity_test.dart b/packages/connectivity/connectivity_macos/example/test_driver/integration_test/connectivity_test.dart index 54a67337285a..3abe491d193b 100644 --- a/packages/connectivity/connectivity_macos/example/test_driver/integration_test/connectivity_test.dart +++ b/packages/connectivity/connectivity_macos/example/test_driver/integration_test/connectivity_test.dart @@ -2,19 +2,20 @@ // 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 'package:integration_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:connectivity/connectivity.dart'; +import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('Connectivity test driver', () { - Connectivity _connectivity; + ConnectivityPlatform _connectivity; setUpAll(() async { - _connectivity = Connectivity(); + _connectivity = ConnectivityPlatform.instance; }); testWidgets('test connectivity result', (WidgetTester tester) async { diff --git a/packages/connectivity/connectivity_macos/pubspec.yaml b/packages/connectivity/connectivity_macos/pubspec.yaml index 0a22a8ba5f53..781bee88b55a 100644 --- a/packages/connectivity/connectivity_macos/pubspec.yaml +++ b/packages/connectivity/connectivity_macos/pubspec.yaml @@ -1,6 +1,6 @@ name: connectivity_macos description: macOS implementation of the connectivity plugin. -version: 2.0.0-nullsafety +version: 2.0.0 homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_macos flutter: @@ -10,7 +10,7 @@ flutter: pluginClass: ConnectivityPlugin environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.10.0" dependencies: @@ -18,4 +18,4 @@ dependencies: sdk: flutter dev_dependencies: - pedantic: ^1.8.0 + pedantic: ^1.10.0 From d3ab0718dcc8ba0e2cfdd3dfa5a1e7ce2e9179da Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Mon, 22 Feb 2021 19:48:31 +0100 Subject: [PATCH 0173/1565] [cross_file] Stable null safety release (#3593) --- packages/cross_file/CHANGELOG.md | 2 +- packages/cross_file/pubspec.yaml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/cross_file/CHANGELOG.md b/packages/cross_file/CHANGELOG.md index c9b3d1ab2522..5bbb43f9e882 100644 --- a/packages/cross_file/CHANGELOG.md +++ b/packages/cross_file/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.3.0-nullsafety +## 0.3.0 * Migrated package to null-safety. * **breaking change** According to our unit tests, the API should be backwards-compatible. Some relevant changes were made, however: diff --git a/packages/cross_file/pubspec.yaml b/packages/cross_file/pubspec.yaml index af1b7e7d4c0f..8e09b21d4536 100644 --- a/packages/cross_file/pubspec.yaml +++ b/packages/cross_file/pubspec.yaml @@ -1,18 +1,18 @@ name: cross_file description: An abstraction to allow working with files across multiple platforms. homepage: https://github.com/flutter/plugins/tree/master/packages/cross_file -version: 0.3.0-nullsafety +version: 0.3.0 dependencies: flutter: sdk: flutter - meta: ^1.3.0-nullsafety.3 + meta: ^1.3.0 dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.10.0-nullsafety.3 + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.22.0" From 1baec7a192368b1cd271d39993c31531ffa717d1 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Mon, 22 Feb 2021 10:53:04 -0800 Subject: [PATCH 0174/1565] [shared_preferences] Bump platform versions to NNBD stable (#3595) --- .../shared_preferences_linux/CHANGELOG.md | 6 +----- .../example/pubspec.yaml | 6 +++--- .../shared_preferences_linux/pubspec.yaml | 18 ++++++++--------- .../shared_preferences_macos/CHANGELOG.md | 8 ++------ .../example/pubspec.yaml | 6 +++--- .../shared_preferences_macos/pubspec.yaml | 10 +++++----- .../shared_preferences_web/CHANGELOG.md | 6 +----- .../shared_preferences_web/pubspec.yaml | 12 +++++------ .../shared_preferences_windows/CHANGELOG.md | 7 +------ .../example/CHANGELOG.md | 3 --- .../example/pubspec.yaml | 8 ++++---- .../shared_preferences_windows/pubspec.yaml | 20 +++++++++---------- 12 files changed, 45 insertions(+), 65 deletions(-) delete mode 100644 packages/shared_preferences/shared_preferences_windows/example/CHANGELOG.md diff --git a/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md b/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md index 1d287cf57401..a50b4e470c53 100644 --- a/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md @@ -1,8 +1,4 @@ -## 2.0.0-nullsafety - -* Update version for consistency. - -## 0.0.4-nullsafety +## 2.0.0 * Migrate to null-safety. diff --git a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml index 12b78c37ea9c..dffdbd7526d2 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml @@ -17,11 +17,11 @@ dev_dependencies: sdk: flutter integration_test: path: ../../../integration_test - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.12.8" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" diff --git a/packages/shared_preferences/shared_preferences_linux/pubspec.yaml b/packages/shared_preferences/shared_preferences_linux/pubspec.yaml index ee2288a79b4a..0730ca8d5fec 100644 --- a/packages/shared_preferences/shared_preferences_linux/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_linux/pubspec.yaml @@ -1,6 +1,6 @@ name: shared_preferences_linux description: Linux implementation of the shared_preferences plugin -version: 2.0.0-nullsafety +version: 2.0.0 homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_linux flutter: @@ -11,19 +11,19 @@ flutter: pluginClass: none environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.12.8" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" dependencies: flutter: sdk: flutter - file: ^6.0.0-nullsafety.4 - meta: ^1.0.4 - path: ^1.8.0-nullsafety.3 - path_provider_linux: ^0.2.0-nullsafety - shared_preferences_platform_interface: ^2.0.0-nullsafety + file: ^6.0.0 + meta: ^1.3.0 + path: ^1.8.0 + path_provider_linux: ^2.0.0 + shared_preferences_platform_interface: ^2.0.0 dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0 diff --git a/packages/shared_preferences/shared_preferences_macos/CHANGELOG.md b/packages/shared_preferences/shared_preferences_macos/CHANGELOG.md index 002e1b7224ea..00c2f628796f 100644 --- a/packages/shared_preferences/shared_preferences_macos/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_macos/CHANGELOG.md @@ -1,10 +1,6 @@ -## 2.0.0-nullsafety +## 2.0.0 -* Update version to (semi-belatedly) meet 1.0-consistency promise. - -## 0.0.2-nullsafety - -* Update Dart SDK constraint for null safety. +* Migrate to null safety. ## 0.0.1+12 diff --git a/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml index 6a8e7e4b470a..7db361fccfd5 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml @@ -4,7 +4,7 @@ description: Demonstrates how to use the shared_preferences plugin. dependencies: flutter: sdk: flutter - shared_preferences_platform_interface: ^2.0.0-nullsafety + shared_preferences_platform_interface: ^2.0.0 shared_preferences_macos: # When depending on this package from a real application you should use: # shared_preferences_macos: ^x.y.z @@ -18,11 +18,11 @@ dev_dependencies: sdk: flutter integration_test: path: ../../../integration_test - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.8" diff --git a/packages/shared_preferences/shared_preferences_macos/pubspec.yaml b/packages/shared_preferences/shared_preferences_macos/pubspec.yaml index 4f014ecb8929..24811830c1fd 100644 --- a/packages/shared_preferences/shared_preferences_macos/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_macos/pubspec.yaml @@ -1,6 +1,6 @@ name: shared_preferences_macos description: macOS implementation of the shared_preferences plugin. -version: 2.0.0-nullsafety +version: 2.0.0 homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_macos flutter: @@ -10,13 +10,13 @@ flutter: pluginClass: SharedPreferencesPlugin environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.12.8" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" dependencies: - shared_preferences_platform_interface: ^2.0.0-nullsafety + shared_preferences_platform_interface: ^2.0.0 flutter: sdk: flutter dev_dependencies: - pedantic: ^1.8.0 + pedantic: ^1.10.0 diff --git a/packages/shared_preferences/shared_preferences_web/CHANGELOG.md b/packages/shared_preferences/shared_preferences_web/CHANGELOG.md index 2526ffe4447d..ec08267fe59f 100644 --- a/packages/shared_preferences/shared_preferences_web/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_web/CHANGELOG.md @@ -1,8 +1,4 @@ -## 2.0.0-nullsafety - -* Update version to (semi-belatedly) meet 1.0-consistency promise. - -## 0.2.0-nullsafety +## 2.0.0 * Migrate to null-safety. diff --git a/packages/shared_preferences/shared_preferences_web/pubspec.yaml b/packages/shared_preferences/shared_preferences_web/pubspec.yaml index 33970f4d857d..9a14b218572a 100644 --- a/packages/shared_preferences/shared_preferences_web/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_web/pubspec.yaml @@ -1,7 +1,7 @@ name: shared_preferences_web description: Web platform implementation of shared_preferences homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_web -version: 2.0.0-nullsafety +version: 2.0.0 flutter: plugin: @@ -11,18 +11,18 @@ flutter: fileName: shared_preferences_web.dart dependencies: - shared_preferences_platform_interface: ^2.0.0-nullsafety + shared_preferences_platform_interface: ^2.0.0 flutter: sdk: flutter flutter_web_plugins: sdk: flutter - meta: ^1.1.7 + meta: ^1.3.0 dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.12.13+hotfix.4" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" diff --git a/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md b/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md index d6a5fb336fe5..6fa4eb162083 100644 --- a/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md @@ -1,9 +1,4 @@ - -## 2.0.0-nullsafety - -* Update version for consistency. - -## 0.0.3-nullsafety +## 2.0.0 * Migrate to null-safety. diff --git a/packages/shared_preferences/shared_preferences_windows/example/CHANGELOG.md b/packages/shared_preferences/shared_preferences_windows/example/CHANGELOG.md deleted file mode 100644 index 41cc7d8192ec..000000000000 --- a/packages/shared_preferences/shared_preferences_windows/example/CHANGELOG.md +++ /dev/null @@ -1,3 +0,0 @@ -## 0.0.1 - -* TODO: Describe initial release. diff --git a/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml index 575e3f8409c6..6725259c4bdc 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml @@ -2,13 +2,13 @@ name: shared_preferences_windows_example description: Demonstrates how to use the shared_preferences_windows plugin. environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.12.8" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" dependencies: flutter: sdk: flutter - shared_preferences_windows: ^0.0.1 + shared_preferences_windows: ^2.0.0 dependency_overrides: shared_preferences_windows: @@ -24,7 +24,7 @@ dev_dependencies: sdk: flutter integration_test: path: ../../../integration_test - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true diff --git a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml index 0b95c0c0d14a..d804dd1ddb8f 100644 --- a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml @@ -1,7 +1,7 @@ name: shared_preferences_windows description: Windows implementation of shared_preferences homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_windows -version: 2.0.0-nullsafety +version: 2.0.0 flutter: @@ -12,20 +12,20 @@ flutter: pluginClass: none environment: - sdk: '>=2.12.0-0 <3.0.0' - flutter: ">=1.12.8" + sdk: '>=2.12.0-259.9.beta <3.0.0' + flutter: ">=1.20.0" dependencies: - shared_preferences_platform_interface: ^2.0.0-nullsafety + shared_preferences_platform_interface: ^2.0.0 flutter: sdk: flutter - file: ^6.0.0-nullsafety.4 - meta: ^1.1.7 - path: ^1.6.4 - path_provider_platform_interface: ^2.0.0-nullsafety - path_provider_windows: ^0.1.0-nullsafety.2 + file: ^6.0.0 + meta: ^1.3.0 + path: ^1.8.0 + path_provider_platform_interface: ^2.0.0 + path_provider_windows: ^2.0.0 dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.10.0-nullsafety.3 + pedantic: ^1.10.0 From 6c57e87edb3c37fa807e51d952a443aaba1d42fc Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Mon, 22 Feb 2021 10:54:07 -0800 Subject: [PATCH 0175/1565] [url_launcher] Update platforms to NNBD stable (#3584) Updates all versions to stable. Converts all desktop examples to null-safety, and migrates Linux and macOS to use platform interface for examples rather than app-facing package to eliminate circular dependencies (implementation copied directly from Windows). --- .../url_launcher_linux/CHANGELOG.md | 15 +-- .../integration_test/url_launcher_test.dart | 15 +-- .../url_launcher_linux/example/lib/main.dart | 123 ++---------------- .../url_launcher_linux/example/pubspec.yaml | 8 +- .../example/test_driver/integration_test.dart | 2 + .../url_launcher_linux/pubspec.yaml | 7 +- .../url_launcher_macos/CHANGELOG.md | 16 +-- .../integration_test/url_launcher_test.dart | 15 ++- .../url_launcher_macos/example/lib/main.dart | 123 ++---------------- .../url_launcher_macos/example/pubspec.yaml | 8 +- .../example/test_driver/integration_test.dart | 2 + .../url_launcher_macos/pubspec.yaml | 7 +- .../url_launcher_web/CHANGELOG.md | 2 +- .../url_launcher_web/example/pubspec.yaml | 2 +- .../url_launcher_web/pubspec.yaml | 8 +- .../url_launcher_windows/CHANGELOG.md | 16 +-- .../integration_test/url_launcher_test.dart | 2 + .../example/lib/main.dart | 4 +- .../url_launcher_windows/example/pubspec.yaml | 8 +- .../example/test_driver/integration_test.dart | 2 + .../url_launcher_windows/pubspec.yaml | 7 +- 21 files changed, 86 insertions(+), 306 deletions(-) diff --git a/packages/url_launcher/url_launcher_linux/CHANGELOG.md b/packages/url_launcher/url_launcher_linux/CHANGELOG.md index bd3c15cb31fb..ec9fad53437c 100644 --- a/packages/url_launcher/url_launcher_linux/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_linux/CHANGELOG.md @@ -1,18 +1,9 @@ -## 2.0.0-nullsafety - -* Update version for consistency with other implementations. - -## 0.1.0-nullsafety.3 +## 2.0.0 +* Migrate to null safety. * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. - -## 0.1.0-nullsafety.2 - * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) - -## 0.1.0-nullsafety.1 - -* Migrate to null safety. +* Set `implementation` in pubspec.yaml ## 0.0.2+1 diff --git a/packages/url_launcher/url_launcher_linux/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_linux/example/integration_test/url_launcher_test.dart index d11ddb49966b..e1008fddd4e1 100644 --- a/packages/url_launcher/url_launcher_linux/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_linux/example/integration_test/url_launcher_test.dart @@ -2,22 +2,21 @@ // 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:url_launcher/url_launcher.dart'; +import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('canLaunch', (WidgetTester _) async { - expect(await canLaunch('randomstring'), false); - - // Generally all devices should have some default browser. - expect(await canLaunch('http://flutter.dev'), true); + UrlLauncherPlatform launcher = UrlLauncherPlatform.instance; - // Desktop will not necessarily support sms:. + expect(await launcher.canLaunch('randomstring'), false); - // tel: and mailto: links may not be openable on every device. iOS - // simulators notably can't open these link types. + // Generally all devices should have some default browser. + expect(await launcher.canLaunch('http://flutter.dev'), true); }); } diff --git a/packages/url_launcher/url_launcher_linux/example/lib/main.dart b/packages/url_launcher/url_launcher_linux/example/lib/main.dart index a45862012328..f49e9fa290c5 100644 --- a/packages/url_launcher/url_launcher_linux/example/lib/main.dart +++ b/packages/url_launcher/url_launcher_linux/example/lib/main.dart @@ -6,7 +6,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:url_launcher/url_launcher.dart'; +import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; void main() { runApp(MyApp()); @@ -26,7 +26,7 @@ class MyApp extends StatelessWidget { } class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); + MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @override @@ -34,77 +34,24 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { - Future _launched; - String _phone = ''; + Future? _launched; Future _launchInBrowser(String url) async { - if (await canLaunch(url)) { - await launch( + if (await UrlLauncherPlatform.instance.canLaunch(url)) { + await UrlLauncherPlatform.instance.launch( url, - forceSafariVC: false, - forceWebView: false, - headers: {'my_header_key': 'my_header_value'}, + useSafariVC: false, + useWebView: false, + enableJavaScript: false, + enableDomStorage: false, + universalLinksOnly: false, + headers: {}, ); } else { throw 'Could not launch $url'; } } - Future _launchInWebViewOrVC(String url) async { - if (await canLaunch(url)) { - await launch( - url, - forceSafariVC: true, - forceWebView: true, - headers: {'my_header_key': 'my_header_value'}, - ); - } else { - throw 'Could not launch $url'; - } - } - - Future _launchInWebViewWithJavaScript(String url) async { - if (await canLaunch(url)) { - await launch( - url, - forceSafariVC: true, - forceWebView: true, - enableJavaScript: true, - ); - } else { - throw 'Could not launch $url'; - } - } - - Future _launchInWebViewWithDomStorage(String url) async { - if (await canLaunch(url)) { - await launch( - url, - forceSafariVC: true, - forceWebView: true, - enableDomStorage: true, - ); - } else { - throw 'Could not launch $url'; - } - } - - Future _launchUniversalLinkIos(String url) async { - if (await canLaunch(url)) { - final bool nativeAppLaunchSucceeded = await launch( - url, - forceSafariVC: false, - universalLinksOnly: true, - ); - if (!nativeAppLaunchSucceeded) { - await launch( - url, - forceSafariVC: true, - ); - } - } - } - Widget _launchStatus(BuildContext context, AsyncSnapshot snapshot) { if (snapshot.hasError) { return Text('Error: ${snapshot.error}'); @@ -113,14 +60,6 @@ class _MyHomePageState extends State { } } - Future _makePhoneCall(String url) async { - if (await canLaunch(url)) { - await launch(url); - } else { - throw 'Could not launch $url'; - } - } - @override Widget build(BuildContext context) { const String toLaunch = 'https://www.cylog.org/headers/'; @@ -133,19 +72,6 @@ class _MyHomePageState extends State { Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Padding( - padding: const EdgeInsets.all(16.0), - child: TextField( - onChanged: (String text) => _phone = text, - decoration: const InputDecoration( - hintText: 'Input the phone number to launch')), - ), - ElevatedButton( - onPressed: () => setState(() { - _launched = _makePhoneCall('tel:$_phone'); - }), - child: const Text('Make phone call'), - ), const Padding( padding: EdgeInsets.all(16.0), child: Text(toLaunch), @@ -157,33 +83,6 @@ class _MyHomePageState extends State { child: const Text('Launch in browser'), ), const Padding(padding: EdgeInsets.all(16.0)), - ElevatedButton( - onPressed: () => setState(() { - _launched = _launchInWebViewOrVC(toLaunch); - }), - child: const Text('Launch in app'), - ), - ElevatedButton( - onPressed: () => setState(() { - _launched = _launchInWebViewWithJavaScript(toLaunch); - }), - child: const Text('Launch in app(JavaScript ON)'), - ), - ElevatedButton( - onPressed: () => setState(() { - _launched = _launchInWebViewWithDomStorage(toLaunch); - }), - child: const Text('Launch in app(DOM storage ON)'), - ), - const Padding(padding: EdgeInsets.all(16.0)), - ElevatedButton( - onPressed: () => setState(() { - _launched = _launchUniversalLinkIos(toLaunch); - }), - child: const Text( - 'Launch a universal link in a native app, fallback to Safari.(Youtube)'), - ), - const Padding(padding: EdgeInsets.all(16.0)), FutureBuilder(future: _launched, builder: _launchStatus), ], ), diff --git a/packages/url_launcher/url_launcher_linux/example/pubspec.yaml b/packages/url_launcher/url_launcher_linux/example/pubspec.yaml index e95bcd0af478..63c920fba614 100644 --- a/packages/url_launcher/url_launcher_linux/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_linux/example/pubspec.yaml @@ -4,7 +4,6 @@ description: Demonstrates how to use the url_launcher plugin. dependencies: flutter: sdk: flutter - url_launcher: any url_launcher_linux: # When depending on this package from a real application you should use: # url_launcher_linux: ^x.y.z @@ -12,17 +11,18 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ + url_launcher_platform_interface: ^2.0.0 dev_dependencies: integration_test: path: ../../../integration_test flutter_driver: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.12.8" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" diff --git a/packages/url_launcher/url_launcher_linux/example/test_driver/integration_test.dart b/packages/url_launcher/url_launcher_linux/example/test_driver/integration_test.dart index 7a2c21338786..a8a56aa90f6a 100644 --- a/packages/url_launcher/url_launcher_linux/example/test_driver/integration_test.dart +++ b/packages/url_launcher/url_launcher_linux/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/url_launcher/url_launcher_linux/pubspec.yaml b/packages/url_launcher/url_launcher_linux/pubspec.yaml index 37a074a57436..cc974094b2d0 100644 --- a/packages/url_launcher/url_launcher_linux/pubspec.yaml +++ b/packages/url_launcher/url_launcher_linux/pubspec.yaml @@ -1,17 +1,18 @@ name: url_launcher_linux description: Linux implementation of the url_launcher plugin. -version: 2.0.0-nullsafety +version: 2.0.0 homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_linux flutter: plugin: + implements: url_launcher platforms: linux: pluginClass: UrlLauncherPlugin environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.12.8" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" dependencies: flutter: diff --git a/packages/url_launcher/url_launcher_macos/CHANGELOG.md b/packages/url_launcher/url_launcher_macos/CHANGELOG.md index 5835c15f64e0..6b0820fd5588 100644 --- a/packages/url_launcher/url_launcher_macos/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_macos/CHANGELOG.md @@ -1,18 +1,8 @@ -## 2.0.0-nullsafety - -* Update version to (semi-belatedly) meet 1.0-consistency promise. - -# 0.1.0-nullsafety.2 - -* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. - -# 0.1.0-nullsafety.1 - -* Bump SDK to support null safety. - -# 0.1.0-nullsafety +## 2.0.0 * Migrate to null safety. +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. +* Set `implementation` in pubspec.yaml ## 0.0.2+1 diff --git a/packages/url_launcher/url_launcher_macos/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_macos/example/integration_test/url_launcher_test.dart index 3e8d34c0b258..d0c1a8bd7325 100644 --- a/packages/url_launcher/url_launcher_macos/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_macos/example/integration_test/url_launcher_test.dart @@ -2,23 +2,24 @@ // 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:url_launcher/url_launcher.dart'; +import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('canLaunch', (WidgetTester _) async { - expect(await canLaunch('randomstring'), false); + UrlLauncherPlatform launcher = UrlLauncherPlatform.instance; + + expect(await launcher.canLaunch('randomstring'), false); // Generally all devices should have some default browser. - expect(await canLaunch('http://flutter.dev'), true); + expect(await launcher.canLaunch('http://flutter.dev'), true); // Generally all devices should have some default SMS app. - expect(await canLaunch('sms:5555555555'), true); - - // tel: and mailto: links may not be openable on every device. iOS - // simulators notably can't open these link types. + expect(await launcher.canLaunch('sms:5555555555'), true); }); } diff --git a/packages/url_launcher/url_launcher_macos/example/lib/main.dart b/packages/url_launcher/url_launcher_macos/example/lib/main.dart index a45862012328..f49e9fa290c5 100644 --- a/packages/url_launcher/url_launcher_macos/example/lib/main.dart +++ b/packages/url_launcher/url_launcher_macos/example/lib/main.dart @@ -6,7 +6,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:url_launcher/url_launcher.dart'; +import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; void main() { runApp(MyApp()); @@ -26,7 +26,7 @@ class MyApp extends StatelessWidget { } class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); + MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @override @@ -34,77 +34,24 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { - Future _launched; - String _phone = ''; + Future? _launched; Future _launchInBrowser(String url) async { - if (await canLaunch(url)) { - await launch( + if (await UrlLauncherPlatform.instance.canLaunch(url)) { + await UrlLauncherPlatform.instance.launch( url, - forceSafariVC: false, - forceWebView: false, - headers: {'my_header_key': 'my_header_value'}, + useSafariVC: false, + useWebView: false, + enableJavaScript: false, + enableDomStorage: false, + universalLinksOnly: false, + headers: {}, ); } else { throw 'Could not launch $url'; } } - Future _launchInWebViewOrVC(String url) async { - if (await canLaunch(url)) { - await launch( - url, - forceSafariVC: true, - forceWebView: true, - headers: {'my_header_key': 'my_header_value'}, - ); - } else { - throw 'Could not launch $url'; - } - } - - Future _launchInWebViewWithJavaScript(String url) async { - if (await canLaunch(url)) { - await launch( - url, - forceSafariVC: true, - forceWebView: true, - enableJavaScript: true, - ); - } else { - throw 'Could not launch $url'; - } - } - - Future _launchInWebViewWithDomStorage(String url) async { - if (await canLaunch(url)) { - await launch( - url, - forceSafariVC: true, - forceWebView: true, - enableDomStorage: true, - ); - } else { - throw 'Could not launch $url'; - } - } - - Future _launchUniversalLinkIos(String url) async { - if (await canLaunch(url)) { - final bool nativeAppLaunchSucceeded = await launch( - url, - forceSafariVC: false, - universalLinksOnly: true, - ); - if (!nativeAppLaunchSucceeded) { - await launch( - url, - forceSafariVC: true, - ); - } - } - } - Widget _launchStatus(BuildContext context, AsyncSnapshot snapshot) { if (snapshot.hasError) { return Text('Error: ${snapshot.error}'); @@ -113,14 +60,6 @@ class _MyHomePageState extends State { } } - Future _makePhoneCall(String url) async { - if (await canLaunch(url)) { - await launch(url); - } else { - throw 'Could not launch $url'; - } - } - @override Widget build(BuildContext context) { const String toLaunch = 'https://www.cylog.org/headers/'; @@ -133,19 +72,6 @@ class _MyHomePageState extends State { Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Padding( - padding: const EdgeInsets.all(16.0), - child: TextField( - onChanged: (String text) => _phone = text, - decoration: const InputDecoration( - hintText: 'Input the phone number to launch')), - ), - ElevatedButton( - onPressed: () => setState(() { - _launched = _makePhoneCall('tel:$_phone'); - }), - child: const Text('Make phone call'), - ), const Padding( padding: EdgeInsets.all(16.0), child: Text(toLaunch), @@ -157,33 +83,6 @@ class _MyHomePageState extends State { child: const Text('Launch in browser'), ), const Padding(padding: EdgeInsets.all(16.0)), - ElevatedButton( - onPressed: () => setState(() { - _launched = _launchInWebViewOrVC(toLaunch); - }), - child: const Text('Launch in app'), - ), - ElevatedButton( - onPressed: () => setState(() { - _launched = _launchInWebViewWithJavaScript(toLaunch); - }), - child: const Text('Launch in app(JavaScript ON)'), - ), - ElevatedButton( - onPressed: () => setState(() { - _launched = _launchInWebViewWithDomStorage(toLaunch); - }), - child: const Text('Launch in app(DOM storage ON)'), - ), - const Padding(padding: EdgeInsets.all(16.0)), - ElevatedButton( - onPressed: () => setState(() { - _launched = _launchUniversalLinkIos(toLaunch); - }), - child: const Text( - 'Launch a universal link in a native app, fallback to Safari.(Youtube)'), - ), - const Padding(padding: EdgeInsets.all(16.0)), FutureBuilder(future: _launched, builder: _launchStatus), ], ), diff --git a/packages/url_launcher/url_launcher_macos/example/pubspec.yaml b/packages/url_launcher/url_launcher_macos/example/pubspec.yaml index 2e66616101c2..40bb4eaba67a 100644 --- a/packages/url_launcher/url_launcher_macos/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_macos/example/pubspec.yaml @@ -4,7 +4,6 @@ description: Demonstrates how to use the url_launcher plugin. dependencies: flutter: sdk: flutter - url_launcher: any url_launcher_macos: # When depending on this package from a real application you should use: # url_launcher_macos: ^x.y.z @@ -12,17 +11,18 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ + url_launcher_platform_interface: ^2.0.0 dev_dependencies: integration_test: path: ../../../integration_test flutter_driver: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.12.8" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" diff --git a/packages/url_launcher/url_launcher_macos/example/test_driver/integration_test.dart b/packages/url_launcher/url_launcher_macos/example/test_driver/integration_test.dart index 7a2c21338786..a8a56aa90f6a 100644 --- a/packages/url_launcher/url_launcher_macos/example/test_driver/integration_test.dart +++ b/packages/url_launcher/url_launcher_macos/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/url_launcher/url_launcher_macos/pubspec.yaml b/packages/url_launcher/url_launcher_macos/pubspec.yaml index bd918bfda24e..6b5e6cf2a825 100644 --- a/packages/url_launcher/url_launcher_macos/pubspec.yaml +++ b/packages/url_launcher/url_launcher_macos/pubspec.yaml @@ -1,18 +1,19 @@ name: url_launcher_macos description: macOS implementation of the url_launcher plugin. -version: 2.0.0-nullsafety +version: 2.0.0 homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_macos flutter: plugin: + implements: url_launcher platforms: macos: pluginClass: UrlLauncherPlugin fileName: url_launcher_macos.dart environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.12.8" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" dependencies: flutter: diff --git a/packages/url_launcher/url_launcher_web/CHANGELOG.md b/packages/url_launcher/url_launcher_web/CHANGELOG.md index 49d72457ecd9..7da0ba0a8095 100644 --- a/packages/url_launcher/url_launcher_web/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_web/CHANGELOG.md @@ -1,4 +1,4 @@ -# 2.0.0-nullsafety +# 2.0.0 - Migrate to null safety. diff --git a/packages/url_launcher/url_launcher_web/example/pubspec.yaml b/packages/url_launcher/url_launcher_web/example/pubspec.yaml index 5fc060fe7abe..51748610e971 100644 --- a/packages/url_launcher/url_launcher_web/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/example/pubspec.yaml @@ -18,5 +18,5 @@ dev_dependencies: sdk: flutter environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.26.0-0" # For integration_test from sdk diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml index b9f957a7ee76..371a40e16f7b 100644 --- a/packages/url_launcher/url_launcher_web/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/pubspec.yaml @@ -1,7 +1,7 @@ name: url_launcher_web description: Web platform implementation of url_launcher homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_web -version: 2.0.0-nullsafety +version: 2.0.0 flutter: plugin: @@ -11,7 +11,7 @@ flutter: fileName: url_launcher_web.dart dependencies: - url_launcher_platform_interface: ^2.0.0-nullsafety + url_launcher_platform_interface: ^2.0.0 meta: ^1.3.0 # null safe flutter: sdk: flutter @@ -24,5 +24,5 @@ dev_dependencies: sdk: flutter environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.12.13+hotfix.5" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" diff --git a/packages/url_launcher/url_launcher_windows/CHANGELOG.md b/packages/url_launcher/url_launcher_windows/CHANGELOG.md index b57785524d08..e906254eef44 100644 --- a/packages/url_launcher/url_launcher_windows/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_windows/CHANGELOG.md @@ -1,18 +1,8 @@ -## 2.0.0-nullsafety - -* Update version to (semi-belatedly) meet 1.0-consistency promise. - -## 0.1.0-nullsafety.2 - -* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. - -## 0.1.0-nullsafety.1 - -* Bump Dart SDK to support null safety. - -## 0.1.0-nullsafety +## 2.0.0 * Migrate to null-safety. +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. +* Set `implementation` in pubspec.yaml ## 0.0.2+1 diff --git a/packages/url_launcher/url_launcher_windows/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_windows/example/integration_test/url_launcher_test.dart index 2617150348ee..e1008fddd4e1 100644 --- a/packages/url_launcher/url_launcher_windows/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_windows/example/integration_test/url_launcher_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:url_launcher_platform_interface/url_launcher_platform_interface.dart'; diff --git a/packages/url_launcher/url_launcher_windows/example/lib/main.dart b/packages/url_launcher/url_launcher_windows/example/lib/main.dart index e6c9f477b5a4..f49e9fa290c5 100644 --- a/packages/url_launcher/url_launcher_windows/example/lib/main.dart +++ b/packages/url_launcher/url_launcher_windows/example/lib/main.dart @@ -26,7 +26,7 @@ class MyApp extends StatelessWidget { } class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); + MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @override @@ -34,7 +34,7 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { - Future _launched; + Future? _launched; Future _launchInBrowser(String url) async { if (await UrlLauncherPlatform.instance.canLaunch(url)) { diff --git a/packages/url_launcher/url_launcher_windows/example/pubspec.yaml b/packages/url_launcher/url_launcher_windows/example/pubspec.yaml index 2de2bcf14f44..8a273ba65020 100644 --- a/packages/url_launcher/url_launcher_windows/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_windows/example/pubspec.yaml @@ -4,7 +4,7 @@ description: Demonstrates the Windows implementation of the url_launcher plugin. dependencies: flutter: sdk: flutter - url_launcher_platform_interface: any + url_launcher_platform_interface: ^2.0.0 url_launcher_windows: # When depending on this package from a real application you should use: # url_launcher_windows: ^x.y.z @@ -18,11 +18,11 @@ dev_dependencies: path: ../../../integration_test flutter_driver: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.12.8" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" diff --git a/packages/url_launcher/url_launcher_windows/example/test_driver/integration_test.dart b/packages/url_launcher/url_launcher_windows/example/test_driver/integration_test.dart index 7a2c21338786..a8a56aa90f6a 100644 --- a/packages/url_launcher/url_launcher_windows/example/test_driver/integration_test.dart +++ b/packages/url_launcher/url_launcher_windows/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/url_launcher/url_launcher_windows/pubspec.yaml b/packages/url_launcher/url_launcher_windows/pubspec.yaml index 368c3f831c2a..e5b611f86af0 100644 --- a/packages/url_launcher/url_launcher_windows/pubspec.yaml +++ b/packages/url_launcher/url_launcher_windows/pubspec.yaml @@ -1,17 +1,18 @@ name: url_launcher_windows description: Windows implementation of the url_launcher plugin. -version: 2.0.0-nullsafety +version: 2.0.0 homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_windows flutter: plugin: + implements: url_launcher platforms: windows: pluginClass: UrlLauncherPlugin environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.12.8" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" dependencies: flutter: From f14eaecb33f6b7d1e4d359c17e4832fe216a18f1 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Mon, 22 Feb 2021 12:01:18 -0800 Subject: [PATCH 0176/1565] [battery] Bump version for NNBD stable (#3594) Also replaces Mockito with test/Fake since the usage is a simple fake. --- packages/battery/battery/CHANGELOG.md | 2 +- packages/battery/battery/example/pubspec.yaml | 4 ++-- packages/battery/battery/pubspec.yaml | 14 +++++++------- packages/battery/battery/test/battery_test.dart | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/battery/battery/CHANGELOG.md b/packages/battery/battery/CHANGELOG.md index d907ca33fe1e..ae9e798c364d 100644 --- a/packages/battery/battery/CHANGELOG.md +++ b/packages/battery/battery/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.0.0-nullsafety +## 2.0.0 * Migrate to null safety. diff --git a/packages/battery/battery/example/pubspec.yaml b/packages/battery/battery/example/pubspec.yaml index e118a7c21540..ea3d5d39ae14 100644 --- a/packages/battery/battery/example/pubspec.yaml +++ b/packages/battery/battery/example/pubspec.yaml @@ -17,11 +17,11 @@ dev_dependencies: sdk: flutter integration_test: path: ../../../integration_test - pedantic: ^1.10.0-nullsafety + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/battery/battery/pubspec.yaml b/packages/battery/battery/pubspec.yaml index 455905d62a9a..a987bd8c45a6 100644 --- a/packages/battery/battery/pubspec.yaml +++ b/packages/battery/battery/pubspec.yaml @@ -2,7 +2,7 @@ name: battery description: Flutter plugin for accessing information about the battery state (full, charging, discharging) on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/battery/battery -version: 2.0.0-nullsafety +version: 2.0.0 flutter: plugin: @@ -16,18 +16,18 @@ flutter: dependencies: flutter: sdk: flutter - meta: ^1.3.0-nullsafety - battery_platform_interface: ^2.0.0-nullsafety + meta: ^1.3.0 + battery_platform_interface: ^2.0.0 dev_dependencies: - mockito: ^5.0.0-nullsafety.0 flutter_test: sdk: flutter - plugin_platform_interface: ^1.1.0-nullsafety + plugin_platform_interface: ">=1.0.0 <3.0.0" integration_test: path: ../../integration_test - pedantic: ^1.10.0-nullsafety + pedantic: ^1.10.0 + test: ^1.16.3 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/battery/battery/test/battery_test.dart b/packages/battery/battery/test/battery_test.dart index 43155c59692c..ff1bf1596250 100644 --- a/packages/battery/battery/test/battery_test.dart +++ b/packages/battery/battery/test/battery_test.dart @@ -4,11 +4,11 @@ import 'dart:async'; +import 'package:battery/battery.dart'; import 'package:battery_platform_interface/battery_platform_interface.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; -import 'package:battery/battery.dart'; -import 'package:mockito/mockito.dart'; +import 'package:test/fake.dart'; void main() { group('battery', () { @@ -30,7 +30,7 @@ void main() { }); } -class MockBatteryPlatform extends Mock +class MockBatteryPlatform extends Fake with MockPlatformInterfaceMixin implements BatteryPlatform { Future batteryLevel() async { From bb3fc5ad22aca210d617d5a5c8f958bc3c629d62 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Mon, 22 Feb 2021 12:04:17 -0800 Subject: [PATCH 0177/1565] [path_provider] Update to stable NNBD (#3582) Bumps the versions in the app-facing package to make it stable NNBD. Changes the interface of four core methods to non-nullable, and adds a new exceptions if they aren't provided by the platform implementations. The list is somewhat arbitrary, but these seem like the four that are core enough that any implementation should either provide them, or explicitly say they don't have such a concept via UnsupportedError, since there isn't an obvious way for a developer to fall back if they are unexpectedly missing. --- .../path_provider/path_provider/CHANGELOG.md | 11 +- .../path_provider/example/pubspec.yaml | 4 +- .../path_provider/lib/path_provider.dart | 52 +++++-- .../path_provider/path_provider/pubspec.yaml | 18 +-- .../test/path_provider_test.dart | 127 +++++++++++++++--- 5 files changed, 165 insertions(+), 47 deletions(-) diff --git a/packages/path_provider/path_provider/CHANGELOG.md b/packages/path_provider/path_provider/CHANGELOG.md index a52711bf0736..c28c617bbea4 100644 --- a/packages/path_provider/path_provider/CHANGELOG.md +++ b/packages/path_provider/path_provider/CHANGELOG.md @@ -1,11 +1,10 @@ -## 2.0.0-nullsafety.1 - -* Require latest path_provider_windows to avoid potential issues - with breaking changes in `ffi` and `win32`. - -## 2.0.0-nullsafety +## 2.0.0 * Migrate to null safety. +* BREAKING CHANGE: Path accessors that return non-nullable results will throw + a `MissingPlatformDirectoryException` if the platform implementation is unable + to get the corresponding directory (except on platforms where the method is + explicitly unsupported, where they will continue to throw `UnsupportedError`). ## 1.6.28 diff --git a/packages/path_provider/path_provider/example/pubspec.yaml b/packages/path_provider/path_provider/example/pubspec.yaml index cef0449ca01a..68c751a81843 100644 --- a/packages/path_provider/path_provider/example/pubspec.yaml +++ b/packages/path_provider/path_provider/example/pubspec.yaml @@ -17,11 +17,11 @@ dev_dependencies: path: ../../../integration_test flutter_driver: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/path_provider/path_provider/lib/path_provider.dart b/packages/path_provider/path_provider/lib/path_provider.dart index 1560c3399e72..da9c0b3d48a3 100644 --- a/packages/path_provider/path_provider/lib/path_provider.dart +++ b/packages/path_provider/path_provider/lib/path_provider.dart @@ -20,6 +20,27 @@ set disablePathProviderPlatformOverride(bool override) {} bool _manualDartRegistrationNeeded = true; +/// An exception thrown when a directory that should always be available on +/// the current platform cannot be obtained. +class MissingPlatformDirectoryException implements Exception { + /// Creates a new exception + MissingPlatformDirectoryException(this.message, {this.details}); + + /// The explanation of the exception. + final String message; + + /// Added details, if any. + /// + /// E.g., an error object from the platform implementation. + final Object? details; + + @override + String toString() { + String detailsAddition = details == null ? '' : ': $details'; + return 'MissingPlatformDirectoryException($message)$detailsAddition'; + } +} + PathProviderPlatform get _platform { // This is to manually endorse Dart implementations until automatic // registration of Dart plugins is implemented. For details see @@ -51,10 +72,14 @@ PathProviderPlatform get _platform { /// On iOS, this uses the `NSCachesDirectory` API. /// /// On Android, this uses the `getCacheDir` API on the context. -Future getTemporaryDirectory() async { +/// +/// Throws a `MissingPlatformDirectoryException` if the system is unable to +/// provide the directory. +Future getTemporaryDirectory() async { final String? path = await _platform.getTemporaryPath(); if (path == null) { - return null; + throw MissingPlatformDirectoryException( + 'Unable to get temporary directory'); } return Directory(path); } @@ -69,10 +94,14 @@ Future getTemporaryDirectory() async { /// If this directory does not exist, it is created automatically. /// /// On Android, this function uses the `getFilesDir` API on the context. -Future getApplicationSupportDirectory() async { +/// +/// Throws a `MissingPlatformDirectoryException` if the system is unable to +/// provide the directory. +Future getApplicationSupportDirectory() async { final String? path = await _platform.getApplicationSupportPath(); if (path == null) { - return null; + throw MissingPlatformDirectoryException( + 'Unable to get application support directory'); } return Directory(path); @@ -83,10 +112,13 @@ Future getApplicationSupportDirectory() async { /// /// On Android, this function throws an [UnsupportedError] as no equivalent /// path exists. -Future getLibraryDirectory() async { +/// +/// Throws a `MissingPlatformDirectoryException` if the system is unable to +/// provide the directory on a supported platform. +Future getLibraryDirectory() async { final String? path = await _platform.getLibraryPath(); if (path == null) { - return null; + throw MissingPlatformDirectoryException('Unable to get library directory'); } return Directory(path); } @@ -100,10 +132,14 @@ Future getLibraryDirectory() async { /// On Android, this uses the `getDataDirectory` API on the context. Consider /// using [getExternalStorageDirectory] instead if data is intended to be visible /// to the user. -Future getApplicationDocumentsDirectory() async { +/// +/// Throws a `MissingPlatformDirectoryException` if the system is unable to +/// provide the directory. +Future getApplicationDocumentsDirectory() async { final String? path = await _platform.getApplicationDocumentsPath(); if (path == null) { - return null; + throw MissingPlatformDirectoryException( + 'Unable to get application documents directory'); } return Directory(path); } diff --git a/packages/path_provider/path_provider/pubspec.yaml b/packages/path_provider/path_provider/pubspec.yaml index 3d79c99e2223..81941dac67b1 100644 --- a/packages/path_provider/path_provider/pubspec.yaml +++ b/packages/path_provider/path_provider/pubspec.yaml @@ -1,7 +1,7 @@ name: path_provider description: Flutter plugin for getting commonly used locations on host platform file systems, such as the temp and app data directories. homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider -version: 2.0.0-nullsafety.1 +version: 2.0.0 flutter: plugin: @@ -21,10 +21,10 @@ flutter: dependencies: flutter: sdk: flutter - path_provider_platform_interface: ^2.0.0-nullsafety - path_provider_macos: ^0.0.5-nullsafety - path_provider_linux: ^0.2.0-nullsafety - path_provider_windows: ^0.1.0-nullsafety.3 + path_provider_platform_interface: ^2.0.0 + path_provider_macos: ^2.0.0 + path_provider_linux: ^2.0.0 + path_provider_windows: ^2.0.0 dev_dependencies: integration_test: @@ -33,10 +33,10 @@ dev_dependencies: sdk: flutter flutter_driver: sdk: flutter - pedantic: ^1.10.0-nullsafety - mockito: ^5.0.0-nullsafety.0 - plugin_platform_interface: ^1.1.0-nullsafety + pedantic: ^1.10.0 + plugin_platform_interface: ">=1.0.0 <3.0.0" + test: ^1.16.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/path_provider/path_provider/test/path_provider_test.dart b/packages/path_provider/path_provider/test/path_provider_test.dart index aec5e060f631..759e9c09ffc2 100644 --- a/packages/path_provider/path_provider/test/path_provider_test.dart +++ b/packages/path_provider/path_provider/test/path_provider_test.dart @@ -6,10 +6,10 @@ import 'dart:io' show Directory; import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; import 'package:path_provider/path_provider.dart'; import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import 'package:test/fake.dart'; const String kTemporaryPath = 'temporaryPath'; const String kApplicationSupportPath = 'applicationSupportPath'; @@ -20,31 +20,30 @@ const String kExternalCachePath = 'externalCachePath'; const String kExternalStoragePath = 'externalStoragePath'; void main() { - group('PathProvider', () { - TestWidgetsFlutterBinding.ensureInitialized(); - + TestWidgetsFlutterBinding.ensureInitialized(); + group('PathProvider full implementation', () { setUp(() async { - PathProviderPlatform.instance = MockPathProviderPlatform(); + PathProviderPlatform.instance = FakePathProviderPlatform(); }); test('getTemporaryDirectory', () async { - Directory? result = await getTemporaryDirectory(); - expect(result?.path, kTemporaryPath); + Directory result = await getTemporaryDirectory(); + expect(result.path, kTemporaryPath); }); test('getApplicationSupportDirectory', () async { - Directory? result = await getApplicationSupportDirectory(); - expect(result?.path, kApplicationSupportPath); + Directory result = await getApplicationSupportDirectory(); + expect(result.path, kApplicationSupportPath); }); test('getLibraryDirectory', () async { - Directory? result = await getLibraryDirectory(); - expect(result?.path, kLibraryPath); + Directory result = await getLibraryDirectory(); + expect(result.path, kLibraryPath); }); test('getApplicationDocumentsDirectory', () async { - Directory? result = await getApplicationDocumentsDirectory(); - expect(result?.path, kApplicationDocumentsPath); + Directory result = await getApplicationDocumentsDirectory(); + expect(result.path, kApplicationDocumentsPath); }); test('getExternalStorageDirectory', () async { @@ -69,42 +68,126 @@ void main() { expect(result?.path, kDownloadsPath); }); }); + + group('PathProvider null implementation', () { + setUp(() async { + PathProviderPlatform.instance = AllNullFakePathProviderPlatform(); + }); + + test('getTemporaryDirectory throws on null', () async { + expect(getTemporaryDirectory(), + throwsA(isA())); + }); + + test('getApplicationSupportDirectory throws on null', () async { + expect(getApplicationSupportDirectory(), + throwsA(isA())); + }); + + test('getLibraryDirectory throws on null', () async { + expect(getLibraryDirectory(), + throwsA(isA())); + }); + + test('getApplicationDocumentsDirectory throws on null', () async { + expect(getApplicationDocumentsDirectory(), + throwsA(isA())); + }); + + test('getExternalStorageDirectory passes null through', () async { + Directory? result = await getExternalStorageDirectory(); + expect(result, isNull); + }); + + test('getExternalCacheDirectories passes null through', () async { + List? result = await getExternalCacheDirectories(); + expect(result, isNull); + }); + + test('getExternalStorageDirectories passes null through', () async { + List? result = await getExternalStorageDirectories(); + expect(result, isNull); + }); + + test('getDownloadsDirectory passses null through', () async { + Directory? result = await getDownloadsDirectory(); + expect(result, isNull); + }); + }); } -class MockPathProviderPlatform extends Mock +class FakePathProviderPlatform extends Fake with MockPlatformInterfaceMixin implements PathProviderPlatform { - Future getTemporaryPath() async { + Future getTemporaryPath() async { return kTemporaryPath; } - Future getApplicationSupportPath() async { + Future getApplicationSupportPath() async { return kApplicationSupportPath; } - Future getLibraryPath() async { + Future getLibraryPath() async { return kLibraryPath; } - Future getApplicationDocumentsPath() async { + Future getApplicationDocumentsPath() async { return kApplicationDocumentsPath; } - Future getExternalStoragePath() async { + Future getExternalStoragePath() async { return kExternalStoragePath; } - Future> getExternalCachePaths() async { + Future?> getExternalCachePaths() async { return [kExternalCachePath]; } - Future> getExternalStoragePaths({ + Future?> getExternalStoragePaths({ StorageDirectory? type, }) async { return [kExternalStoragePath]; } - Future getDownloadsPath() async { + Future getDownloadsPath() async { return kDownloadsPath; } } + +class AllNullFakePathProviderPlatform extends Fake + with MockPlatformInterfaceMixin + implements PathProviderPlatform { + Future getTemporaryPath() async { + return null; + } + + Future getApplicationSupportPath() async { + return null; + } + + Future getLibraryPath() async { + return null; + } + + Future getApplicationDocumentsPath() async { + return null; + } + + Future getExternalStoragePath() async { + return null; + } + + Future?> getExternalCachePaths() async { + return null; + } + + Future?> getExternalStoragePaths({ + StorageDirectory? type, + }) async { + return null; + } + + Future getDownloadsPath() async { + return null; + } +} From b98d72548a2142c618b1e7e270f89ca9db67c039 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 22 Feb 2021 12:15:13 -0800 Subject: [PATCH 0178/1565] [connectivity_macos] fix version (#3599) --- packages/connectivity/connectivity_macos/CHANGELOG.md | 2 +- packages/connectivity/connectivity_macos/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/connectivity/connectivity_macos/CHANGELOG.md b/packages/connectivity/connectivity_macos/CHANGELOG.md index b3ad35a03281..7031e48318dd 100644 --- a/packages/connectivity/connectivity_macos/CHANGELOG.md +++ b/packages/connectivity/connectivity_macos/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.0.0 +## 0.2.0 * Remove placeholder Dart file. * Update Dart SDK constraint for compatibility with null safety. diff --git a/packages/connectivity/connectivity_macos/pubspec.yaml b/packages/connectivity/connectivity_macos/pubspec.yaml index 781bee88b55a..b8f36c8f55b4 100644 --- a/packages/connectivity/connectivity_macos/pubspec.yaml +++ b/packages/connectivity/connectivity_macos/pubspec.yaml @@ -1,6 +1,6 @@ name: connectivity_macos description: macOS implementation of the connectivity plugin. -version: 2.0.0 +version: 0.2.0 homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_macos flutter: From 0838c8253e8938fd92d1a3fee54ae4f4b5cd5594 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Mon, 22 Feb 2021 12:29:49 -0800 Subject: [PATCH 0179/1565] [google_maps_flutter] Bump platform interface version for NNBD stable (#3598) --- .../CHANGELOG.md | 6 +----- .../pubspec.yaml | 14 +++++++------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md index 7b2268395caf..0d5748d13f79 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md @@ -1,8 +1,4 @@ -## 2.0.0-nullsafety.1 - -* Fix overly-restrictive type check. - -## 2.0.0-nullsafety +## 2.0.0 * Migrated to null-safety. * BREAKING CHANGE: Removed deprecated APIs. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml index 2ec9e449a335..602efe3e6c62 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml @@ -3,22 +3,22 @@ description: A common platform interface for the google_maps_flutter plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0-nullsafety.1 +version: 2.0.0 dependencies: flutter: sdk: flutter - meta: ^1.0.5 - plugin_platform_interface: ^1.1.0-nullsafety.2 - stream_transform: ^2.0.0-nullsafety.0 - collection: ^1.14.13 + meta: ^1.3.0 + plugin_platform_interface: ">=1.0.0 <3.0.0" + stream_transform: ^2.0.0 + collection: ^1.15.0 dev_dependencies: flutter_test: sdk: flutter mockito: ^5.0.0-nullsafety.0 - pedantic: ^1.8.0 + pedantic: ^1.10.0 environment: - sdk: '>=2.12.0-0 <3.0.0' + sdk: '>=2.12.0-259.9.beta <3.0.0' flutter: ">=1.9.1+hotfix.4" From 61a736f46528a9069d50800d3055d4c168bcee03 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 22 Feb 2021 12:44:04 -0800 Subject: [PATCH 0180/1565] [device_info_platform_interface] null safety stable release (#3597) --- .../device_info_platform_interface/CHANGELOG.md | 11 ++--------- .../device_info_platform_interface/pubspec.yaml | 12 ++++++------ 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/packages/device_info/device_info_platform_interface/CHANGELOG.md b/packages/device_info/device_info_platform_interface/CHANGELOG.md index d4bc81e0f0aa..23e9bc770c95 100644 --- a/packages/device_info/device_info_platform_interface/CHANGELOG.md +++ b/packages/device_info/device_info_platform_interface/CHANGELOG.md @@ -1,16 +1,9 @@ -## 2.0.0-nullsafety.2 +## 2.0.0 +* Migrate to null safety. * Make `baseOS`, `previewSdkInt`, and `securityPatch` nullable types. * Remove default values for non-nullable types. -## 2.0.0-nullsafety.1 - -* Bump Dart SDK to support null safety. - -## 2.0.0-nullsafety - -* Migrate to null safety. - ## 1.0.2 - Update Flutter SDK constraint. diff --git a/packages/device_info/device_info_platform_interface/pubspec.yaml b/packages/device_info/device_info_platform_interface/pubspec.yaml index ca72cc753b63..3887aea3eff2 100644 --- a/packages/device_info/device_info_platform_interface/pubspec.yaml +++ b/packages/device_info/device_info_platform_interface/pubspec.yaml @@ -3,20 +3,20 @@ description: A common platform interface for the device_info plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/device_info # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0-nullsafety.2 +version: 2.0.0 dependencies: flutter: sdk: flutter - meta: ^1.3.0-nullsafety.3 - plugin_platform_interface: ^1.1.0-nullsafety.1 + meta: ^1.3.0 + plugin_platform_interface: ">=1.0.0 <3.0.0" dev_dependencies: flutter_test: sdk: flutter - test: ^1.10.0-nullsafety.1 - pedantic: ^1.10.0-nullsafety.1 + test: ^1.16.3 + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.9.1+hotfix.4" From 0ea8ef89b63097d8d9974307f9665bb02d9ee4d7 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Mon, 22 Feb 2021 12:59:52 -0800 Subject: [PATCH 0181/1565] [share] Bump version for NNBD stable (#3600) --- packages/share/CHANGELOG.md | 15 +++------------ packages/share/example/lib/image_previews.dart | 10 +++++----- packages/share/example/lib/main.dart | 2 +- packages/share/example/pubspec.yaml | 6 +++--- .../test_driver/test/integration_test.dart | 2 ++ packages/share/pubspec.yaml | 14 +++++++------- 6 files changed, 21 insertions(+), 28 deletions(-) diff --git a/packages/share/CHANGELOG.md b/packages/share/CHANGELOG.md index ba44db433d17..20afdea9f054 100644 --- a/packages/share/CHANGELOG.md +++ b/packages/share/CHANGELOG.md @@ -1,18 +1,9 @@ -## 2.0.0-nullsafety.3 - -* Update README with the new documentation urls. - -## 2.0.0-nullsafety.2 +## 2.0.0 +* Migrate to null safety. * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. - -## 2.0.0-nullsafety.1 - * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) - -## 2.0.0-nullsafety - -* Migrate to null safety. +* Update README with the new documentation urls. ## 0.6.5+5 diff --git a/packages/share/example/lib/image_previews.dart b/packages/share/example/lib/image_previews.dart index 61ecec43bdc7..9070749267fc 100644 --- a/packages/share/example/lib/image_previews.dart +++ b/packages/share/example/lib/image_previews.dart @@ -9,11 +9,11 @@ class ImagePreviews extends StatelessWidget { final List imagePaths; /// Callback when an image should be removed - final Function(int) onDelete; + final Function(int)? onDelete; /// Creates a widget for preview of images. [imagePaths] can not be empty /// and all contained paths need to be non empty. - const ImagePreviews(this.imagePaths, {Key key, this.onDelete}) + const ImagePreviews(this.imagePaths, {Key? key, this.onDelete}) : super(key: key); @override @@ -26,7 +26,7 @@ class ImagePreviews extends StatelessWidget { for (int i = 0; i < imagePaths.length; i++) { imageWidgets.add(_ImagePreview( imagePaths[i], - onDelete: onDelete != null ? () => onDelete(i) : null, + onDelete: onDelete != null ? () => onDelete!(i) : null, )); } @@ -39,9 +39,9 @@ class ImagePreviews extends StatelessWidget { class _ImagePreview extends StatelessWidget { final String imagePath; - final VoidCallback onDelete; + final VoidCallback? onDelete; - const _ImagePreview(this.imagePath, {Key key, this.onDelete}) + const _ImagePreview(this.imagePath, {Key? key, this.onDelete}) : super(key: key); @override diff --git a/packages/share/example/lib/main.dart b/packages/share/example/lib/main.dart index a9ebd6bb79fb..8d6a78305db9 100644 --- a/packages/share/example/lib/main.dart +++ b/packages/share/example/lib/main.dart @@ -116,7 +116,7 @@ class DemoAppState extends State { // RenderObject in its descendent tree when it's not // a RenderObjectWidget. The ElevatedButton's RenderObject // has its position and size after it's built. - final RenderBox box = context.findRenderObject(); + final RenderBox box = context.findRenderObject() as RenderBox; if (imagePaths.isNotEmpty) { await Share.shareFiles(imagePaths, diff --git a/packages/share/example/pubspec.yaml b/packages/share/example/pubspec.yaml index 372633ec19ec..2df76efb6ca2 100644 --- a/packages/share/example/pubspec.yaml +++ b/packages/share/example/pubspec.yaml @@ -11,18 +11,18 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - image_picker: ^0.6.7+4 + image_picker: ^0.7.0 dev_dependencies: flutter_driver: sdk: flutter integration_test: path: ../../integration_test - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.0.0-dev.28.0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.9.1+hotfix.2" diff --git a/packages/share/example/test_driver/test/integration_test.dart b/packages/share/example/test_driver/test/integration_test.dart index 7a2c21338786..a8a56aa90f6a 100644 --- a/packages/share/example/test_driver/test/integration_test.dart +++ b/packages/share/example/test_driver/test/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/share/pubspec.yaml b/packages/share/pubspec.yaml index 4d2b231bbdfb..e8a116799433 100644 --- a/packages/share/pubspec.yaml +++ b/packages/share/pubspec.yaml @@ -2,7 +2,7 @@ name: share description: Flutter plugin for sharing content via the platform share UI, using the ACTION_SEND intent on Android and UIActivityViewController on iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/share -version: 2.0.0-nullsafety.3 +version: 2.0.0 flutter: plugin: @@ -14,20 +14,20 @@ flutter: pluginClass: FLTSharePlugin dependencies: - meta: ^1.3.0-nullsafety.6 - mime: ^1.0.0-nullsafety.0 + meta: ^1.3.0 + mime: ^1.0.0 flutter: sdk: flutter dev_dependencies: - test: ^1.16.0-nullsafety.13 - mockito: ^4.1.3 + test: ^1.16.3 + mockito: ^5.0.0-nullsafety.7 flutter_test: sdk: flutter integration_test: path: ../integration_test - pedantic: ^1.10.0-nullsafety.3 + pedantic: ^1.10.0 environment: flutter: ">=1.12.13+hotfix.5" - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" From 39964495426d74f0e4149ff904ca8d702a116329 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Mon, 22 Feb 2021 13:40:29 -0800 Subject: [PATCH 0182/1565] [android_intent] Bump version for NNBD stable (#3601) --- packages/android_intent/CHANGELOG.md | 12 +++--------- .../integration_test/android_intent_test.dart | 6 ++++++ packages/android_intent/example/pubspec.yaml | 4 ++-- .../example/test_driver/integration_test.dart | 6 ++++++ packages/android_intent/pubspec.yaml | 14 +++++++------- 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/packages/android_intent/CHANGELOG.md b/packages/android_intent/CHANGELOG.md index 3e878a50aac2..70926b4f4943 100644 --- a/packages/android_intent/CHANGELOG.md +++ b/packages/android_intent/CHANGELOG.md @@ -1,14 +1,8 @@ -## 2.0.0-nullsafety.2 - -* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. - -## 2.0.0-nullsafety.1 - -* Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) - -## 2.0.0-nullsafety +## 2.0.0 * Migrate to null safety. +* Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. ## 0.3.7+8 diff --git a/packages/android_intent/example/integration_test/android_intent_test.dart b/packages/android_intent/example/integration_test/android_intent_test.dart index 78a667b27a09..e11a5e4e4898 100644 --- a/packages/android_intent/example/integration_test/android_intent_test.dart +++ b/packages/android_intent/example/integration_test/android_intent_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 'dart:io'; import 'package:android_intent/android_intent.dart'; diff --git a/packages/android_intent/example/pubspec.yaml b/packages/android_intent/example/pubspec.yaml index 7a0814d4acc0..2b1aab823d12 100644 --- a/packages/android_intent/example/pubspec.yaml +++ b/packages/android_intent/example/pubspec.yaml @@ -17,12 +17,12 @@ dev_dependencies: path: ../../integration_test flutter_driver: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0 # The following section is specific to Flutter. flutter: uses-material-design: true environment: - sdk: ">=2.3.0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/android_intent/example/test_driver/integration_test.dart b/packages/android_intent/example/test_driver/integration_test.dart index 34483b996049..0378ec31ee3c 100644 --- a/packages/android_intent/example/test_driver/integration_test.dart +++ b/packages/android_intent/example/test_driver/integration_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 'dart:async'; import 'dart:convert'; import 'dart:io'; diff --git a/packages/android_intent/pubspec.yaml b/packages/android_intent/pubspec.yaml index c61460718fc1..ba830bddf1df 100644 --- a/packages/android_intent/pubspec.yaml +++ b/packages/android_intent/pubspec.yaml @@ -1,7 +1,7 @@ name: android_intent description: Flutter plugin for launching Android Intents. Not supported on iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/android_intent -version: 2.0.0-nullsafety.2 +version: 2.0.0 flutter: plugin: @@ -13,15 +13,15 @@ flutter: dependencies: flutter: sdk: flutter - platform: ^3.0.0-nullsafety.4 - meta: ^1.3.0-nullsafety.6 + platform: ^3.0.0 + meta: ^1.3.0 dev_dependencies: - test: ^1.16.0-nullsafety.13 - mockito: ^4.1.3 + test: ^1.16.3 + mockito: ^5.0.0-nullsafety.7 flutter_test: sdk: flutter - pedantic: ^1.10.0-nullsafety.1 + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" From 5f29f9e7c3655221bcbb9c2c306d3a1194cd4155 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Mon, 22 Feb 2021 14:10:35 -0800 Subject: [PATCH 0183/1565] [shared_preferences] Bump app-facing version for NNBD stable (#3602) --- .../shared_preferences/CHANGELOG.md | 6 +----- .../shared_preferences/example/pubspec.yaml | 4 ++-- .../shared_preferences/pubspec.yaml | 18 +++++++++--------- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/packages/shared_preferences/shared_preferences/CHANGELOG.md b/packages/shared_preferences/shared_preferences/CHANGELOG.md index a14ebf547659..2e05c8bbff05 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,8 +1,4 @@ -## 2.0.0-nullsafety.1 - -* Fix crash when list string's type is dynamic. - -## 2.0.0-nullsafety +## 2.0.0 * Migrate to null-safety. diff --git a/packages/shared_preferences/shared_preferences/example/pubspec.yaml b/packages/shared_preferences/shared_preferences/example/pubspec.yaml index ab6c8fe11f7f..84692d76e5a1 100644 --- a/packages/shared_preferences/shared_preferences/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/example/pubspec.yaml @@ -17,11 +17,11 @@ dev_dependencies: sdk: flutter integration_test: path: ../../../integration_test - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.9.1+hotfix.2" diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index fc556972a847..583600d6a78b 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -2,7 +2,7 @@ name: shared_preferences description: Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences -version: 2.0.0-nullsafety.1 +version: 2.0.0 flutter: plugin: @@ -20,19 +20,19 @@ flutter: default_package: shared_preferences_web dependencies: - meta: ^1.0.4 + meta: ^1.3.0 flutter: sdk: flutter - shared_preferences_platform_interface: ^2.0.0-nullsafety + shared_preferences_platform_interface: ^2.0.0 # The design on https://flutter.dev/go/federated-plugins was to leave # this constraint as "any". We cannot do it right now as it fails pub publish # validation, so we set a ^ constraint. # TODO(franciscojma): Revisit this (either update this part in the design or the pub tool). # https://github.com/flutter/flutter/issues/46264 - shared_preferences_linux: ^0.0.4-nullsafety - shared_preferences_macos: ^0.0.2-nullsafety - shared_preferences_web: ^0.2.0-nullsafety - shared_preferences_windows: ^0.0.3-nullsafety + shared_preferences_linux: ^2.0.0 + shared_preferences_macos: ^2.0.0 + shared_preferences_web: ^2.0.0 + shared_preferences_windows: ^2.0.0 dev_dependencies: flutter_test: @@ -41,8 +41,8 @@ dev_dependencies: sdk: flutter integration_test: path: ../../integration_test - pedantic: ^1.8.0 + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" From f2696d56f2edf0279134ffba4e63dce05279e6d5 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 22 Feb 2021 15:26:08 -0800 Subject: [PATCH 0184/1565] [connectivity_macos] fix flutter version constraint (#3604) --- packages/connectivity/connectivity_macos/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/connectivity/connectivity_macos/pubspec.yaml b/packages/connectivity/connectivity_macos/pubspec.yaml index b8f36c8f55b4..860b16497bc6 100644 --- a/packages/connectivity/connectivity_macos/pubspec.yaml +++ b/packages/connectivity/connectivity_macos/pubspec.yaml @@ -11,7 +11,7 @@ flutter: environment: sdk: ">=2.12.0-259.9.beta <3.0.0" - flutter: ">=1.10.0" + flutter: ">=1.20.0" dependencies: flutter: From 774d623c8e5c8f34ee3e76095145076879364793 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Mon, 22 Feb 2021 15:44:01 -0800 Subject: [PATCH 0185/1565] [url_launcher] Bump app-facing version for NNBD stable (#3603) --- .../url_launcher/url_launcher/CHANGELOG.md | 34 +++---------------- .../url_launcher/example/pubspec.yaml | 8 ++--- .../url_launcher/url_launcher/pubspec.yaml | 22 ++++++------ 3 files changed, 19 insertions(+), 45 deletions(-) diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index f467ec4d1830..f5fb73104c50 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,35 +1,9 @@ -## 6.0.0-nullsafety.7 - -* Re-endorse `url_launcher_web` in the `nullsafety` prerelease. - -## 6.0.0-nullsafety.6 - -* Correct statement in description about which platforms url_launcher supports. - -## 6.0.0-nullsafety.5 - -* Document that the web plugin is not endorsed in the `nullsafety` prerelease for now. - -## 6.0.0-nullsafety.4 - -* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. - -## 6.0.0-nullsafety.3 - -* forceSafariVC should be nullable. - -## 6.0.0-nullsafety.2 - -* Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) - -## 6.0.0-nullsafety.1 - -* Bump Dart SDK to support null safety. - -## 6.0.0-nullsafety +## 6.0.0 * Migrate to null safety. -* **Breaking change**: web plugins aren't endorsed in null-safe plugins yet. +* Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. +* Correct statement in description about which platforms url_launcher supports. ## 5.7.13 diff --git a/packages/url_launcher/url_launcher/example/pubspec.yaml b/packages/url_launcher/url_launcher/example/pubspec.yaml index 520b6863ec2d..5f313f3870c5 100644 --- a/packages/url_launcher/url_launcher/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher/example/pubspec.yaml @@ -17,13 +17,13 @@ dev_dependencies: path: ../../../integration_test flutter_driver: sdk: flutter - pedantic: ^1.10.0-nullsafety.1 - mockito: ^4.1.1 - plugin_platform_interface: ^1.1.0-nullsafety.1 + pedantic: ^1.10.0 + mockito: ^5.0.0-nullsafety.7 + plugin_platform_interface: ">=1.0.0 <3.0.0" flutter: uses-material-design: true environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index d058e2fa1409..a9c2794b069a 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -2,7 +2,7 @@ name: url_launcher description: Flutter plugin for launching a URL. Supports web, phone, SMS, and email schemes. homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher -version: 6.0.0-nullsafety.7 +version: 6.0.0 flutter: plugin: @@ -24,25 +24,25 @@ flutter: dependencies: flutter: sdk: flutter - url_launcher_platform_interface: ^2.0.0-nullsafety + url_launcher_platform_interface: ^2.0.0 # The design on https://flutter.dev/go/federated-plugins was to leave # this constraint as "any". We cannot do it right now as it fails pub publish # validation, so we set a ^ constraint. # TODO(amirh): Revisit this (either update this part in the design or the pub tool). # https://github.com/flutter/flutter/issues/46264 - url_launcher_linux: ^0.1.0-nullsafety - url_launcher_macos: ^0.1.0-nullsafety - url_launcher_windows: ^0.1.0-nullsafety - url_launcher_web: ^2.0.0-nullsafety + url_launcher_linux: ^2.0.0 + url_launcher_macos: ^2.0.0 + url_launcher_windows: ^2.0.0 + url_launcher_web: ^2.0.0 dev_dependencies: flutter_test: sdk: flutter - test: ^1.10.0-nullsafety.1 - mockito: ^4.1.1 - plugin_platform_interface: ^1.1.0-nullsafety.1 - pedantic: ^1.10.0-nullsafety.1 + test: ^1.16.3 + mockito: ^5.0.0-nullsafety.7 + plugin_platform_interface: ">=1.0.0 <3.0.0" + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" From d4480fbf7d554833caec9854b6c6b4da83f0cbe2 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Mon, 22 Feb 2021 17:57:43 -0800 Subject: [PATCH 0186/1565] [android_intent] Fix Flutter SDK version (#3607) --- packages/android_intent/example/pubspec.yaml | 2 +- packages/android_intent/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/android_intent/example/pubspec.yaml b/packages/android_intent/example/pubspec.yaml index 2b1aab823d12..fd0e2d6b7844 100644 --- a/packages/android_intent/example/pubspec.yaml +++ b/packages/android_intent/example/pubspec.yaml @@ -25,4 +25,4 @@ flutter: environment: sdk: ">=2.12.0-259.9.beta <3.0.0" - flutter: ">=1.12.13+hotfix.5" + flutter: ">=1.20.0" diff --git a/packages/android_intent/pubspec.yaml b/packages/android_intent/pubspec.yaml index ba830bddf1df..e02c7a270344 100644 --- a/packages/android_intent/pubspec.yaml +++ b/packages/android_intent/pubspec.yaml @@ -24,4 +24,4 @@ dev_dependencies: environment: sdk: ">=2.12.0-259.9.beta <3.0.0" - flutter: ">=1.12.13+hotfix.5" + flutter: ">=1.20.0" From ab8fb51eecc03d497618b462ef90d3f5c3b81fab Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Mon, 22 Feb 2021 18:33:08 -0800 Subject: [PATCH 0187/1565] [file_selector_platform_interface] null safety stable release (#3605) --- .../CHANGELOG.md | 2 +- .../pubspec.yaml | 19 +++++++++--------- ...file_selector_platform_interface_test.dart | 20 ------------------- 3 files changed, 10 insertions(+), 31 deletions(-) diff --git a/packages/file_selector/file_selector_platform_interface/CHANGELOG.md b/packages/file_selector/file_selector_platform_interface/CHANGELOG.md index 2fbe18db7bfd..ed720ca0515d 100644 --- a/packages/file_selector/file_selector_platform_interface/CHANGELOG.md +++ b/packages/file_selector/file_selector_platform_interface/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.0.0-nullsafety.0 +## 2.0.0 * Migration to null-safety diff --git a/packages/file_selector/file_selector_platform_interface/pubspec.yaml b/packages/file_selector/file_selector_platform_interface/pubspec.yaml index 9735bced03fb..30398a2f0d23 100644 --- a/packages/file_selector/file_selector_platform_interface/pubspec.yaml +++ b/packages/file_selector/file_selector_platform_interface/pubspec.yaml @@ -3,23 +3,22 @@ description: A common platform interface for the file_selector plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/file_selector/file_selector_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0-nullsafety.0 +version: 2.0.0 dependencies: flutter: sdk: flutter - meta: ^1.0.5 - http: ^0.13.0-nullsafety.0 - plugin_platform_interface: ^1.1.0-nullsafety.2 - cross_file: ^0.3.0-nullsafety + meta: ^1.3.0 + http: ^0.13.0 + plugin_platform_interface: ">=1.0.0 <3.0.0" + cross_file: ^0.3.0 dev_dependencies: - test: ^1.15.0 + test: ^1.16.3 flutter_test: sdk: flutter - mockito: ^5.0.0-nullsafety.5 - pedantic: ^1.8.0 + pedantic: ^1.10.0 environment: - sdk: '>=2.12.0-0 <3.0.0' - flutter: ">=1.9.1+hotfix.4" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" diff --git a/packages/file_selector/file_selector_platform_interface/test/file_selector_platform_interface_test.dart b/packages/file_selector/file_selector_platform_interface/test/file_selector_platform_interface_test.dart index 6809cee66963..56f6ae91bf28 100644 --- a/packages/file_selector/file_selector_platform_interface/test/file_selector_platform_interface_test.dart +++ b/packages/file_selector/file_selector_platform_interface/test/file_selector_platform_interface_test.dart @@ -2,9 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:mockito/mockito.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; import 'package:file_selector_platform_interface/src/method_channel/method_channel_file_selector.dart'; @@ -16,28 +14,10 @@ void main() { isInstanceOf()); }); - test('Cannot be implemented with `implements`', () { - expect(() { - FileSelectorPlatform.instance = ImplementsFileSelectorPlatform(); - }, throwsA(isInstanceOf())); - }); - - test('Can be mocked with `implements`', () { - final FileSelectorPlatformMock mock = FileSelectorPlatformMock(); - FileSelectorPlatform.instance = mock; - }); - test('Can be extended', () { FileSelectorPlatform.instance = ExtendsFileSelectorPlatform(); }); }); } -class FileSelectorPlatformMock extends Mock - with MockPlatformInterfaceMixin - implements FileSelectorPlatform {} - -class ImplementsFileSelectorPlatform extends Mock - implements FileSelectorPlatform {} - class ExtendsFileSelectorPlatform extends FileSelectorPlatform {} From af50af79f0b546b7848a0343cc3dcbc0d346569b Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 22 Feb 2021 18:41:03 -0800 Subject: [PATCH 0188/1565] [connectivity] null safety stable release (#3596) --- packages/connectivity/connectivity/CHANGELOG.md | 14 ++------------ .../connectivity/example/pubspec.yaml | 6 +++--- packages/connectivity/connectivity/pubspec.yaml | 17 ++++++++--------- .../connectivity/test/connectivity_test.dart | 4 ++-- 4 files changed, 15 insertions(+), 26 deletions(-) diff --git a/packages/connectivity/connectivity/CHANGELOG.md b/packages/connectivity/connectivity/CHANGELOG.md index a1d0231a5bd4..c4566ae73fd0 100644 --- a/packages/connectivity/connectivity/CHANGELOG.md +++ b/packages/connectivity/connectivity/CHANGELOG.md @@ -1,19 +1,9 @@ -## 3.0.0-nullsafety.3 +## 3.0.0 +* Migrate to null safety. * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) - -## 3.0.0-nullsafety.2 - * Android: Cleanup the NetworkCallback object when a connectivity stream is cancelled -## 3.0.0-nullsafety.1 - -* Bump Dart SDK to support null safety. - -## 3.0.0-nullsafety - -* Migrate to null safety. - ## 2.0.3 * Update Flutter SDK constraint. diff --git a/packages/connectivity/connectivity/example/pubspec.yaml b/packages/connectivity/connectivity/example/pubspec.yaml index b50214619c13..6395dc38c3ae 100644 --- a/packages/connectivity/connectivity/example/pubspec.yaml +++ b/packages/connectivity/connectivity/example/pubspec.yaml @@ -15,14 +15,14 @@ dependencies: dev_dependencies: flutter_driver: sdk: flutter - test: ^1.10.0-nullsafety.1 + test: ^1.16.3 integration_test: path: ../../../integration_test - pedantic: ^1.10.0-nullsafety.1 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/connectivity/connectivity/pubspec.yaml b/packages/connectivity/connectivity/pubspec.yaml index 7ae03553a26c..254e325203d1 100644 --- a/packages/connectivity/connectivity/pubspec.yaml +++ b/packages/connectivity/connectivity/pubspec.yaml @@ -2,7 +2,7 @@ name: connectivity description: Flutter plugin for discovering the state of the network (WiFi & mobile/cellular) connectivity on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity -version: 3.0.0-nullsafety.3 +version: 3.0.0 flutter: plugin: @@ -20,11 +20,11 @@ flutter: dependencies: flutter: sdk: flutter - meta: ^1.0.5 - connectivity_platform_interface: ^2.0.0-nullsafety.1 + meta: ^1.3.0 + connectivity_platform_interface: ^2.0.0 #TODO(cyanglaz): re-endorse the below plugins when they have migrated to nnbd. # https://github.com/flutter/flutter/issues/68669 - connectivity_macos: ^0.2.0-nullsafety + connectivity_macos: ^0.2.0 # connectivity_for_web: ^0.3.0 dev_dependencies: @@ -32,13 +32,12 @@ dev_dependencies: sdk: flutter flutter_driver: sdk: flutter - test: ^1.10.0-nullsafety.1 + test: ^1.16.3 integration_test: path: ../../integration_test - mockito: ^4.1.1 - plugin_platform_interface: ^1.1.0-nullsafety.1 - pedantic: ^1.10.0-nullsafety.1 + plugin_platform_interface: ">=1.0.0 <3.0.0" + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/connectivity/connectivity/test/connectivity_test.dart b/packages/connectivity/connectivity/test/connectivity_test.dart index e83196546cd2..6747c79bb64a 100644 --- a/packages/connectivity/connectivity/test/connectivity_test.dart +++ b/packages/connectivity/connectivity/test/connectivity_test.dart @@ -8,7 +8,7 @@ import 'package:connectivity/connectivity.dart'; import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; -import 'package:mockito/mockito.dart'; +import 'package:test/fake.dart'; const ConnectivityResult kCheckConnectivityResult = ConnectivityResult.wifi; const LocationAuthorizationStatus kRequestLocationResult = @@ -33,7 +33,7 @@ void main() { }); } -class MockConnectivityPlatform extends Mock +class MockConnectivityPlatform extends Fake with MockPlatformInterfaceMixin implements ConnectivityPlatform { Future checkConnectivity() async { From e21952ad3b2a80ce154feca291f6412e5836e765 Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Mon, 22 Feb 2021 19:11:03 -0800 Subject: [PATCH 0189/1565] [video_player_platform_interface] Bump version for NNBD stable (#3578) --- .../CHANGELOG.md | 26 ++--- .../lib/messages.dart | 30 ++--- .../lib/test.dart | 2 +- .../pubspec.yaml | 11 +- .../method_channel_video_player_test.dart | 110 +++++++----------- 5 files changed, 70 insertions(+), 109 deletions(-) diff --git a/packages/video_player/video_player_platform_interface/CHANGELOG.md b/packages/video_player/video_player_platform_interface/CHANGELOG.md index 7b223f4d958c..d0c59bd05023 100644 --- a/packages/video_player/video_player_platform_interface/CHANGELOG.md +++ b/packages/video_player/video_player_platform_interface/CHANGELOG.md @@ -1,27 +1,15 @@ -## 4.0.0-nullsafety.1 +## 4.0.0 +* **Breaking Changes**: + * Migrate to null-safety + * Update to latest Pigeon. This includes a breaking change to how the test logic is exposed. * Add note about the `mixWithOthers` option being ignored on the web. - -## 4.0.0-nullsafety.0 - -* Update to latest Pigeon. - This includes a breaking change to how the test logic is exposed. - -## 3.0.0-nullsafety.3 - -* `messages.dart` sets Dart `2.12`. - -## 3.0.0-nullsafety.2 - -* Bump Dart SDK to support null safety. - -## 3.0.0-nullsafety.1 - * Make DataSource's `uri` parameter nullable. +* `messages.dart` sets Dart `2.12`. -## 3.0.0-nullsafety +## 3.0.0 -* Migrate to null safety. +* Version 3 only was published as nullsafety "previews". ## 2.2.1 diff --git a/packages/video_player/video_player_platform_interface/lib/messages.dart b/packages/video_player/video_player_platform_interface/lib/messages.dart index 3f2d78ef9ed5..dc5237f2e151 100644 --- a/packages/video_player/video_player_platform_interface/lib/messages.dart +++ b/packages/video_player/video_player_platform_interface/lib/messages.dart @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v0.1.19), do not edit directly. +// 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 @@ -18,7 +18,7 @@ class TextureMessage { static TextureMessage decode(Object message) { final Map pigeonMap = message as Map; - return TextureMessage()..textureId = pigeonMap['textureId'] as int; + return TextureMessage()..textureId = pigeonMap['textureId'] as int?; } } @@ -40,10 +40,10 @@ class CreateMessage { static CreateMessage decode(Object message) { final Map pigeonMap = message as Map; return CreateMessage() - ..asset = pigeonMap['asset'] as String - ..uri = pigeonMap['uri'] as String - ..packageName = pigeonMap['packageName'] as String - ..formatHint = pigeonMap['formatHint'] as String; + ..asset = pigeonMap['asset'] as String? + ..uri = pigeonMap['uri'] as String? + ..packageName = pigeonMap['packageName'] as String? + ..formatHint = pigeonMap['formatHint'] as String?; } } @@ -61,8 +61,8 @@ class LoopingMessage { static LoopingMessage decode(Object message) { final Map pigeonMap = message as Map; return LoopingMessage() - ..textureId = pigeonMap['textureId'] as int - ..isLooping = pigeonMap['isLooping'] as bool; + ..textureId = pigeonMap['textureId'] as int? + ..isLooping = pigeonMap['isLooping'] as bool?; } } @@ -80,8 +80,8 @@ class VolumeMessage { static VolumeMessage decode(Object message) { final Map pigeonMap = message as Map; return VolumeMessage() - ..textureId = pigeonMap['textureId'] as int - ..volume = pigeonMap['volume'] as double; + ..textureId = pigeonMap['textureId'] as int? + ..volume = pigeonMap['volume'] as double?; } } @@ -99,8 +99,8 @@ class PlaybackSpeedMessage { static PlaybackSpeedMessage decode(Object message) { final Map pigeonMap = message as Map; return PlaybackSpeedMessage() - ..textureId = pigeonMap['textureId'] as int - ..speed = pigeonMap['speed'] as double; + ..textureId = pigeonMap['textureId'] as int? + ..speed = pigeonMap['speed'] as double?; } } @@ -118,8 +118,8 @@ class PositionMessage { static PositionMessage decode(Object message) { final Map pigeonMap = message as Map; return PositionMessage() - ..textureId = pigeonMap['textureId'] as int - ..position = pigeonMap['position'] as int; + ..textureId = pigeonMap['textureId'] as int? + ..position = pigeonMap['position'] as int?; } } @@ -135,7 +135,7 @@ class MixWithOthersMessage { static MixWithOthersMessage decode(Object message) { final Map pigeonMap = message as Map; return MixWithOthersMessage() - ..mixWithOthers = pigeonMap['mixWithOthers'] as bool; + ..mixWithOthers = pigeonMap['mixWithOthers'] as bool?; } } diff --git a/packages/video_player/video_player_platform_interface/lib/test.dart b/packages/video_player/video_player_platform_interface/lib/test.dart index 538e9526b111..457a838e8d24 100644 --- a/packages/video_player/video_player_platform_interface/lib/test.dart +++ b/packages/video_player/video_player_platform_interface/lib/test.dart @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v0.1.19), do not edit directly. +// 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 diff --git a/packages/video_player/video_player_platform_interface/pubspec.yaml b/packages/video_player/video_player_platform_interface/pubspec.yaml index ed16ea1033fa..c85f483d041f 100644 --- a/packages/video_player/video_player_platform_interface/pubspec.yaml +++ b/packages/video_player/video_player_platform_interface/pubspec.yaml @@ -3,19 +3,18 @@ description: A common platform interface for the video_player plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 4.0.0-nullsafety.1 +version: 4.0.0 dependencies: flutter: sdk: flutter - meta: ^1.3.0-nullsafety.3 + meta: ^1.3.0 flutter_test: sdk: flutter dev_dependencies: - mockito: ^4.1.1 - pedantic: ^1.10.0-nullsafety.1 + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.10.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" diff --git a/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart b/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart index 669fd2839897..fae4b746bf05 100644 --- a/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart +++ b/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart @@ -2,14 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(egarciad): Remove once Mockito is migrated to null safety. -// @dart = 2.9 - import 'dart:ui'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; import 'package:video_player_platform_interface/messages.dart'; import 'package:video_player_platform_interface/method_channel_video_player.dart'; import 'package:video_player_platform_interface/test.dart'; @@ -17,13 +13,13 @@ import 'package:video_player_platform_interface/video_player_platform_interface. class _ApiLogger implements TestHostVideoPlayerApi { final List log = []; - TextureMessage textureMessage; - CreateMessage createMessage; - PositionMessage positionMessage; - LoopingMessage loopingMessage; - VolumeMessage volumeMessage; - PlaybackSpeedMessage playbackSpeedMessage; - MixWithOthersMessage mixWithOthersMessage; + TextureMessage? textureMessage; + CreateMessage? createMessage; + PositionMessage? positionMessage; + LoopingMessage? loopingMessage; + VolumeMessage? volumeMessage; + PlaybackSpeedMessage? playbackSpeedMessage; + MixWithOthersMessage? mixWithOthersMessage; @override TextureMessage create(CreateMessage arg) { @@ -101,28 +97,11 @@ void main() { expect(VideoPlayerPlatform.instance, isInstanceOf()); }); - - test('Cannot be implemented with `implements`', () { - expect(() { - VideoPlayerPlatform.instance = ImplementsVideoPlayerPlatform(); - }, throwsA(isInstanceOf())); - }); - - test('Can be mocked with `implements`', () { - final ImplementsVideoPlayerPlatform mock = - ImplementsVideoPlayerPlatform(); - when(mock.isMock).thenReturn(true); - VideoPlayerPlatform.instance = mock; - }); - - test('Can be extended', () { - VideoPlayerPlatform.instance = ExtendsVideoPlayerPlatform(); - }); }); group('$MethodChannelVideoPlayer', () { final MethodChannelVideoPlayer player = MethodChannelVideoPlayer(); - _ApiLogger log; + late _ApiLogger log; setUp(() { log = _ApiLogger(); @@ -140,108 +119,108 @@ void main() { test('dispose', () async { await player.dispose(1); expect(log.log.last, 'dispose'); - expect(log.textureMessage.textureId, 1); + expect(log.textureMessage?.textureId, 1); }); test('create with asset', () async { - final int textureId = await player.create(DataSource( + final int? textureId = await player.create(DataSource( sourceType: DataSourceType.asset, asset: 'someAsset', package: 'somePackage', )); expect(log.log.last, 'create'); - expect(log.createMessage.asset, 'someAsset'); - expect(log.createMessage.packageName, 'somePackage'); + expect(log.createMessage?.asset, 'someAsset'); + expect(log.createMessage?.packageName, 'somePackage'); expect(textureId, 3); }); test('create with network', () async { - final int textureId = await player.create(DataSource( + final int? textureId = await player.create(DataSource( sourceType: DataSourceType.network, uri: 'someUri', formatHint: VideoFormat.dash, )); expect(log.log.last, 'create'); - expect(log.createMessage.uri, 'someUri'); - expect(log.createMessage.formatHint, 'dash'); + expect(log.createMessage?.uri, 'someUri'); + expect(log.createMessage?.formatHint, 'dash'); expect(textureId, 3); }); test('create with file', () async { - final int textureId = await player.create(DataSource( + final int? textureId = await player.create(DataSource( sourceType: DataSourceType.file, uri: 'someUri', )); expect(log.log.last, 'create'); - expect(log.createMessage.uri, 'someUri'); + expect(log.createMessage?.uri, 'someUri'); expect(textureId, 3); }); test('setLooping', () async { await player.setLooping(1, true); expect(log.log.last, 'setLooping'); - expect(log.loopingMessage.textureId, 1); - expect(log.loopingMessage.isLooping, true); + expect(log.loopingMessage?.textureId, 1); + expect(log.loopingMessage?.isLooping, true); }); test('play', () async { await player.play(1); expect(log.log.last, 'play'); - expect(log.textureMessage.textureId, 1); + expect(log.textureMessage?.textureId, 1); }); test('pause', () async { await player.pause(1); expect(log.log.last, 'pause'); - expect(log.textureMessage.textureId, 1); + expect(log.textureMessage?.textureId, 1); }); test('setMixWithOthers', () async { await player.setMixWithOthers(true); expect(log.log.last, 'setMixWithOthers'); - expect(log.mixWithOthersMessage.mixWithOthers, true); + expect(log.mixWithOthersMessage?.mixWithOthers, true); await player.setMixWithOthers(false); expect(log.log.last, 'setMixWithOthers'); - expect(log.mixWithOthersMessage.mixWithOthers, false); + expect(log.mixWithOthersMessage?.mixWithOthers, false); }); test('setVolume', () async { await player.setVolume(1, 0.7); expect(log.log.last, 'setVolume'); - expect(log.volumeMessage.textureId, 1); - expect(log.volumeMessage.volume, 0.7); + expect(log.volumeMessage?.textureId, 1); + expect(log.volumeMessage?.volume, 0.7); }); test('setPlaybackSpeed', () async { await player.setPlaybackSpeed(1, 1.5); expect(log.log.last, 'setPlaybackSpeed'); - expect(log.playbackSpeedMessage.textureId, 1); - expect(log.playbackSpeedMessage.speed, 1.5); + expect(log.playbackSpeedMessage?.textureId, 1); + expect(log.playbackSpeedMessage?.speed, 1.5); }); test('seekTo', () async { await player.seekTo(1, const Duration(milliseconds: 12345)); expect(log.log.last, 'seekTo'); - expect(log.positionMessage.textureId, 1); - expect(log.positionMessage.position, 12345); + expect(log.positionMessage?.textureId, 1); + expect(log.positionMessage?.position, 12345); }); test('getPosition', () async { final Duration position = await player.getPosition(1); expect(log.log.last, 'position'); - expect(log.textureMessage.textureId, 1); + expect(log.textureMessage?.textureId, 1); expect(position, const Duration(milliseconds: 234)); }); test('videoEventsFor', () async { - ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler( + ServicesBinding.instance?.defaultBinaryMessenger.setMockMessageHandler( "flutter.io/videoPlayer/videoEvents123", - (ByteData message) async { + (ByteData? message) async { final MethodCall methodCall = const StandardMethodCodec().decodeMethodCall(message); if (methodCall.method == 'listen') { - await ServicesBinding.instance.defaultBinaryMessenger + await ServicesBinding.instance?.defaultBinaryMessenger .handlePlatformMessage( "flutter.io/videoPlayer/videoEvents123", const StandardMethodCodec() @@ -251,18 +230,18 @@ void main() { 'width': 1920, 'height': 1080, }), - (ByteData data) {}); + (ByteData? data) {}); - await ServicesBinding.instance.defaultBinaryMessenger + await ServicesBinding.instance?.defaultBinaryMessenger .handlePlatformMessage( "flutter.io/videoPlayer/videoEvents123", const StandardMethodCodec() .encodeSuccessEnvelope({ 'event': 'completed', }), - (ByteData data) {}); + (ByteData? data) {}); - await ServicesBinding.instance.defaultBinaryMessenger + await ServicesBinding.instance?.defaultBinaryMessenger .handlePlatformMessage( "flutter.io/videoPlayer/videoEvents123", const StandardMethodCodec() @@ -273,25 +252,25 @@ void main() { [1235, 4000], ], }), - (ByteData data) {}); + (ByteData? data) {}); - await ServicesBinding.instance.defaultBinaryMessenger + await ServicesBinding.instance?.defaultBinaryMessenger .handlePlatformMessage( "flutter.io/videoPlayer/videoEvents123", const StandardMethodCodec() .encodeSuccessEnvelope({ 'event': 'bufferingStart', }), - (ByteData data) {}); + (ByteData? data) {}); - await ServicesBinding.instance.defaultBinaryMessenger + await ServicesBinding.instance?.defaultBinaryMessenger .handlePlatformMessage( "flutter.io/videoPlayer/videoEvents123", const StandardMethodCodec() .encodeSuccessEnvelope({ 'event': 'bufferingEnd', }), - (ByteData data) {}); + (ByteData? data) {}); return const StandardMethodCodec().encodeSuccessEnvelope(null); } else if (methodCall.method == 'cancel') { @@ -328,8 +307,3 @@ void main() { }); }); } - -class ImplementsVideoPlayerPlatform extends Mock - implements VideoPlayerPlatform {} - -class ExtendsVideoPlayerPlatform extends VideoPlayerPlatform {} From f47dbdf372feefea9268f3c03d9b2b4cd3ae2626 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Mon, 22 Feb 2021 20:11:21 -0800 Subject: [PATCH 0190/1565] [android_alarm_manager] Bump version for NNBD stable (#3608) --- packages/android_alarm_manager/CHANGELOG.md | 2 +- packages/android_alarm_manager/example/pubspec.yaml | 10 +++++----- packages/android_alarm_manager/pubspec.yaml | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/android_alarm_manager/CHANGELOG.md b/packages/android_alarm_manager/CHANGELOG.md index b06f23c45a30..10ad02a5ac43 100644 --- a/packages/android_alarm_manager/CHANGELOG.md +++ b/packages/android_alarm_manager/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.0.0-nullsafety +## 2.0.0 * Migrate to null safety. diff --git a/packages/android_alarm_manager/example/pubspec.yaml b/packages/android_alarm_manager/example/pubspec.yaml index 029a60493193..b92f45c73d35 100644 --- a/packages/android_alarm_manager/example/pubspec.yaml +++ b/packages/android_alarm_manager/example/pubspec.yaml @@ -11,10 +11,10 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - shared_preferences: ^2.0.0-nullsafety + shared_preferences: ^2.0.0 integration_test: path: ../../integration_test - path_provider: ^2.0.0-nullsafety + path_provider: ^2.0.0 dev_dependencies: espresso: ^0.0.1+3 @@ -22,11 +22,11 @@ dev_dependencies: sdk: flutter flutter_test: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: '>=2.12.0-0 <3.0.0' - flutter: ">=1.12.13+hotfix.5" + sdk: '>=2.12.0-259.9.beta <3.0.0' + flutter: ">=1.20.0" diff --git a/packages/android_alarm_manager/pubspec.yaml b/packages/android_alarm_manager/pubspec.yaml index ab1937242859..3934de6f06fe 100644 --- a/packages/android_alarm_manager/pubspec.yaml +++ b/packages/android_alarm_manager/pubspec.yaml @@ -1,7 +1,7 @@ name: android_alarm_manager description: Flutter plugin for accessing the Android AlarmManager service, and running Dart code in the background when alarms fire. -version: 2.0.0-nullsafety +version: 2.0.0 homepage: https://github.com/flutter/plugins/tree/master/packages/android_alarm_manager dependencies: @@ -11,7 +11,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: plugin: @@ -21,5 +21,5 @@ flutter: pluginClass: AndroidAlarmManagerPlugin environment: - sdk: '>=2.12.0-0 <3.0.0' - flutter: ">=1.12.13+hotfix.5" + sdk: '>=2.12.0-259.9.beta <3.0.0' + flutter: ">=1.20.0" From f081633ecf0e419755f6008b42de18a91ec2d31d Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Tue, 23 Feb 2021 10:25:48 -0800 Subject: [PATCH 0191/1565] [local_auth] Bump version for NNBD stable (#3615) --- packages/local_auth/CHANGELOG.md | 29 ++++++------------------ packages/local_auth/example/pubspec.yaml | 4 ++-- packages/local_auth/pubspec.yaml | 14 ++++++------ 3 files changed, 16 insertions(+), 31 deletions(-) diff --git a/packages/local_auth/CHANGELOG.md b/packages/local_auth/CHANGELOG.md index 152ffb603e10..b4d58395295f 100644 --- a/packages/local_auth/CHANGELOG.md +++ b/packages/local_auth/CHANGELOG.md @@ -1,32 +1,17 @@ -## 1.1.0-nullsafety +## 1.1.0 -* Allow pin, passcode, and pattern authentication with `authenticate` method +* Migrate to null safety. +* Allow pin, passcode, and pattern authentication with `authenticate` method. +* Fix incorrect error handling switch case fallthrough. +* Update README for Android Integration. +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. +* Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)). * **Breaking change**. Parameter names refactored to use the generic `biometric` prefix in place of `fingerprint` in the `AndroidAuthMessages` class * `fingerprintHint` is now `biometricHint` * `fingerprintNotRecognized`is now `biometricNotRecognized` * `fingerprintSuccess`is now `biometricSuccess` * `fingerprintRequiredTitle` is now `biometricRequiredTitle` -## 1.0.0-nullsafety.4 - -* Fix incorrect error handling switch case fallthrough. - -## 1.0.0-nullsafety.3 - -* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. - -## 1.0.0-nullsafety.2 - -* Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) - -## 1.0.0-nullsafety.1 - -* Update README for Android Integration. - -## 1.0.0-nullsafety - -* Migrate to null safety. - ## 0.6.3+5 * Update Flutter SDK constraint. diff --git a/packages/local_auth/example/pubspec.yaml b/packages/local_auth/example/pubspec.yaml index 364f604a31d8..d50940f6b63c 100644 --- a/packages/local_auth/example/pubspec.yaml +++ b/packages/local_auth/example/pubspec.yaml @@ -17,11 +17,11 @@ dev_dependencies: path: ../../integration_test flutter_driver: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/local_auth/pubspec.yaml b/packages/local_auth/pubspec.yaml index 79870cc57da2..337006aa196f 100644 --- a/packages/local_auth/pubspec.yaml +++ b/packages/local_auth/pubspec.yaml @@ -2,7 +2,7 @@ name: local_auth description: Flutter plugin for Android and iOS devices to allow local authentication via fingerprint, touch ID, face ID, passcode, pin, or pattern. homepage: https://github.com/flutter/plugins/tree/master/packages/local_auth -version: 1.0.0-nullsafety.4 +version: 1.1.0 flutter: plugin: @@ -16,10 +16,10 @@ flutter: dependencies: flutter: sdk: flutter - meta: ^1.3.0-nullsafety.3 - intl: ^0.17.0-nullsafety.2 - platform: ^3.0.0-nullsafety.4 - flutter_plugin_android_lifecycle: ^2.0.0-nullsafety + meta: ^1.3.0 + intl: ^0.17.0 + platform: ^3.0.0 + flutter_plugin_android_lifecycle: ^2.0.0 dev_dependencies: integration_test: @@ -28,8 +28,8 @@ dev_dependencies: sdk: flutter flutter_test: sdk: flutter - pedantic: ^1.10.0-nullsafety.1 + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" From bba55439a7800f5fec39f764855eb5482a13401f Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 23 Feb 2021 10:41:03 -0800 Subject: [PATCH 0192/1565] quick action stable (#3618) --- packages/quick_actions/CHANGELOG.md | 2 +- .../example/integration_test/quick_actions_test.dart | 1 + packages/quick_actions/example/lib/main.dart | 2 +- packages/quick_actions/example/pubspec.yaml | 4 ++-- .../example/test_driver/integration_test.dart | 1 + packages/quick_actions/pubspec.yaml | 11 +++++------ 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/quick_actions/CHANGELOG.md b/packages/quick_actions/CHANGELOG.md index 774ccac1bb44..1b6de34ca375 100644 --- a/packages/quick_actions/CHANGELOG.md +++ b/packages/quick_actions/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.5.0-nullsafety +## 0.5.0 * Migrate to null safety. diff --git a/packages/quick_actions/example/integration_test/quick_actions_test.dart b/packages/quick_actions/example/integration_test/quick_actions_test.dart index 03ecfe491d93..43822c9e8b2b 100644 --- a/packages/quick_actions/example/integration_test/quick_actions_test.dart +++ b/packages/quick_actions/example/integration_test/quick_actions_test.dart @@ -2,6 +2,7 @@ // 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:quick_actions/quick_actions.dart'; diff --git a/packages/quick_actions/example/lib/main.dart b/packages/quick_actions/example/lib/main.dart index fc289810ea24..a7e9d5e4c031 100644 --- a/packages/quick_actions/example/lib/main.dart +++ b/packages/quick_actions/example/lib/main.dart @@ -25,7 +25,7 @@ class MyApp extends StatelessWidget { } class MyHomePage extends StatefulWidget { - MyHomePage({Key key}) : super(key: key); + MyHomePage({Key? key}) : super(key: key); @override _MyHomePageState createState() => _MyHomePageState(); diff --git a/packages/quick_actions/example/pubspec.yaml b/packages/quick_actions/example/pubspec.yaml index deba400ccd9f..ded88685c41b 100644 --- a/packages/quick_actions/example/pubspec.yaml +++ b/packages/quick_actions/example/pubspec.yaml @@ -17,11 +17,11 @@ dev_dependencies: sdk: flutter integration_test: path: ../../integration_test - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.0.0-dev.28.0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.9.1+hotfix.2" diff --git a/packages/quick_actions/example/test_driver/integration_test.dart b/packages/quick_actions/example/test_driver/integration_test.dart index 7a2c21338786..0352d4aaeb2d 100644 --- a/packages/quick_actions/example/test_driver/integration_test.dart +++ b/packages/quick_actions/example/test_driver/integration_test.dart @@ -2,6 +2,7 @@ // 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/quick_actions/pubspec.yaml b/packages/quick_actions/pubspec.yaml index 46bc53e63ce6..dc500e2516e1 100644 --- a/packages/quick_actions/pubspec.yaml +++ b/packages/quick_actions/pubspec.yaml @@ -2,7 +2,7 @@ name: quick_actions description: Flutter plugin for creating shortcuts on home screen, also known as Quick Actions on iOS and App Shortcuts on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/quick_actions -version: 0.5.0-nullsafety +version: 0.5.0 flutter: plugin: @@ -16,17 +16,16 @@ flutter: dependencies: flutter: sdk: flutter - meta: ^1.3.0-nullsafety + meta: ^1.3.0 dev_dependencies: - test: ^1.16.0-nullsafety - mockito: ^5.0.0-nullsafety.0 + test: ^1.16.3 flutter_test: sdk: flutter integration_test: path: ../integration_test - pedantic: ^1.10.0-nullsafety + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" From 082efa88b13533f834784c1975520fadecdf8ab3 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Tue, 23 Feb 2021 10:51:05 -0800 Subject: [PATCH 0193/1565] [ios_platform_images] Bump version for stable NNBD (#3616) --- packages/ios_platform_images/CHANGELOG.md | 2 +- .../ios/Runner.xcodeproj/project.pbxproj | 6 +-- .../contents.xcworkspacedata | 10 ++++ .../ios_platform_images/example/pubspec.yaml | 47 ++----------------- packages/ios_platform_images/pubspec.yaml | 43 ++--------------- 5 files changed, 20 insertions(+), 88 deletions(-) create mode 100644 packages/ios_platform_images/example/ios/Runner.xcworkspace/contents.xcworkspacedata diff --git a/packages/ios_platform_images/CHANGELOG.md b/packages/ios_platform_images/CHANGELOG.md index bae98440f668..bb87b7d6ff81 100644 --- a/packages/ios_platform_images/CHANGELOG.md +++ b/packages/ios_platform_images/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.2.0-nullsafety +## 0.2.0 * Migrate to null safety. diff --git a/packages/ios_platform_images/example/ios/Runner.xcodeproj/project.pbxproj b/packages/ios_platform_images/example/ios/Runner.xcodeproj/project.pbxproj index 03bbe666a0ed..ba0b25c0015b 100644 --- a/packages/ios_platform_images/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/ios_platform_images/example/ios/Runner.xcodeproj/project.pbxproj @@ -229,9 +229,12 @@ files = ( ); inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/ios_platform_images/ios_platform_images.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ios_platform_images.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -310,7 +313,6 @@ /* Begin XCBuildConfiguration section */ 249021D3217E4FDB00AE95B9 /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -387,7 +389,6 @@ }; 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -443,7 +444,6 @@ }; 97C147041CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; diff --git a/packages/ios_platform_images/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/ios_platform_images/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..21a3cc14c74e --- /dev/null +++ b/packages/ios_platform_images/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/packages/ios_platform_images/example/pubspec.yaml b/packages/ios_platform_images/example/pubspec.yaml index 7802a2b0fe0a..552790ea74af 100644 --- a/packages/ios_platform_images/example/pubspec.yaml +++ b/packages/ios_platform_images/example/pubspec.yaml @@ -4,15 +4,13 @@ publish_to: 'none' homepage: https://github.com/flutter/plugins/tree/master/packages/ios_platform_images/ios_platform_images environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" dependencies: flutter: sdk: flutter - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.2 + cupertino_icons: ^1.0.2 dev_dependencies: flutter_test: @@ -24,46 +22,7 @@ dev_dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - pedantic: ^1.8.0 + pedantic: ^1.10.0 -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/packages/ios_platform_images/pubspec.yaml b/packages/ios_platform_images/pubspec.yaml index 6284f7c96871..820542bcc362 100644 --- a/packages/ios_platform_images/pubspec.yaml +++ b/packages/ios_platform_images/pubspec.yaml @@ -1,10 +1,10 @@ name: ios_platform_images description: A plugin to share images between Flutter and iOS in add-to-app setups. -version: 0.2.0-nullsafety +version: 0.2.0 homepage: https://github.com/flutter/plugins/tree/master/packages/ios_platform_images/ios_platform_images environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" dependencies: @@ -14,47 +14,10 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.10.0-nullsafety + pedantic: ^1.10.0 -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. flutter: - # This section identifies this Flutter project as a plugin project. - # The androidPackage and pluginClass identifiers should not ordinarily - # be modified. They are used by the tooling to maintain consistency when - # adding or updating assets for this project. plugin: platforms: ios: pluginClass: IosPlatformImagesPlugin - # To add assets to your plugin package, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # - # For details regarding assets in packages, see - # https://flutter.dev/assets-and-images/#from-packages - # - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # To add custom fonts to your plugin package, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts in packages, see - # https://flutter.dev/custom-fonts/#from-packages From b45875f01ece18dc1d1b01697c6d067eba5a7f8e Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Tue, 23 Feb 2021 11:31:03 -0800 Subject: [PATCH 0194/1565] [espresso] Update SDK requirement for null-safety (#3614) --- packages/espresso/CHANGELOG.md | 4 +++ packages/espresso/example/lib/main.dart | 2 +- packages/espresso/example/pubspec.yaml | 48 ++----------------------- packages/espresso/pubspec.yaml | 8 ++--- script/nnbd_plugins.sh | 1 + 5 files changed, 13 insertions(+), 50 deletions(-) diff --git a/packages/espresso/CHANGELOG.md b/packages/espresso/CHANGELOG.md index fe43202b7654..454736454cdf 100644 --- a/packages/espresso/CHANGELOG.md +++ b/packages/espresso/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.0 + +* Update SDK requirement for null-safety compatibility. + ## 0.0.1+9 * Update Flutter SDK constraint. diff --git a/packages/espresso/example/lib/main.dart b/packages/espresso/example/lib/main.dart index c74423f507e8..958d26a0c149 100644 --- a/packages/espresso/example/lib/main.dart +++ b/packages/espresso/example/lib/main.dart @@ -27,7 +27,7 @@ class MyApp extends StatelessWidget { } class _MyHomePage extends StatefulWidget { - _MyHomePage({Key key, this.title}) : super(key: key); + _MyHomePage({Key? key, required this.title}) : super(key: key); // This widget is the home page of your application. It is stateful, meaning // that it has a State object (defined below) that contains fields that affect diff --git a/packages/espresso/example/pubspec.yaml b/packages/espresso/example/pubspec.yaml index 4854d85cb281..6e824acb4080 100644 --- a/packages/espresso/example/pubspec.yaml +++ b/packages/espresso/example/pubspec.yaml @@ -3,22 +3,19 @@ description: Demonstrates how to use the espresso plugin. publish_to: 'none' environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" dependencies: flutter: sdk: flutter - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.2 - dev_dependencies: flutter_test: sdk: flutter flutter_driver: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0 espresso: # When depending on this package from a real application you should use: @@ -28,44 +25,5 @@ dev_dependencies: # the parent directory to use the current plugin's version. path: ../ -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/packages/espresso/pubspec.yaml b/packages/espresso/pubspec.yaml index e79c46e73e40..90b485fdc48d 100644 --- a/packages/espresso/pubspec.yaml +++ b/packages/espresso/pubspec.yaml @@ -1,11 +1,11 @@ name: espresso description: Java classes for testing Flutter apps using Espresso. -version: 0.0.1+9 +version: 0.1.0 homepage: https://github.com/flutter/plugins/espresso environment: - sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.10.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" dependencies: flutter: @@ -14,7 +14,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.8.0 + pedantic: ^1.10.0 # The following section is specific to Flutter. flutter: diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index eceb78cc970c..fb5f8eac44e9 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -13,6 +13,7 @@ readonly NNBD_PLUGINS_LIST=( "connectivity" "cross_file" "device_info" + "espresso" "file_selector" "flutter_plugin_android_lifecycle" "flutter_webview" From 34d0aa57f00f7b39bc2a1057c60f1794b86b71b8 Mon Sep 17 00:00:00 2001 From: Vishnu Agarwal <53317018+vishnuagbly@users.noreply.github.com> Date: Wed, 24 Feb 2021 01:07:39 +0530 Subject: [PATCH 0195/1565] [google_maps_flutter] fixed a small bug in example app. (#3590) in _onMarkerTapped function we were changing markers[markerId] to defaultMarker and than again markers[markerId] to hueGreen marker, while instead we should have changed markers[selectedMarker] to defaultMarker first instead of markers[markerId] --- .../google_maps_flutter/google_maps_flutter/CHANGELOG.md | 4 ++++ .../google_maps_flutter/example/lib/place_marker.dart | 7 ++++--- .../google_maps_flutter/google_maps_flutter/pubspec.yaml | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index 549aa4e06f3c..ef64aac534a5 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.0-nullsafety.1 + +* Fix in example app to properly change marker icon. + ## 2.0.0-nullsafety * Migrate to null-safety diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart index 576808c38a5e..c650ca34c1b0 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart @@ -53,10 +53,11 @@ class PlaceMarkerBodyState extends State { final Marker? tappedMarker = markers[markerId]; if (tappedMarker != null) { setState(() { - if (markers.containsKey(markerId)) { - final Marker resetOld = markers[markerId]! + final MarkerId? previousMarkerId = selectedMarker; + if (previousMarkerId != null && markers.containsKey(previousMarkerId)) { + final Marker resetOld = markers[previousMarkerId]! .copyWith(iconParam: BitmapDescriptor.defaultMarker); - markers[markerId] = resetOld; + markers[previousMarkerId] = resetOld; } selectedMarker = markerId; final Marker newMarker = tappedMarker.copyWith( diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index 8e9ab62d5f38..fbab15231b25 100644 --- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: google_maps_flutter description: A Flutter plugin for integrating Google Maps in iOS and Android applications. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter -version: 2.0.0-nullsafety +version: 2.0.0-nullsafety.1 dependencies: flutter: From 36a14570ae462e9f448dc565a0b33c286f5b2742 Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Tue, 23 Feb 2021 12:06:42 -0800 Subject: [PATCH 0196/1565] [google_sign_in_web] Ignore analyzer checks in generated files. (#3622) These checks are currently breaking the engine/framework rolls. --- .../google_sign_in_web/lib/src/generated/gapi.dart | 2 ++ .../google_sign_in_web/lib/src/generated/gapiauth2.dart | 2 ++ 2 files changed, 4 insertions(+) diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart index 97ae9b48dc1b..95f07490d3e6 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.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. +// ignore_for_file: public_member_api_docs, unused_element + @JS() library gapi; diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart index ed7a2816d55e..8c8d23378e3e 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.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. +// ignore_for_file: public_member_api_docs, unused_element + @JS() library gapiauth2; From 7413abf088fa49703034e68fdf87215ddef0a7a3 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Tue, 23 Feb 2021 12:17:06 -0800 Subject: [PATCH 0197/1565] [google_sign_in] Bump platform interface version for NNBD stable (#3617) --- .../google_sign_in_platform_interface/CHANGELOG.md | 4 ++-- .../google_sign_in_platform_interface/pubspec.yaml | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md b/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md index f01d03080af7..dd6c22fbef29 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md @@ -1,6 +1,6 @@ -## 2.0.0-nullsafety +## 2.0.0 -* Migration to nnbd. +* Migrate to null-safety. ## 1.1.3 diff --git a/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml b/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml index 4480debc9ba3..56b4033dcb88 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml @@ -3,20 +3,20 @@ description: A common platform interface for the google_sign_in plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0-nullsafety +version: 2.0.0 dependencies: flutter: sdk: flutter - meta: ^1.3.0-nullsafety.6 - quiver: ^3.0.0-nullsafety.2 + meta: ^1.3.0 + quiver: ^3.0.0 dev_dependencies: flutter_test: sdk: flutter mockito: ^5.0.0-nullsafety.1 - pedantic: ^1.10.0-nullsafety.1 + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" From 73aefe620202349b56a9c4e7487580657b299596 Mon Sep 17 00:00:00 2001 From: Darshan Rander Date: Wed, 24 Feb 2021 02:21:04 +0530 Subject: [PATCH 0198/1565] [shared_preferences] Removed deprecated AsyncTask API (#3481) --- .../shared_preferences/CHANGELOG.md | 4 +++ .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../MethodCallHandlerImpl.java | 34 +++++++++++++------ .../shared_preferences/pubspec.yaml | 2 +- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/packages/shared_preferences/shared_preferences/CHANGELOG.md b/packages/shared_preferences/shared_preferences/CHANGELOG.md index 2e05c8bbff05..74555f59c27f 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +* Removed deprecated [AsyncTask](https://developer.android.com/reference/android/os/AsyncTask) was deprecated in API level 30 ([#3481](https://github.com/flutter/plugins/pull/3481)) + ## 2.0.0 * Migrate to null-safety. diff --git a/packages/shared_preferences/shared_preferences/android/gradle/wrapper/gradle-wrapper.properties b/packages/shared_preferences/shared_preferences/android/gradle/wrapper/gradle-wrapper.properties index caf54fa2801c..3c9d0852bfa5 100644 --- a/packages/shared_preferences/shared_preferences/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/shared_preferences/shared_preferences/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip diff --git a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java index 33f2474592fa..f2c0f298578c 100644 --- a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java +++ b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java @@ -6,7 +6,8 @@ import android.content.Context; import android.content.SharedPreferences; -import android.os.AsyncTask; +import android.os.Handler; +import android.os.Looper; import android.util.Base64; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; @@ -21,6 +22,10 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; /** * Implementation of the {@link MethodChannel.MethodCallHandler} for the plugin. It is also @@ -118,17 +123,24 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) { private void commitAsync( final SharedPreferences.Editor editor, final MethodChannel.Result result) { - new AsyncTask() { - @Override - protected Boolean doInBackground(Void... voids) { - return editor.commit(); - } + final ExecutorService executor = + new ThreadPoolExecutor(0, 1, 30L, TimeUnit.SECONDS, new SynchronousQueue()); + final Handler handler = new Handler(Looper.getMainLooper()); - @Override - protected void onPostExecute(Boolean value) { - result.success(value); - } - }.execute(); + executor.execute( + new Runnable() { + @Override + public void run() { + final boolean response = editor.commit(); + handler.post( + new Runnable() { + @Override + public void run() { + result.success(response); + } + }); + } + }); } private List decodeList(String encodedList) throws IOException { diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index 583600d6a78b..1809a979c6f3 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -2,7 +2,7 @@ name: shared_preferences description: Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences -version: 2.0.0 +version: 2.0.1 flutter: plugin: From bc355f1ae386da64ab10a4729d70bee2910f60d8 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 23 Feb 2021 12:52:37 -0800 Subject: [PATCH 0199/1565] [webview_flutter] release null safety to stable(#3619) --- packages/webview_flutter/CHANGELOG.md | 22 ++----------------- packages/webview_flutter/example/pubspec.yaml | 4 ++-- packages/webview_flutter/pubspec.yaml | 6 ++--- 3 files changed, 7 insertions(+), 25 deletions(-) diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index 0a060ef0cf2d..fb448d245127 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,31 +1,13 @@ -## 2.0.0-nullsafety.6 +## 2.0.0 +* Migration to null-safety. * Added support for progress tracking. - -## 2.0.0-nullsafety.5 - * Add section to the wiki explaining how to use Material components. - -## 2.0.0-nullsafety.4 - * Update integration test to workaround an iOS 14 issue with `evaluateJavascript`. - -## 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)) - -## 2.0.0-nullsafety.1 - * Added `allowsInlineMediaPlayback` property. -## 2.0.0-nullsafety - -* Migration to null-safety. - ## 1.0.8 * Update Flutter SDK constraint. diff --git a/packages/webview_flutter/example/pubspec.yaml b/packages/webview_flutter/example/pubspec.yaml index b61b6df590ce..d7688b720f3f 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.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" dependencies: flutter: @@ -22,7 +22,7 @@ dev_dependencies: sdk: flutter integration_test: path: ../../integration_test - pedantic: ^1.8.0 + pedantic: ^1.10.0 flutter: uses-material-design: true diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml index 5d8e512b5aa5..bae19fd8b726 100644 --- a/packages/webview_flutter/pubspec.yaml +++ b/packages/webview_flutter/pubspec.yaml @@ -1,10 +1,10 @@ name: webview_flutter description: A Flutter plugin that provides a WebView widget on Android and iOS. -version: 2.0.0-nullsafety.5 homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter +version: 2.0.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.22.0" dependencies: @@ -16,7 +16,7 @@ dev_dependencies: sdk: flutter flutter_driver: sdk: flutter - pedantic: ^1.10.0-nullsafety.1 + pedantic: ^1.10.0 flutter: plugin: From a2cb89410f1bb244b25ecf2d096486dc7eab1bd4 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 23 Feb 2021 12:58:26 -0800 Subject: [PATCH 0200/1565] [wifi_info_flutter_platform_interface] null safety stable release (#3620) --- .../wifi_info_flutter_platform_interface/CHANGELOG.md | 2 +- .../wifi_info_flutter_platform_interface/pubspec.yaml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/CHANGELOG.md b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/CHANGELOG.md index 043a3d31b68d..cb770cb2d279 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/CHANGELOG.md +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.0.0-nullsafety +## 2.0.0 * Migrate to null safety. diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/pubspec.yaml b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/pubspec.yaml index 1d830f0af5f6..8e2eff392df7 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/pubspec.yaml +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/pubspec.yaml @@ -1,20 +1,20 @@ name: wifi_info_flutter_platform_interface description: A common platform interface for the wifi_info_flutter plugin. -version: 2.0.0-nullsafety +version: 2.0.0 # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes homepage: https://github.com/flutter/plugins/tree/master/packages/wifi_info_flutter/wifi_info_flutter_platform_interface environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.17.0" dependencies: - plugin_platform_interface: ^1.1.0-nullsafety + plugin_platform_interface: ">=1.0.0 <3.0.0" flutter: sdk: flutter dev_dependencies: - pedantic: ^1.10.0-nullsafety + pedantic: ^1.10.0 flutter_test: sdk: flutter From bd886154e54de9001c2ce2ee1180b5378cffdb7a Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Tue, 23 Feb 2021 22:06:03 +0100 Subject: [PATCH 0201/1565] [camera] Fix example from README.md (#3592) --- packages/camera/camera/CHANGELOG.md | 4 ++++ packages/camera/camera/README.md | 11 ++++++----- packages/camera/camera/pubspec.yaml | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 29774748a32b..079aa1685bd5 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.8.0-nullsafety.3 + +* Updates the example code listed in the [README.md](README.md), so it runs without errors when you simply copy/ paste it into a Flutter App. + ## 0.8.0-nullsafety.2 * Solved delay when using the zoom feature on iOS. diff --git a/packages/camera/camera/README.md b/packages/camera/camera/README.md index b9fdd7384297..fb6144face9b 100644 --- a/packages/camera/camera/README.md +++ b/packages/camera/camera/README.md @@ -79,6 +79,7 @@ List cameras; Future main() async { WidgetsFlutterBinding.ensureInitialized(); + cameras = await availableCameras(); runApp(CameraApp()); } @@ -94,7 +95,7 @@ class _CameraAppState extends State { @override void initState() { super.initState(); - controller = CameraController(cameras[0], ResolutionPreset.medium); + controller = CameraController(cameras[0], ResolutionPreset.max); controller.initialize().then((_) { if (!mounted) { return; @@ -114,12 +115,12 @@ class _CameraAppState extends State { if (!controller.value.isInitialized) { return Container(); } - return AspectRatio( - aspectRatio: - controller.value.aspectRatio, - child: CameraPreview(controller)); + return MaterialApp( + home: CameraPreview(controller), + ); } } + ``` For a more elaborate usage example see [here](https://github.com/flutter/plugins/tree/master/packages/camera/camera/example). diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 4b820b8b64cf..2d620505def2 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.8.0-nullsafety.2 +version: 0.8.0-nullsafety.3 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: From 3b4202514f4de3c868345a96b8a384ecc063a6bd Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 23 Feb 2021 14:12:55 -0800 Subject: [PATCH 0202/1565] [device_info_platform_interface] handle null value from method channel (#3609) --- .../lib/device_info_platform_interface.dart | 2 - .../method_channel_device_info.dart | 16 +- .../lib/model/android_device_info.dart | 104 ++++++--- .../lib/model/ios_device_info.dart | 58 +++-- .../test/method_channel_device_info_test.dart | 216 ++++++++++++++++++ 5 files changed, 344 insertions(+), 52 deletions(-) diff --git a/packages/device_info/device_info_platform_interface/lib/device_info_platform_interface.dart b/packages/device_info/device_info_platform_interface/lib/device_info_platform_interface.dart index 808b7adf9dc7..2dd41dcc580f 100644 --- a/packages/device_info/device_info_platform_interface/lib/device_info_platform_interface.dart +++ b/packages/device_info/device_info_platform_interface/lib/device_info_platform_interface.dart @@ -7,10 +7,8 @@ import 'dart:async'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'method_channel/method_channel_device_info.dart'; - import 'model/android_device_info.dart'; import 'model/ios_device_info.dart'; - export 'model/android_device_info.dart'; export 'model/ios_device_info.dart'; diff --git a/packages/device_info/device_info_platform_interface/lib/method_channel/method_channel_device_info.dart b/packages/device_info/device_info_platform_interface/lib/method_channel/method_channel_device_info.dart index 7bd02e97436d..331f718989ce 100644 --- a/packages/device_info/device_info_platform_interface/lib/method_channel/method_channel_device_info.dart +++ b/packages/device_info/device_info_platform_interface/lib/method_channel/method_channel_device_info.dart @@ -1,8 +1,11 @@ +// 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. + import 'dart:async'; import 'package:flutter/services.dart'; import 'package:meta/meta.dart'; - import 'package:device_info_platform_interface/device_info_platform_interface.dart'; /// An implementation of [DeviceInfoPlatform] that uses method channels. @@ -13,16 +16,15 @@ class MethodChannelDeviceInfo extends DeviceInfoPlatform { // Method channel for Android devices Future androidInfo() async { - return AndroidDeviceInfo.fromMap( - (await channel.invokeMethod('getAndroidDeviceInfo')) - .cast(), - ); + return AndroidDeviceInfo.fromMap((await channel + .invokeMapMethod('getAndroidDeviceInfo')) ?? + {}); } // Method channel for iOS devices Future iosInfo() async { return IosDeviceInfo.fromMap( - (await channel.invokeMethod('getIosDeviceInfo')).cast(), - ); + (await channel.invokeMapMethod('getIosDeviceInfo')) ?? + {}); } } diff --git a/packages/device_info/device_info_platform_interface/lib/model/android_device_info.dart b/packages/device_info/device_info_platform_interface/lib/model/android_device_info.dart index 4fb940c3effa..c5210ab10f50 100644 --- a/packages/device_info/device_info_platform_interface/lib/model/android_device_info.dart +++ b/packages/device_info/device_info_platform_interface/lib/model/android_device_info.dart @@ -38,39 +38,63 @@ class AndroidDeviceInfo { final AndroidBuildVersion version; /// The name of the underlying board, like "goldfish". + /// + /// The value is an empty String if it is not available. final String board; /// The system bootloader version number. + /// + /// The value is an empty String if it is not available. final String bootloader; /// The consumer-visible brand with which the product/hardware will be associated, if any. + /// + /// The value is an empty String if it is not available. final String brand; /// The name of the industrial design. + /// + /// The value is an empty String if it is not available. final String device; /// A build ID string meant for displaying to the user. + /// + /// The value is an empty String if it is not available. final String display; /// A string that uniquely identifies this build. + /// + /// The value is an empty String if it is not available. final String fingerprint; /// The name of the hardware (from the kernel command line or /proc). + /// + /// The value is an empty String if it is not available. final String hardware; /// Hostname. + /// + /// The value is an empty String if it is not available. final String host; /// Either a changelist number, or a label like "M4-rc20". + /// + /// The value is an empty String if it is not available. final String id; /// The manufacturer of the product/hardware. + /// + /// The value is an empty String if it is not available. final String manufacturer; /// The end-user-visible name for the end product. + /// + /// The value is an empty String if it is not available. final String model; /// The name of the overall product. + /// + /// The value is an empty String if it is not available. final String product; /// An ordered list of 32 bit ABIs supported by this device. @@ -83,15 +107,23 @@ class AndroidDeviceInfo { final List supportedAbis; /// Comma-separated tags describing the build, like "unsigned,debug". + /// + /// The value is an empty String if it is not available. final String tags; /// The type of build, like "user" or "eng". + /// + /// The value is an empty String if it is not available. final String type; - /// `false` if the application is running in an emulator, `true` otherwise. + /// The value is `true` if the application is running on a physical device. + /// + /// The value is `false` when the application is running on a emulator, or the value is unavailable. final bool isPhysicalDevice; /// The Android hardware device ID that is unique between the device + user and app signing. + /// + /// The value is an empty String if it is not available. final String androidId; /// Describes what features are available on the current device. @@ -113,35 +145,41 @@ class AndroidDeviceInfo { /// Deserializes from the message received from [_kChannel]. static AndroidDeviceInfo fromMap(Map map) { return AndroidDeviceInfo( - version: - AndroidBuildVersion._fromMap(map['version']!.cast()), - board: map['board']!, - bootloader: map['bootloader']!, - brand: map['brand']!, - device: map['device']!, - display: map['display']!, - fingerprint: map['fingerprint']!, - hardware: map['hardware']!, - host: map['host']!, - id: map['id']!, - manufacturer: map['manufacturer']!, - model: map['model']!, - product: map['product']!, - supported32BitAbis: _fromList(map['supported32BitAbis']!), - supported64BitAbis: _fromList(map['supported64BitAbis']!), - supportedAbis: _fromList(map['supportedAbis']!), - tags: map['tags']!, - type: map['type']!, - isPhysicalDevice: map['isPhysicalDevice']!, - androidId: map['androidId']!, - systemFeatures: _fromList(map['systemFeatures']!), + version: AndroidBuildVersion._fromMap(map['version'] != null + ? map['version'].cast() + : {}), + board: map['board'] ?? '', + bootloader: map['bootloader'] ?? '', + brand: map['brand'] ?? '', + device: map['device'] ?? '', + display: map['display'] ?? '', + fingerprint: map['fingerprint'] ?? '', + hardware: map['hardware'] ?? '', + host: map['host'] ?? '', + id: map['id'] ?? '', + manufacturer: map['manufacturer'] ?? '', + model: map['model'] ?? '', + product: map['product'] ?? '', + supported32BitAbis: _fromList(map['supported32BitAbis']), + supported64BitAbis: _fromList(map['supported64BitAbis']), + supportedAbis: _fromList(map['supportedAbis']), + tags: map['tags'] ?? '', + type: map['type'] ?? '', + isPhysicalDevice: map['isPhysicalDevice'] ?? false, + androidId: map['androidId'] ?? '', + systemFeatures: _fromList(map['systemFeatures']), ); } /// Deserializes message as List static List _fromList(dynamic message) { - final List list = message; - return List.from(list); + if (message == null) { + return []; + } + assert(message is List); + final List list = List.from(message) + ..removeWhere((value) => value == null); + return list.cast(); } } @@ -173,17 +211,25 @@ class AndroidBuildVersion { final String? securityPatch; /// The current development codename, or the string "REL" if this is a release build. + /// + /// The value is an empty String if it is not available. final String codename; /// The internal value used by the underlying source control to represent this build. + /// + /// The value is an empty String if it is not available. final String incremental; /// The user-visible version string. + /// + /// The value is an empty String if it is not available. final String release; /// The user-visible SDK version of the framework. /// /// Possible values are defined in: https://developer.android.com/reference/android/os/Build.VERSION_CODES.html + /// + /// The value is -1 if it is unavailable. final int sdkInt; /// Deserializes from the map message received from [_kChannel]. @@ -192,10 +238,10 @@ class AndroidBuildVersion { baseOS: map['baseOS'], previewSdkInt: map['previewSdkInt'], securityPatch: map['securityPatch'], - codename: map['codename']!, - incremental: map['incremental']!, - release: map['release']!, - sdkInt: map['sdkInt']!, + codename: map['codename'] ?? '', + incremental: map['incremental'] ?? '', + release: map['release'] ?? '', + sdkInt: map['sdkInt'] ?? -1, ); } } diff --git a/packages/device_info/device_info_platform_interface/lib/model/ios_device_info.dart b/packages/device_info/device_info_platform_interface/lib/model/ios_device_info.dart index eb6e5874073b..20ec8362f66d 100644 --- a/packages/device_info/device_info_platform_interface/lib/model/ios_device_info.dart +++ b/packages/device_info/device_info_platform_interface/lib/model/ios_device_info.dart @@ -19,40 +19,60 @@ class IosDeviceInfo { }); /// Device name. + /// + /// The value is an empty String if it is not available. final String name; /// The name of the current operating system. + /// + /// The value is an empty String if it is not available. final String systemName; /// The current operating system version. + /// + /// The value is an empty String if it is not available. final String systemVersion; /// Device model. + /// + /// The value is an empty String if it is not available. final String model; /// Localized name of the device model. + /// + /// The value is an empty String if it is not available. final String localizedModel; /// Unique UUID value identifying the current device. + /// + /// The value is an empty String if it is not available. final String identifierForVendor; - /// `false` if the application is running in a simulator, `true` otherwise. + /// The value is `true` if the application is running on a physical device. + /// + /// The value is `false` when the application is running on a simulator, or the value is unavailable. final bool isPhysicalDevice; /// Operating system information derived from `sys/utsname.h`. + /// + /// The value is an empty String if it is not available. final IosUtsname utsname; /// Deserializes from the map message received from [_kChannel]. static IosDeviceInfo fromMap(Map map) { return IosDeviceInfo( - name: map['name']!, - systemName: map['systemName']!, - systemVersion: map['systemVersion']!, - model: map['model']!, - localizedModel: map['localizedModel']!, - identifierForVendor: map['identifierForVendor']!, - isPhysicalDevice: map['isPhysicalDevice'] == 'true', - utsname: IosUtsname._fromMap(map['utsname']!.cast()), + name: map['name'] ?? '', + systemName: map['systemName'] ?? '', + systemVersion: map['systemVersion'] ?? '', + model: map['model'] ?? '', + localizedModel: map['localizedModel'] ?? '', + identifierForVendor: map['identifierForVendor'] ?? '', + isPhysicalDevice: map['isPhysicalDevice'] != null + ? map['isPhysicalDevice'] == 'true' + : false, + utsname: IosUtsname._fromMap(map['utsname'] != null + ? map['utsname'].cast() + : {}), ); } } @@ -69,28 +89,38 @@ class IosUtsname { }); /// Operating system name. + /// + /// The value is an empty String if it is not available. final String sysname; /// Network node name. + /// + /// The value is an empty String if it is not available. final String nodename; /// Release level. + /// + /// The value is an empty String if it is not available. final String release; /// Version level. + /// + /// The value is an empty String if it is not available. final String version; /// Hardware type (e.g. 'iPhone7,1' for iPhone 6 Plus). + /// + /// The value is an empty String if it is not available. final String machine; /// Deserializes from the map message received from [_kChannel]. static IosUtsname _fromMap(Map map) { return IosUtsname._( - sysname: map['sysname']!, - nodename: map['nodename']!, - release: map['release']!, - version: map['version']!, - machine: map['machine']!, + sysname: map['sysname'] ?? '', + nodename: map['nodename'] ?? '', + release: map['release'] ?? '', + version: map['version'] ?? '', + machine: map['machine'] ?? '', ); } } diff --git a/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart b/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart index 15963854ab12..03ff4b53cda9 100644 --- a/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart +++ b/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart @@ -158,4 +158,220 @@ void main() { expect(result.utsname.machine, "x86_64"); }); }); + + group( + "$MethodChannelDeviceInfo handles null value in the map returned from method channel", + () { + MethodChannelDeviceInfo methodChannelDeviceInfo; + + setUp(() async { + methodChannelDeviceInfo = MethodChannelDeviceInfo(); + + methodChannelDeviceInfo.channel + .setMockMethodCallHandler((MethodCall methodCall) async { + switch (methodCall.method) { + case 'getAndroidDeviceInfo': + return ({ + "version": null, + "board": null, + "bootloader": null, + "brand": null, + "device": null, + "display": null, + "fingerprint": null, + "hardware": null, + "host": null, + "id": null, + "manufacturer": null, + "model": null, + "product": null, + "supported32BitAbis": null, + "supported64BitAbis": null, + "supportedAbis": null, + "tags": null, + "type": null, + "isPhysicalDevice": null, + "androidId": null, + "systemFeatures": null, + }); + case 'getIosDeviceInfo': + return ({ + "name": null, + "systemName": null, + "systemVersion": null, + "model": null, + "localizedModel": null, + "identifierForVendor": null, + "isPhysicalDevice": null, + "utsname": null, + }); + default: + return null; + } + }); + }); + + test("androidInfo hanels null", () async { + final AndroidDeviceInfo result = + await methodChannelDeviceInfo.androidInfo(); + + expect(result.version.securityPatch, null); + expect(result.version.sdkInt, -1); + expect(result.version.release, ''); + expect(result.version.previewSdkInt, null); + expect(result.version.incremental, ''); + expect(result.version.codename, ''); + expect(result.board, ''); + expect(result.bootloader, ''); + expect(result.brand, ''); + expect(result.device, ''); + expect(result.display, ''); + expect(result.fingerprint, ''); + expect(result.hardware, ''); + expect(result.host, ''); + expect(result.id, ''); + expect(result.manufacturer, ''); + expect(result.model, ''); + expect(result.product, ''); + expect(result.supported32BitAbis, []); + expect(result.supported64BitAbis, []); + expect(result.supportedAbis, []); + expect(result.tags, ''); + expect(result.type, ''); + expect(result.isPhysicalDevice, false); + expect(result.androidId, ''); + expect(result.systemFeatures, []); + }); + + test("iosInfo handles null", () async { + final IosDeviceInfo result = await methodChannelDeviceInfo.iosInfo(); + expect(result.name, ''); + expect(result.systemName, ''); + expect(result.systemVersion, ''); + expect(result.model, ''); + expect(result.localizedModel, ''); + expect(result.identifierForVendor, ''); + expect(result.isPhysicalDevice, false); + expect(result.utsname.sysname, ''); + expect(result.utsname.nodename, ''); + expect(result.utsname.release, ''); + expect(result.utsname.version, ''); + expect(result.utsname.machine, ''); + }); + }); + + group("$MethodChannelDeviceInfo handles method channel returns null", () { + MethodChannelDeviceInfo methodChannelDeviceInfo; + + setUp(() async { + methodChannelDeviceInfo = MethodChannelDeviceInfo(); + + methodChannelDeviceInfo.channel + .setMockMethodCallHandler((MethodCall methodCall) async { + switch (methodCall.method) { + case 'getAndroidDeviceInfo': + return null; + case 'getIosDeviceInfo': + return null; + default: + return null; + } + }); + }); + + test("androidInfo handles null", () async { + final AndroidDeviceInfo result = + await methodChannelDeviceInfo.androidInfo(); + + expect(result.version.securityPatch, null); + expect(result.version.sdkInt, -1); + expect(result.version.release, ''); + expect(result.version.previewSdkInt, null); + expect(result.version.incremental, ''); + expect(result.version.codename, ''); + expect(result.board, ''); + expect(result.bootloader, ''); + expect(result.brand, ''); + expect(result.device, ''); + expect(result.display, ''); + expect(result.fingerprint, ''); + expect(result.hardware, ''); + expect(result.host, ''); + expect(result.id, ''); + expect(result.manufacturer, ''); + expect(result.model, ''); + expect(result.product, ''); + expect(result.supported32BitAbis, []); + expect(result.supported64BitAbis, []); + expect(result.supportedAbis, []); + expect(result.tags, ''); + expect(result.type, ''); + expect(result.isPhysicalDevice, false); + expect(result.androidId, ''); + expect(result.systemFeatures, []); + }); + + test("iosInfo handles null", () async { + final IosDeviceInfo result = await methodChannelDeviceInfo.iosInfo(); + expect(result.name, ''); + expect(result.systemName, ''); + expect(result.systemVersion, ''); + expect(result.model, ''); + expect(result.localizedModel, ''); + expect(result.identifierForVendor, ''); + expect(result.isPhysicalDevice, false); + expect(result.utsname.sysname, ''); + expect(result.utsname.nodename, ''); + expect(result.utsname.release, ''); + expect(result.utsname.version, ''); + expect(result.utsname.machine, ''); + }); + }); + + group("$MethodChannelDeviceInfo android handles null values in list", () { + MethodChannelDeviceInfo methodChannelDeviceInfo; + + setUp(() async { + methodChannelDeviceInfo = MethodChannelDeviceInfo(); + + methodChannelDeviceInfo.channel + .setMockMethodCallHandler((MethodCall methodCall) async { + switch (methodCall.method) { + case 'getAndroidDeviceInfo': + return ({ + "supported32BitAbis": ["x86", null], + "supported64BitAbis": ["x86_64", null], + "supportedAbis": ["x86_64", "x86", null], + "systemFeatures": [ + "android.hardware.sensor.proximity", + "android.software.adoptable_storage", + "android.hardware.sensor.accelerometer", + "android.hardware.faketouch", + "android.software.backup", + "android.hardware.touchscreen", + null + ], + }); + default: + return null; + } + }); + }); + + test("androidInfo hanels null in list", () async { + final AndroidDeviceInfo result = + await methodChannelDeviceInfo.androidInfo(); + expect(result.supported32BitAbis, ['x86']); + expect(result.supported64BitAbis, ['x86_64']); + expect(result.supportedAbis, ['x86_64', 'x86']); + expect(result.systemFeatures, [ + "android.hardware.sensor.proximity", + "android.software.adoptable_storage", + "android.hardware.sensor.accelerometer", + "android.hardware.faketouch", + "android.software.backup", + "android.hardware.touchscreen" + ]); + }); + }); } From 07e37f51a58da0c413a05d9bf794365b87c72b22 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Tue, 23 Feb 2021 14:36:02 -0800 Subject: [PATCH 0203/1565] [google_maps_flutter] Bump app-facing version for NNBD stable (#3623) --- .../google_maps_flutter/CHANGELOG.md | 6 +-- .../google_maps_flutter/example/pubspec.yaml | 43 +------------------ .../google_maps_flutter/pubspec.yaml | 16 +++---- 3 files changed, 11 insertions(+), 54 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index ef64aac534a5..dae5caf89a60 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,8 +1,4 @@ -## 2.0.0-nullsafety.1 - -* Fix in example app to properly change marker icon. - -## 2.0.0-nullsafety +## 2.0.0 * Migrate to null-safety * BREAKING CHANGE: Passing an unknown map object ID (e.g., MarkerId) to a diff --git a/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml index 181550d32877..35d0da3488be 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml @@ -2,15 +2,13 @@ name: google_maps_flutter_example description: Demonstrates how to use the google_maps_flutter plugin. environment: - sdk: '>=2.12.0-0 <3.0.0' + sdk: '>=2.12.0-259.9.beta <3.0.0' flutter: ">=1.22.0" dependencies: flutter: sdk: flutter - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.0 google_maps_flutter: # When depending on this package from a real application you should use: @@ -26,46 +24,9 @@ dev_dependencies: sdk: flutter integration_test: path: ../../../integration_test - pedantic: ^1.8.0 + pedantic: ^1.10.0 -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. uses-material-design: true - - # To add assets to your application, add an assets section, like this: assets: - assets/ - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index fbab15231b25..3d0e79473a33 100644 --- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml @@ -1,13 +1,13 @@ name: google_maps_flutter description: A Flutter plugin for integrating Google Maps in iOS and Android applications. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter -version: 2.0.0-nullsafety.1 +version: 2.0.0 dependencies: flutter: sdk: flutter - flutter_plugin_android_lifecycle: ^2.0.0-nullsafety.2 - google_maps_flutter_platform_interface: ^2.0.0-nullsafety.1 + flutter_plugin_android_lifecycle: ^2.0.0 + google_maps_flutter_platform_interface: ^2.0.0 dev_dependencies: flutter_test: @@ -17,10 +17,10 @@ dev_dependencies: # https://github.com/dart-lang/pub/issues/2101 is resolved. flutter_driver: sdk: flutter - test: ^1.16.0-nullsafety.17 - pedantic: ^1.10.0-nullsafety.3 - plugin_platform_interface: ^1.1.0-nullsafety.2 - stream_transform: ^2.0.0-nullsafety.0 + test: ^1.16.0 + pedantic: ^1.10.0 + plugin_platform_interface: ">=1.0.0 <3.0.0" + stream_transform: ^2.0.0 flutter: plugin: @@ -32,5 +32,5 @@ flutter: pluginClass: FLTGoogleMapsPlugin environment: - sdk: '>=2.12.0-0 <3.0.0' + sdk: '>=2.12.0-259.9.beta <3.0.0' flutter: ">=1.22.0" From 29c3f1fd37de821ebd942f6f86999a09b1ba0a3f Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Tue, 23 Feb 2021 15:10:32 -0800 Subject: [PATCH 0204/1565] [video_player_web] Bump version for NNBD stable (#3574) --- .../video_player/video_player_web/CHANGELOG.md | 18 ++---------------- .../video_player/video_player_web/pubspec.yaml | 12 ++++++------ .../test/video_player_web_test.dart | 4 +++- 3 files changed, 11 insertions(+), 23 deletions(-) diff --git a/packages/video_player/video_player_web/CHANGELOG.md b/packages/video_player/video_player_web/CHANGELOG.md index 4c58311508a2..63d4e10ef8da 100644 --- a/packages/video_player/video_player_web/CHANGELOG.md +++ b/packages/video_player/video_player_web/CHANGELOG.md @@ -1,23 +1,9 @@ -## 2.0.0-nullsafety.4 +## 2.0.0 +* Migrate to null safety. * Calling `setMixWithOthers()` now is silently ignored instead of throwing an exception. - -## 2.0.0-nullsafety.3 - -* Updated to video_player_platform_interface 4.0. - -## 2.0.0-nullsafety.2 - * Fixed an issue where `isBuffering` was not updating on Web. -## 2.0.0-nullsafety.1 - -* Bump Dart SDK to support null safety. - -## 2.0.0-nullsafety - -* Migrate to null safety. - ## 0.1.4+2 * Update Flutter SDK constraint. diff --git a/packages/video_player/video_player_web/pubspec.yaml b/packages/video_player/video_player_web/pubspec.yaml index d9628535e353..7404896e04a4 100644 --- a/packages/video_player/video_player_web/pubspec.yaml +++ b/packages/video_player/video_player_web/pubspec.yaml @@ -1,7 +1,7 @@ name: video_player_web description: Web platform implementation of video_player. homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player_web -version: 2.0.0-nullsafety.4 +version: 2.0.0 flutter: plugin: @@ -15,14 +15,14 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - meta: ^1.3.0-nullsafety.3 - video_player_platform_interface: ^4.0.0-nullsafety.0 + meta: ^1.3.0 + video_player_platform_interface: ^4.0.0 dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.10.0-nullsafety.1 + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.12.8" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" diff --git a/packages/video_player/video_player_web/test/video_player_web_test.dart b/packages/video_player/video_player_web/test/video_player_web_test.dart index 604bebf4e17a..aee5b0350570 100644 --- a/packages/video_player/video_player_web/test/video_player_web_test.dart +++ b/packages/video_player/video_player_web/test/video_player_web_test.dart @@ -98,7 +98,9 @@ void main() { await VideoPlayerPlatform.instance.setVolume(videoPlayerId, 0); await VideoPlayerPlatform.instance.play(videoPlayerId); - expect(eventStream, emitsError(isA())); + expect(() async { + await eventStream.last; + }, throwsA(isA())); }); test('can pause', () { From 22007382fa7b95354b41f4ee68ab1e89e665ff4e Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Wed, 24 Feb 2021 05:00:12 -0800 Subject: [PATCH 0205/1565] [video_player] Bump app-facing version for NNBD stable (#3624) --- .../video_player/video_player/CHANGELOG.md | 53 +++---------------- .../video_player/example/pubspec.yaml | 4 +- .../video_player/video_player/pubspec.yaml | 14 ++--- 3 files changed, 17 insertions(+), 54 deletions(-) diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index f79a05f0e036..57ba54e0a7bc 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,50 +1,13 @@ -## 2.0.0-nullsafety.11 - -* Setting the `mixWithOthers` `VideoPlayerOptions` in web now is silently ignored instead of throwing an exception. - -## 2.0.0-nullsafety.10 - -* Updated to video_player_platform_interface 4.0. - -## 2.0.0-nullsafety.9 - -* Fixed an issue where a crash can occur after a closing a video player view on iOS. - -## 2.0.0-nullsafety.8 - -* Migrated from deprecated `defaultBinaryMessenger`. - -## 2.0.0-nullsafety.7 - -* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. - -## 2.0.0-nullsafety.6 - -* Fix `VideoPlayerValue toString()` test. - -## 2.0.0-nullsafety.5 +## 2.0.0 +* Migrate to null safety. +* Fix an issue where `isBuffering` was not updating on Android. * Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) - -## 2.0.0-nullsafety.4 - -* Fixed an issue where `isBuffering` was not updating on Android. - -## 2.0.0-nullsafety.3 - -* Dart null safety requires `2.12`. - -## 2.0.0-nullsafety.2 - -* Bump SDK version. - -## 2.0.0-nullsafety.1 - -* Merge master. - -## 2.0.0-nullsafety - -* Migration to null safety. +* Fix `VideoPlayerValue toString()` test. +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. +* Migrate from deprecated `defaultBinaryMessenger`. +* Fix an issue where a crash can occur after a closing a video player view on iOS. +* Setting the `mixWithOthers` `VideoPlayerOptions` in web now is silently ignored instead of throwing an exception. ## 1.0.2 diff --git a/packages/video_player/video_player/example/pubspec.yaml b/packages/video_player/video_player/example/pubspec.yaml index 620186afc880..4bfb3e5fefad 100644 --- a/packages/video_player/video_player/example/pubspec.yaml +++ b/packages/video_player/video_player/example/pubspec.yaml @@ -22,7 +22,7 @@ dev_dependencies: integration_test: path: ../../../integration_test test: any - pedantic: ^1.10.0-nullsafety.1 + pedantic: ^1.10.0 flutter: uses-material-design: true @@ -32,5 +32,5 @@ flutter: - assets/bumble_bee_captions.srt environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index 39289d159195..fedc46c721b1 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -1,7 +1,7 @@ name: video_player description: Flutter plugin for displaying inline video with other Flutter widgets on Android, iOS, and web. -version: 2.0.0-nullsafety.11 +version: 2.0.0 homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player flutter: @@ -16,8 +16,8 @@ flutter: default_package: video_player_web dependencies: - meta: ^1.3.0-nullsafety.3 - video_player_platform_interface: ^4.0.0-nullsafety.0 + meta: ^1.3.0 + video_player_platform_interface: ^4.0.0 # The design on https://flutter.dev/go/federated-plugins was to leave # this constraint as "any". We cannot do it right now as it fails pub publish @@ -25,7 +25,7 @@ dependencies: # the constraints on the interface pins it. # TODO(amirh): Revisit this (either update this part in the design or the pub tool). # https://github.com/flutter/flutter/issues/46264 - video_player_web: ^2.0.0-nullsafety.1 + video_player_web: ^2.0.0 flutter: sdk: flutter @@ -33,9 +33,9 @@ dependencies: sdk: flutter dev_dependencies: - pedantic: ^1.10.0-nullsafety.1 - pigeon: ^0.1.19 + pedantic: ^1.10.0 + pigeon: ^0.1.21 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" From f42e6c3ab292510acf3b929b14e392ec1fff7593 Mon Sep 17 00:00:00 2001 From: LI DONGZE Date: Wed, 24 Feb 2021 09:22:52 -0800 Subject: [PATCH 0206/1565] [url_launcher] Update result to `True` when the url was loaded successfully. (#3475) * Update FLTURLLauncherPlugin.m Update result to `True` when the url was loaded successfully. * Update pubspec.yaml * Update CHANGELOG.md * Undo the re-addition of pre-release changelogs. Co-authored-by: Ben Li Co-authored-by: stuartmorgan --- packages/url_launcher/url_launcher/CHANGELOG.md | 4 ++++ .../url_launcher/ios/Classes/FLTURLLauncherPlugin.m | 2 +- packages/url_launcher/url_launcher/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index f5fb73104c50..01f3e787fc9c 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.0.1 + +* Update result to `True` on iOS when the url was loaded successfully. + ## 6.0.0 * Migrate to null safety. diff --git a/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.m b/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.m index 39013b3ca039..ac05417473a3 100644 --- a/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.m +++ b/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.m @@ -34,7 +34,7 @@ - (instancetype)initWithUrl:url withFlutterResult:result { - (void)safariViewController:(SFSafariViewController *)controller didCompleteInitialLoad:(BOOL)didLoadSuccessfully API_AVAILABLE(ios(9.0)) { if (didLoadSuccessfully) { - self.flutterResult(nil); + self.flutterResult(@YES); } else { self.flutterResult([FlutterError errorWithCode:@"Error" diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index a9c2794b069a..4036748a2d2e 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -2,7 +2,7 @@ name: url_launcher description: Flutter plugin for launching a URL. Supports web, phone, SMS, and email schemes. homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher -version: 6.0.0 +version: 6.0.1 flutter: plugin: From 499156ed5f8b2d46e45dd0745f9e837ea9912b6f Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Wed, 24 Feb 2021 17:13:57 -0800 Subject: [PATCH 0207/1565] [quick_action] fix delegate methods not called on iOS (#3621) --- .cirrus.yml | 7 +- packages/quick_actions/CHANGELOG.md | 1 + .../ios/Runner.xcodeproj/project.pbxproj | 161 ++++++++++++++---- .../contents.xcworkspacedata | 7 - .../xcshareddata/xcschemes/Runner.xcscheme | 10 ++ .../xcschemes/RunnerUITests.xcscheme | 52 ++++++ .../example/ios/RunnerUITests/Info.plist | 22 +++ .../example/ios/RunnerUITests/RunnerUITests.m | 61 +++++++ packages/quick_actions/example/lib/main.dart | 10 +- .../ios/Classes/FLTQuickActionsPlugin.m | 1 + 10 files changed, 292 insertions(+), 40 deletions(-) delete mode 100644 packages/quick_actions/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 packages/quick_actions/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/RunnerUITests.xcscheme create mode 100644 packages/quick_actions/example/ios/RunnerUITests/Info.plist create mode 100644 packages/quick_actions/example/ios/RunnerUITests/RunnerUITests.m diff --git a/.cirrus.yml b/.cirrus.yml index 2b6ee2b7f969..6b3614178b11 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -183,7 +183,7 @@ task: - name: build-ipas+drive-examples env: PATH: $PATH:/usr/local/bin - PLUGINS_TO_SKIP_XCTESTS: "battery/battery,camera/camera,connectivity/connectivity,device_info/device_info,espresso,google_maps_flutter/google_maps_flutter,google_sign_in/google_sign_in,in_app_purchase,integration_test,ios_platform_images,local_auth,package_info,path_provider/path_provider,quick_actions,sensors,shared_preferences/shared_preferences,url_launcher/url_launcher,video_player/video_player,webview_flutter,wifi_info_flutter/wifi_info_flutter" + PLUGINS_TO_SKIP_XCTESTS: "battery/battery,camera/camera,connectivity/connectivity,device_info/device_info,espresso,google_maps_flutter/google_maps_flutter,google_sign_in/google_sign_in,in_app_purchase,integration_test,ios_platform_images,local_auth,package_info,path_provider/path_provider,sensors,shared_preferences/shared_preferences,url_launcher/url_launcher,video_player/video_player,webview_flutter,wifi_info_flutter/wifi_info_flutter" matrix: PLUGIN_SHARDING: "--shardIndex 0 --shardCount 4" PLUGIN_SHARDING: "--shardIndex 1 --shardCount 4" @@ -201,8 +201,11 @@ task: - flutter channel $CHANNEL - flutter upgrade - ./script/incremental_build.sh build-examples --ipa - - ./script/incremental_build.sh drive-examples --ios - ./script/incremental_build.sh xctest --target RunnerUITests --skip $PLUGINS_TO_SKIP_XCTESTS --ios-destination "platform=iOS Simulator,name=iPhone 11,OS=14.3" + # `drive-examples` contains integration tests, which changes the UI of the application. + # This UI change sometimes affects `xctest`. + # So we run `drive-examples` after `xctest`, changing the order will result ci failure. + - ./script/incremental_build.sh drive-examples --ios task: # Xcode 11 task diff --git a/packages/quick_actions/CHANGELOG.md b/packages/quick_actions/CHANGELOG.md index 1b6de34ca375..276ddfbf24c4 100644 --- a/packages/quick_actions/CHANGELOG.md +++ b/packages/quick_actions/CHANGELOG.md @@ -1,6 +1,7 @@ ## 0.5.0 * Migrate to null safety. +* Fixes quick actions not working on iOS. ## 0.4.0+12 diff --git a/packages/quick_actions/example/ios/Runner.xcodeproj/project.pbxproj b/packages/quick_actions/example/ios/Runner.xcodeproj/project.pbxproj index fdd275fcede5..dba32819ce42 100644 --- a/packages/quick_actions/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/quick_actions/example/ios/Runner.xcodeproj/project.pbxproj @@ -9,11 +9,8 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 686BE83025E58CCF00862533 /* RunnerUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 686BE82F25E58CCF00862533 /* RunnerUITests.m */; }; 83C36CAF23D629E5ABE75B2A /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CCC799F2B0AB50A9C34344F0 /* libPods-Runner.a */; }; - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; @@ -21,6 +18,16 @@ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 686BE83225E58CCF00862533 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXCopyFilesBuildPhase section */ 9705A1C41CF9048500538489 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; @@ -28,8 +35,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -40,14 +45,15 @@ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 5278439583922091276A37C9 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 686BE82D25E58CCF00862533 /* RunnerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 686BE82F25E58CCF00862533 /* RunnerUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RunnerUITests.m; sourceTree = ""; }; + 686BE83125E58CCF00862533 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; @@ -59,12 +65,17 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 686BE82A25E58CCF00862533 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, 83C36CAF23D629E5ABE75B2A /* libPods-Runner.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -72,12 +83,19 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 686BE82E25E58CCF00862533 /* RunnerUITests */ = { + isa = PBXGroup; + children = ( + 686BE82F25E58CCF00862533 /* RunnerUITests.m */, + 686BE83125E58CCF00862533 /* Info.plist */, + ); + path = RunnerUITests; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( - 3B80C3931E831B6300D905FE /* App.framework */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEBA1CF902C7004384FC /* Flutter.framework */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 9740EEB31CF90195004384FC /* Generated.xcconfig */, @@ -90,6 +108,7 @@ children = ( 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, + 686BE82E25E58CCF00862533 /* RunnerUITests */, 97C146EF1CF9000F007C117D /* Products */, D0FE95BE2380323DD75CB891 /* Pods */, A44AD0D63DEF785A2A2DEE28 /* Frameworks */, @@ -100,6 +119,7 @@ isa = PBXGroup; children = ( 97C146EE1CF9000F007C117D /* Runner.app */, + 686BE82D25E58CCF00862533 /* RunnerUITests.xctest */, ); name = Products; sourceTree = ""; @@ -148,6 +168,24 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 686BE82C25E58CCF00862533 /* RunnerUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 686BE83625E58CCF00862533 /* Build configuration list for PBXNativeTarget "RunnerUITests" */; + buildPhases = ( + 686BE82925E58CCF00862533 /* Sources */, + 686BE82A25E58CCF00862533 /* Frameworks */, + 686BE82B25E58CCF00862533 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 686BE83325E58CCF00862533 /* PBXTargetDependency */, + ); + name = RunnerUITests; + productName = RunnerUITests; + productReference = 686BE82D25E58CCF00862533 /* RunnerUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; 97C146ED1CF9000F007C117D /* Runner */ = { isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; @@ -159,7 +197,6 @@ 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - FEDDF02AA7C2BA0D1905BD95 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -179,6 +216,11 @@ LastUpgradeCheck = 1100; ORGANIZATIONNAME = "The Chromium Authors"; TargetAttributes = { + 686BE82C25E58CCF00862533 = { + CreatedOnToolsVersion = 12.4; + ProvisioningStyle = Automatic; + TestTargetID = 97C146ED1CF9000F007C117D; + }; 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; }; @@ -198,11 +240,19 @@ projectRoot = ""; targets = ( 97C146ED1CF9000F007C117D /* Runner */, + 686BE82C25E58CCF00862533 /* RunnerUITests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 686BE82B25E58CCF00862533 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 97C146EC1CF9000F007C117D /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -229,7 +279,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; @@ -263,24 +313,17 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - FEDDF02AA7C2BA0D1905BD95 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 686BE82925E58CCF00862533 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( + 686BE83025E58CCF00862533 /* RunnerUITests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ 97C146EA1CF9000F007C117D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -293,6 +336,14 @@ }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 686BE83325E58CCF00862533 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 686BE83225E58CCF00862533 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ 97C146FA1CF9000F007C117D /* Main.storyboard */ = { isa = PBXVariantGroup; @@ -313,9 +364,53 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 686BE83425E58CCF00862533 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = RunnerUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.google.RunnerUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Runner; + }; + name = Debug; + }; + 686BE83525E58CCF00862533 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = RunnerUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.google.RunnerUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Runner; + }; + name = Release; + }; 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; @@ -372,7 +467,6 @@ }; 97C147041CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; @@ -466,6 +560,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 686BE83625E58CCF00862533 /* Build configuration list for PBXNativeTarget "RunnerUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 686BE83425E58CCF00862533 /* Debug */, + 686BE83525E58CCF00862533 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/packages/quick_actions/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/quick_actions/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a16ed0f..000000000000 --- a/packages/quick_actions/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/packages/quick_actions/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/quick_actions/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 3bb3697ef41c..9850cc113026 100644 --- a/packages/quick_actions/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/quick_actions/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -37,6 +37,16 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/quick_actions/example/ios/RunnerUITests/Info.plist b/packages/quick_actions/example/ios/RunnerUITests/Info.plist new file mode 100644 index 000000000000..64d65ca49577 --- /dev/null +++ b/packages/quick_actions/example/ios/RunnerUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/packages/quick_actions/example/ios/RunnerUITests/RunnerUITests.m b/packages/quick_actions/example/ios/RunnerUITests/RunnerUITests.m new file mode 100644 index 000000000000..f78081b98a01 --- /dev/null +++ b/packages/quick_actions/example/ios/RunnerUITests/RunnerUITests.m @@ -0,0 +1,61 @@ +// Copyright 2019 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. + +#import +#import + +static const int kElementWaitingTime = 30; + +@interface RunnerUITests : XCTestCase + +@end + +@implementation RunnerUITests + +- (void)setUp { + [super setUp]; + self.continueAfterFailure = NO; +} + +- (void)testQuickAction { + XCUIApplication *app = [[XCUIApplication alloc] init]; + [app launch]; + XCUIElement *actionsReady = app.otherElements[@"actions ready"]; + if (![actionsReady waitForExistenceWithTimeout:kElementWaitingTime]) { + os_log_error(OS_LOG_DEFAULT, "%@", app.debugDescription); + XCTFail(@"Failed due to not able to find the actionsReady in the app with %@ seconds", + @(kElementWaitingTime)); + } + + [[XCUIDevice sharedDevice] pressButton:XCUIDeviceButtonHome]; + + XCUIApplication *springboard = + [[XCUIApplication alloc] initWithBundleIdentifier:@"com.apple.springboard"]; + XCUIElement *quickActionsAppIcon = springboard.icons[@"quick_actions_example"]; + if (![quickActionsAppIcon waitForExistenceWithTimeout:kElementWaitingTime]) { + os_log_error(OS_LOG_DEFAULT, "%@", springboard.debugDescription); + XCTFail(@"Failed due to not able to find the example app from springboard with %@ seconds", + @(kElementWaitingTime)); + } + + [quickActionsAppIcon pressForDuration:2]; + XCUIElement *actionOne = springboard.buttons[@"Action one"]; + if (![actionOne waitForExistenceWithTimeout:kElementWaitingTime]) { + os_log_error(OS_LOG_DEFAULT, "%@", springboard.debugDescription); + XCTFail(@"Failed due to not able to find the actionOne button from springboard with %@ seconds", + @(kElementWaitingTime)); + } + + [actionOne tap]; + + XCUIElement *actionOneConfirmation = app.otherElements[@"action_one"]; + if (![actionOneConfirmation waitForExistenceWithTimeout:kElementWaitingTime]) { + os_log_error(OS_LOG_DEFAULT, "%@", springboard.debugDescription); + XCTFail(@"Failed due to not able to find the actionOneConfirmation in the app with %@ seconds", + @(kElementWaitingTime)); + } + XCTAssertTrue(actionOneConfirmation.exists); +} + +@end diff --git a/packages/quick_actions/example/lib/main.dart b/packages/quick_actions/example/lib/main.dart index a7e9d5e4c031..08d8f4a1fbce 100644 --- a/packages/quick_actions/example/lib/main.dart +++ b/packages/quick_actions/example/lib/main.dart @@ -41,7 +41,9 @@ class _MyHomePageState extends State { final QuickActions quickActions = QuickActions(); quickActions.initialize((String shortcutType) { setState(() { - if (shortcutType != null) shortcut = shortcutType; + if (shortcutType != null) { + shortcut = shortcutType; + } }); }); @@ -59,7 +61,11 @@ class _MyHomePageState extends State { type: 'action_two', localizedTitle: 'Action two', icon: 'ic_launcher'), - ]); + ]).then((value) { + setState(() { + shortcut = "actions ready"; + }); + }); } @override diff --git a/packages/quick_actions/ios/Classes/FLTQuickActionsPlugin.m b/packages/quick_actions/ios/Classes/FLTQuickActionsPlugin.m index 88ff7397af8a..c99c016ed1ed 100644 --- a/packages/quick_actions/ios/Classes/FLTQuickActionsPlugin.m +++ b/packages/quick_actions/ios/Classes/FLTQuickActionsPlugin.m @@ -19,6 +19,7 @@ + (void)registerWithRegistrar:(NSObject *)registrar { FLTQuickActionsPlugin *instance = [[FLTQuickActionsPlugin alloc] init]; instance.channel = channel; [registrar addMethodCallDelegate:instance channel:channel]; + [registrar addApplicationDelegate:instance]; } - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { From 96faf2cff39d7ed65cc52222e5d22e9769311269 Mon Sep 17 00:00:00 2001 From: Darshan Rander Date: Thu, 25 Feb 2021 07:34:20 +0530 Subject: [PATCH 0208/1565] [file_selector_web] Migrated to null-safety (#3550) Co-authored-by: David Iglesias Teixeira --- .../file_selector_web/CHANGELOG.md | 4 + .../file_selector_web/example/README.md | 21 +++++ .../integration_test/dom_helper_test.dart | 16 ++-- .../file_selector_web_test.dart | 76 ++++++++++++------- .../file_selector_web/example/lib/main.dart | 25 ++++++ .../file_selector_web/example/pubspec.yaml | 21 +++++ .../run_test.sh} | 0 .../test_driver/integration_test.dart | 0 .../file_selector_web/example/web/index.html | 12 +++ .../lib/file_selector_web.dart | 34 ++++----- .../file_selector_web/lib/src/dom_helper.dart | 35 +++++---- .../file_selector_web/lib/src/utils.dart | 14 ++-- .../file_selector_web/pubspec.yaml | 16 ++-- .../test/more_tests_exist_elsewhere_test.dart | 10 +++ .../file_selector_web/test/utils_test.dart | 2 - 15 files changed, 199 insertions(+), 87 deletions(-) create mode 100644 packages/file_selector/file_selector_web/example/README.md rename packages/file_selector/file_selector_web/{ => example}/integration_test/dom_helper_test.dart (91%) rename packages/file_selector/file_selector_web/{ => example}/integration_test/file_selector_web_test.dart (59%) create mode 100644 packages/file_selector/file_selector_web/example/lib/main.dart create mode 100644 packages/file_selector/file_selector_web/example/pubspec.yaml rename packages/file_selector/file_selector_web/{run_integration_test => example/run_test.sh} (100%) rename packages/file_selector/file_selector_web/{ => example}/test_driver/integration_test.dart (100%) create mode 100644 packages/file_selector/file_selector_web/example/web/index.html create mode 100644 packages/file_selector/file_selector_web/test/more_tests_exist_elsewhere_test.dart diff --git a/packages/file_selector/file_selector_web/CHANGELOG.md b/packages/file_selector/file_selector_web/CHANGELOG.md index 619aa769d5f6..4caad4b975f9 100644 --- a/packages/file_selector/file_selector_web/CHANGELOG.md +++ b/packages/file_selector/file_selector_web/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.8.0 + +- Migrated to null-safety + # 0.7.0+1 - Add dummy `ios` dir, so flutter sdk can be lower than 1.20 diff --git a/packages/file_selector/file_selector_web/example/README.md b/packages/file_selector/file_selector_web/example/README.md new file mode 100644 index 000000000000..6187e55841c9 --- /dev/null +++ b/packages/file_selector/file_selector_web/example/README.md @@ -0,0 +1,21 @@ +# Testing + +This package utilizes the `integration_test` package to run its tests in a web browser. + +See [flutter.dev > Integration testing](https://flutter.dev/docs/testing/integration-tests) for more info. + +## Running the tests + +Make sure you have updated to the latest Flutter master. + +1. Check what version of Chrome is running on the machine you're running tests on. + +2. Download and install driver for that version from here: + * + +3. Start the driver using `chromedriver --port=4444` + +4. Run tests: `flutter drive -d web-server --browser-name=chrome --driver=test_driver/integration_test.dart --target=integration_test/TEST_NAME.dart`, or (in Linux): + + * Single: `./run_test.sh integration_test/TEST_NAME.dart` + * All: `./run_test.sh` diff --git a/packages/file_selector/file_selector_web/integration_test/dom_helper_test.dart b/packages/file_selector/file_selector_web/example/integration_test/dom_helper_test.dart similarity index 91% rename from packages/file_selector/file_selector_web/integration_test/dom_helper_test.dart rename to packages/file_selector/file_selector_web/example/integration_test/dom_helper_test.dart index a942c0db10bf..274aed93659e 100644 --- a/packages/file_selector/file_selector_web/integration_test/dom_helper_test.dart +++ b/packages/file_selector/file_selector_web/example/integration_test/dom_helper_test.dart @@ -2,8 +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'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; @@ -11,19 +9,19 @@ import 'package:file_selector_web/src/dom_helper.dart'; import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; void main() { - group('FileSelectorWeb', () { + group('dom_helper', () { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - DomHelper domHelper; - FileUploadInputElement input; + late DomHelper domHelper; + late FileUploadInputElement input; - FileList FileListItems(List files) { + FileList? createFileList(List files) { final dataTransfer = DataTransfer(); - files.forEach(dataTransfer.items.add); - return dataTransfer.files; + files.forEach(dataTransfer.items!.add); + return dataTransfer.files as FileList?; } void setFilesAndTriggerChange(List files) { - input.files = FileListItems(files); + input.files = createFileList(files); input.dispatchEvent(Event('change')); } diff --git a/packages/file_selector/file_selector_web/integration_test/file_selector_web_test.dart b/packages/file_selector/file_selector_web/example/integration_test/file_selector_web_test.dart similarity index 59% rename from packages/file_selector/file_selector_web/integration_test/file_selector_web_test.dart rename to packages/file_selector/file_selector_web/example/integration_test/file_selector_web_test.dart index abd31dd9fcc6..5442fedf5408 100644 --- a/packages/file_selector/file_selector_web/integration_test/file_selector_web_test.dart +++ b/packages/file_selector/file_selector_web/example/integration_test/file_selector_web_test.dart @@ -2,11 +2,9 @@ // 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'; import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; import 'package:integration_test/integration_test.dart'; import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; import 'package:file_selector_web/file_selector_web.dart'; @@ -15,18 +13,18 @@ import 'package:file_selector_web/src/dom_helper.dart'; void main() { group('FileSelectorWeb', () { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - MockDomHelper mockDomHelper; - FileSelectorWeb plugin; - - setUp(() { - mockDomHelper = MockDomHelper(); - plugin = FileSelectorWeb(domHelper: mockDomHelper); - }); group('openFile', () { - final mockFile = createXFile('1001', 'identity.png'); - testWidgets('works', (WidgetTester _) async { + final mockFile = createXFile('1001', 'identity.png'); + + final mockDomHelper = MockDomHelper() + ..setFiles([mockFile]) + ..expectAccept('.jpg,.jpeg,image/png,image/*') + ..expectMultiple(false); + + final plugin = FileSelectorWeb(domHelper: mockDomHelper); + final typeGroup = XTypeGroup( label: 'images', extensions: ['jpg', 'jpeg'], @@ -34,11 +32,6 @@ void main() { webWildCards: ['image/*'], ); - when(mockDomHelper.getFiles( - accept: '.jpg,.jpeg,image/png,image/*', - multiple: false, - )).thenAnswer((_) async => [mockFile]); - final file = await plugin.openFile(acceptedTypeGroups: [typeGroup]); expect(file.name, mockFile.name); @@ -49,20 +42,22 @@ void main() { }); group('openFiles', () { - final mockFile1 = createXFile('123456', 'file1.txt'); - final mockFile2 = createXFile('', 'file2.txt'); - testWidgets('works', (WidgetTester _) async { + final mockFile1 = createXFile('123456', 'file1.txt'); + final mockFile2 = createXFile('', 'file2.txt'); + + final mockDomHelper = MockDomHelper() + ..setFiles([mockFile1, mockFile2]) + ..expectAccept('.txt') + ..expectMultiple(true); + + final plugin = FileSelectorWeb(domHelper: mockDomHelper); + final typeGroup = XTypeGroup( label: 'files', extensions: ['.txt'], ); - when(mockDomHelper.getFiles( - accept: '.txt', - multiple: true, - )).thenAnswer((_) async => [mockFile1, mockFile2]); - final files = await plugin.openFiles(acceptedTypeGroups: [typeGroup]); expect(files.length, 2); @@ -81,7 +76,36 @@ void main() { }); } -class MockDomHelper extends Mock implements DomHelper {} +class MockDomHelper implements DomHelper { + List _files = []; + String _expectedAccept = ''; + bool _expectedMultiple = false; + + @override + Future> getFiles({ + String accept = '', + bool multiple = false, + FileUploadInputElement? input, + }) { + expect(accept, _expectedAccept, + reason: 'Expected "accept" value does not match.'); + expect(multiple, _expectedMultiple, + reason: 'Expected "multiple" value does not match.'); + return Future.value(_files); + } + + void setFiles(List files) { + _files = files; + } + + void expectAccept(String accept) { + _expectedAccept = accept; + } + + void expectMultiple(bool multiple) { + _expectedMultiple = multiple; + } +} XFile createXFile(String content, String name) { final data = Uint8List.fromList(content.codeUnits); diff --git a/packages/file_selector/file_selector_web/example/lib/main.dart b/packages/file_selector/file_selector_web/example/lib/main.dart new file mode 100644 index 000000000000..e1a38dcdcd46 --- /dev/null +++ b/packages/file_selector/file_selector_web/example/lib/main.dart @@ -0,0 +1,25 @@ +// Copyright 2013 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/material.dart'; + +void main() { + runApp(MyApp()); +} + +/// App for testing +class MyApp extends StatefulWidget { + @override + _MyAppState createState() => _MyAppState(); +} + +class _MyAppState extends State { + @override + Widget build(BuildContext context) { + return Directionality( + textDirection: TextDirection.ltr, + child: Text('Testing... Look at the console output for results!'), + ); + } +} diff --git a/packages/file_selector/file_selector_web/example/pubspec.yaml b/packages/file_selector/file_selector_web/example/pubspec.yaml new file mode 100644 index 000000000000..cae4b13a8207 --- /dev/null +++ b/packages/file_selector/file_selector_web/example/pubspec.yaml @@ -0,0 +1,21 @@ +name: file_selector_web_integration_tests +publish_to: none + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + build_runner: ^1.10.0 + file_selector_web: + path: ../ + flutter_driver: + sdk: flutter + flutter_test: + sdk: flutter + integration_test: + sdk: flutter + +environment: + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.27.0-0" # For integration_test from sdk diff --git a/packages/file_selector/file_selector_web/run_integration_test b/packages/file_selector/file_selector_web/example/run_test.sh similarity index 100% rename from packages/file_selector/file_selector_web/run_integration_test rename to packages/file_selector/file_selector_web/example/run_test.sh diff --git a/packages/file_selector/file_selector_web/test_driver/integration_test.dart b/packages/file_selector/file_selector_web/example/test_driver/integration_test.dart similarity index 100% rename from packages/file_selector/file_selector_web/test_driver/integration_test.dart rename to packages/file_selector/file_selector_web/example/test_driver/integration_test.dart diff --git a/packages/file_selector/file_selector_web/example/web/index.html b/packages/file_selector/file_selector_web/example/web/index.html new file mode 100644 index 000000000000..dc8d0cfe0428 --- /dev/null +++ b/packages/file_selector/file_selector_web/example/web/index.html @@ -0,0 +1,12 @@ + + + + + Browser Tests + + + + + diff --git a/packages/file_selector/file_selector_web/lib/file_selector_web.dart b/packages/file_selector/file_selector_web/lib/file_selector_web.dart index 48f57ee880c8..1c411ca0a2f0 100644 --- a/packages/file_selector/file_selector_web/lib/file_selector_web.dart +++ b/packages/file_selector/file_selector_web/lib/file_selector_web.dart @@ -13,7 +13,7 @@ import 'package:file_selector_web/src/utils.dart'; /// /// This class implements the `package:file_selector` functionality for the web. class FileSelectorWeb extends FileSelectorPlatform { - final _domHelper; + final DomHelper _domHelper; /// Registers this class as the default instance of [FileSelectorPlatform]. static void registerWith(Registrar registrar) { @@ -23,14 +23,14 @@ class FileSelectorWeb extends FileSelectorPlatform { /// Default constructor, initializes _domHelper that we can use /// to interact with the DOM. /// overrides parameter allows for testing to override functions - FileSelectorWeb({@visibleForTesting DomHelper domHelper}) + FileSelectorWeb({@visibleForTesting DomHelper? domHelper}) : _domHelper = domHelper ?? DomHelper(); @override Future openFile({ - List acceptedTypeGroups, - String initialDirectory, - String confirmButtonText, + List? acceptedTypeGroups, + String? initialDirectory, + String? confirmButtonText, }) async { final files = await _openFiles(acceptedTypeGroups: acceptedTypeGroups); return files.first; @@ -38,31 +38,31 @@ class FileSelectorWeb extends FileSelectorPlatform { @override Future> openFiles({ - List acceptedTypeGroups, - String initialDirectory, - String confirmButtonText, + List? acceptedTypeGroups, + String? initialDirectory, + String? confirmButtonText, }) async { return _openFiles(acceptedTypeGroups: acceptedTypeGroups, multiple: true); } @override - Future getSavePath({ - List acceptedTypeGroups, - String initialDirectory, - String suggestedName, - String confirmButtonText, + Future getSavePath({ + List? acceptedTypeGroups, + String? initialDirectory, + String? suggestedName, + String? confirmButtonText, }) async => null; @override - Future getDirectoryPath({ - String initialDirectory, - String confirmButtonText, + Future getDirectoryPath({ + String? initialDirectory, + String? confirmButtonText, }) async => null; Future> _openFiles({ - List acceptedTypeGroups, + List? acceptedTypeGroups, bool multiple = false, }) async { final accept = acceptedTypesToString(acceptedTypeGroups); diff --git a/packages/file_selector/file_selector_web/lib/src/dom_helper.dart b/packages/file_selector/file_selector_web/lib/src/dom_helper.dart index a965cebe97f9..5c578b6f4639 100644 --- a/packages/file_selector/file_selector_web/lib/src/dom_helper.dart +++ b/packages/file_selector/file_selector_web/lib/src/dom_helper.dart @@ -14,7 +14,7 @@ class DomHelper { /// Default constructor, initializes the container DOM element. DomHelper() { - final body = querySelector('body'); + final body = querySelector('body')!; body.children.add(_container); } @@ -22,42 +22,45 @@ class DomHelper { Future> getFiles({ String accept = '', bool multiple = false, - @visibleForTesting FileUploadInputElement input, + @visibleForTesting FileUploadInputElement? input, }) { - final Completer> _completer = Completer(); - input = input ?? FileUploadInputElement(); + final Completer> completer = Completer(); + final FileUploadInputElement inputElement = + input ?? FileUploadInputElement(); _container.children.add( - input + inputElement ..accept = accept ..multiple = multiple, ); - input.onChange.first.then((_) { - final List files = input.files.map(_convertFileToXFile).toList(); - input.remove(); - _completer.complete(files); + inputElement.onChange.first.then((_) { + final List files = + inputElement.files!.map(_convertFileToXFile).toList(); + inputElement.remove(); + completer.complete(files); }); - input.onError.first.then((event) { - final ErrorEvent error = event; + inputElement.onError.first.then((event) { + final ErrorEvent error = event as ErrorEvent; final platformException = PlatformException( code: error.type, message: error.message, ); - input.remove(); - _completer.completeError(platformException); + inputElement.remove(); + completer.completeError(platformException); }); - input.click(); + inputElement.click(); - return _completer.future; + return completer.future; } XFile _convertFileToXFile(File file) => XFile( Url.createObjectUrl(file), name: file.name, length: file.size, - lastModified: DateTime.fromMillisecondsSinceEpoch(file.lastModified), + lastModified: DateTime.fromMillisecondsSinceEpoch( + file.lastModified ?? DateTime.now().millisecondsSinceEpoch), ); } diff --git a/packages/file_selector/file_selector_web/lib/src/utils.dart b/packages/file_selector/file_selector_web/lib/src/utils.dart index 4ddd7ddcbda5..6be58c2aa0ec 100644 --- a/packages/file_selector/file_selector_web/lib/src/utils.dart +++ b/packages/file_selector/file_selector_web/lib/src/utils.dart @@ -5,19 +5,19 @@ import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; /// Convert list of XTypeGroups to a comma-separated string -String acceptedTypesToString(List acceptedTypes) { +String acceptedTypesToString(List? acceptedTypes) { if (acceptedTypes == null) return ''; final List allTypes = []; for (final group in acceptedTypes) { _assertTypeGroupIsValid(group); if (group.extensions != null) { - allTypes.addAll(group.extensions.map(_normalizeExtension)); + allTypes.addAll(group.extensions!.map(_normalizeExtension)); } if (group.mimeTypes != null) { - allTypes.addAll(group.mimeTypes); + allTypes.addAll(group.mimeTypes!); } if (group.webWildCards != null) { - allTypes.addAll(group.webWildCards); + allTypes.addAll(group.webWildCards!); } } return allTypes.join(','); @@ -26,9 +26,9 @@ String acceptedTypesToString(List acceptedTypes) { /// Make sure that at least one of its fields is populated. void _assertTypeGroupIsValid(XTypeGroup group) { assert( - !((group.extensions == null || group.extensions.isEmpty) && - (group.mimeTypes == null || group.mimeTypes.isEmpty) && - (group.webWildCards == null || group.webWildCards.isEmpty)), + !((group.extensions == null || group.extensions!.isEmpty) && + (group.mimeTypes == null || group.mimeTypes!.isEmpty) && + (group.webWildCards == null || group.webWildCards!.isEmpty)), 'At least one of extensions / mimeTypes / webWildCards is required for web.'); } diff --git a/packages/file_selector/file_selector_web/pubspec.yaml b/packages/file_selector/file_selector_web/pubspec.yaml index a170d5f39607..55424a7a4c1c 100644 --- a/packages/file_selector/file_selector_web/pubspec.yaml +++ b/packages/file_selector/file_selector_web/pubspec.yaml @@ -1,7 +1,7 @@ name: file_selector_web description: Web platform implementation of file_selector homepage: https://github.com/flutter/plugins/tree/master/packages/file_selector/file_selector_web -version: 0.7.0+1 +version: 0.8.0 flutter: plugin: @@ -11,22 +11,18 @@ flutter: fileName: file_selector_web.dart dependencies: - file_selector_platform_interface: ^1.0.2 - platform_detect: ^1.4.0 + file_selector_platform_interface: ^2.0.0 flutter: sdk: flutter flutter_web_plugins: sdk: flutter - meta: ^1.1.7 + meta: ^1.3.0 dev_dependencies: flutter_test: sdk: flutter - mockito: ^4.1.1 - pedantic: ^1.8.0 - integration_test: - path: ../../integration_test + pedantic: ^1.10.0 environment: - sdk: ">=2.2.0 <3.0.0" - flutter: ">=1.10.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" diff --git a/packages/file_selector/file_selector_web/test/more_tests_exist_elsewhere_test.dart b/packages/file_selector/file_selector_web/test/more_tests_exist_elsewhere_test.dart new file mode 100644 index 000000000000..e9faa3af4808 --- /dev/null +++ b/packages/file_selector/file_selector_web/test/more_tests_exist_elsewhere_test.dart @@ -0,0 +1,10 @@ +import 'package:flutter_test/flutter_test.dart'; + +void main() { + test('Tell the user where to find the real tests', () { + print('---'); + print('This package also uses integration_test to run additional tests.'); + print('See `example/README.md` for more info.'); + print('---'); + }); +} diff --git a/packages/file_selector/file_selector_web/test/utils_test.dart b/packages/file_selector/file_selector_web/test/utils_test.dart index 9fa187eede5b..e3e47c00f176 100644 --- a/packages/file_selector/file_selector_web/test/utils_test.dart +++ b/packages/file_selector/file_selector_web/test/utils_test.dart @@ -2,8 +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 'package:flutter_test/flutter_test.dart'; import 'package:file_selector_web/src/utils.dart'; import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; From 82016374219b0433a3bf2de62e7f01f349d6c039 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Wed, 24 Feb 2021 18:49:33 -0800 Subject: [PATCH 0209/1565] [device_info] null safety stable (#3626) --- packages/device_info/device_info/CHANGELOG.md | 11 ++--------- packages/device_info/device_info/example/pubspec.yaml | 4 ++-- packages/device_info/device_info/pubspec.yaml | 10 +++++----- 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/packages/device_info/device_info/CHANGELOG.md b/packages/device_info/device_info/CHANGELOG.md index 910d265b7c3e..f849131eff19 100644 --- a/packages/device_info/device_info/CHANGELOG.md +++ b/packages/device_info/device_info/CHANGELOG.md @@ -1,14 +1,7 @@ -## 2.0.0-nullsafety.2 - -* Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) - -## 2.0.0-nullsafety.1 - -* Bump Dart SDK to support null safety. - -## 2.0.0-nullsafety +## 2.0.0 * Migrate to null safety. +* Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) ## 1.0.1 diff --git a/packages/device_info/device_info/example/pubspec.yaml b/packages/device_info/device_info/example/pubspec.yaml index 1f636977c2a9..bc7d00ef87f0 100644 --- a/packages/device_info/device_info/example/pubspec.yaml +++ b/packages/device_info/device_info/example/pubspec.yaml @@ -17,11 +17,11 @@ dev_dependencies: sdk: flutter integration_test: path: ../../../integration_test - pedantic: ^1.10.0-nullsafety.1 + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.10.0-56.0.dev <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/device_info/device_info/pubspec.yaml b/packages/device_info/device_info/pubspec.yaml index bcdc7c8b54d1..0196338223a6 100644 --- a/packages/device_info/device_info/pubspec.yaml +++ b/packages/device_info/device_info/pubspec.yaml @@ -2,7 +2,7 @@ name: device_info description: Flutter plugin providing detailed information about the device (make, model, etc.), and Android or iOS version the app is running on. homepage: https://github.com/flutter/plugins/tree/master/packages/device_info -version: 2.0.0-nullsafety.2 +version: 2.0.0 flutter: plugin: @@ -16,13 +16,13 @@ flutter: dependencies: flutter: sdk: flutter - device_info_platform_interface: ^2.0.0-nullsafety.1 + device_info_platform_interface: ^2.0.0 dev_dependencies: - test: ^1.10.0-nullsafety.1 + test: ^1.16.3 flutter_test: sdk: flutter - pedantic: ^1.10.0-nullsafety.1 + pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" From 494e9f912eb1976c34f59ee1fda7253364be281d Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Wed, 24 Feb 2021 20:01:03 -0800 Subject: [PATCH 0210/1565] [file_selector] Return a non-null value from getSavePath on web (#3630) --- packages/file_selector/file_selector_web/CHANGELOG.md | 5 +++++ .../example/integration_test/file_selector_web_test.dart | 8 ++++++++ .../file_selector_web/lib/file_selector_web.dart | 5 ++++- packages/file_selector/file_selector_web/pubspec.yaml | 2 +- 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/file_selector/file_selector_web/CHANGELOG.md b/packages/file_selector/file_selector_web/CHANGELOG.md index 4caad4b975f9..3eb7c3b94494 100644 --- a/packages/file_selector/file_selector_web/CHANGELOG.md +++ b/packages/file_selector/file_selector_web/CHANGELOG.md @@ -1,3 +1,8 @@ +# 0.8.1 + +- Return a non-null value from `getSavePath` for consistency with + API expectations that null indicates canceling. + # 0.8.0 - Migrated to null-safety diff --git a/packages/file_selector/file_selector_web/example/integration_test/file_selector_web_test.dart b/packages/file_selector/file_selector_web/example/integration_test/file_selector_web_test.dart index 5442fedf5408..ea9569bf00a9 100644 --- a/packages/file_selector/file_selector_web/example/integration_test/file_selector_web_test.dart +++ b/packages/file_selector/file_selector_web/example/integration_test/file_selector_web_test.dart @@ -73,6 +73,14 @@ void main() { expect(await files[1].lastModified(), isNotNull); }); }); + + group('getSavePath', () { + testWidgets('returns non-null', (WidgetTester _) async { + final plugin = FileSelectorWeb(); + final savePath = plugin.getSavePath(); + expect(await savePath, isNotNull); + }); + }); }); } diff --git a/packages/file_selector/file_selector_web/lib/file_selector_web.dart b/packages/file_selector/file_selector_web/lib/file_selector_web.dart index 1c411ca0a2f0..cf95e403effc 100644 --- a/packages/file_selector/file_selector_web/lib/file_selector_web.dart +++ b/packages/file_selector/file_selector_web/lib/file_selector_web.dart @@ -45,6 +45,9 @@ class FileSelectorWeb extends FileSelectorPlatform { return _openFiles(acceptedTypeGroups: acceptedTypeGroups, multiple: true); } + // This is intended to be passed to XFile, which ignores the path, but 'null' + // indicates a canceled save on other platforms, so provide a non-null dummy + // value. @override Future getSavePath({ List? acceptedTypeGroups, @@ -52,7 +55,7 @@ class FileSelectorWeb extends FileSelectorPlatform { String? suggestedName, String? confirmButtonText, }) async => - null; + ''; @override Future getDirectoryPath({ diff --git a/packages/file_selector/file_selector_web/pubspec.yaml b/packages/file_selector/file_selector_web/pubspec.yaml index 55424a7a4c1c..17f0f476cbac 100644 --- a/packages/file_selector/file_selector_web/pubspec.yaml +++ b/packages/file_selector/file_selector_web/pubspec.yaml @@ -1,7 +1,7 @@ name: file_selector_web description: Web platform implementation of file_selector homepage: https://github.com/flutter/plugins/tree/master/packages/file_selector/file_selector_web -version: 0.8.0 +version: 0.8.1 flutter: plugin: From 98e289b95733fe78287cc08c6d99fb70f55a2bf4 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Wed, 24 Feb 2021 20:17:34 -0800 Subject: [PATCH 0211/1565] [cross_file] Fix base class nullability (#3629) Without this, the dummy ("interface") XFile implementation of these properties has different nullability than the others, and the analyzer doesn't match what the runtime actually sees. --- packages/cross_file/CHANGELOG.md | 5 +++++ packages/cross_file/lib/src/types/base.dart | 4 ++-- packages/cross_file/pubspec.yaml | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/cross_file/CHANGELOG.md b/packages/cross_file/CHANGELOG.md index 5bbb43f9e882..94bf4b29322a 100644 --- a/packages/cross_file/CHANGELOG.md +++ b/packages/cross_file/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.3.1 + +* Fix nullability of `XFileBase`'s `path` and `name` to match the + implementations to avoid potential analyzer issues. + ## 0.3.0 * Migrated package to null-safety. diff --git a/packages/cross_file/lib/src/types/base.dart b/packages/cross_file/lib/src/types/base.dart index 2a59c1c2b246..4522b7343c9b 100644 --- a/packages/cross_file/lib/src/types/base.dart +++ b/packages/cross_file/lib/src/types/base.dart @@ -31,14 +31,14 @@ abstract class XFileBase { /// Accessing the data contained in the picked file by its path /// is platform-dependant (and won't work on web), so use the /// byte getters in the CrossFile instance instead. - String? get path { + String get path { throw UnimplementedError('.path has not been implemented.'); } /// The name of the file as it was selected by the user in their device. /// /// Use only for cosmetic reasons, do not try to use this as a path. - String? get name { + String get name { throw UnimplementedError('.name has not been implemented.'); } diff --git a/packages/cross_file/pubspec.yaml b/packages/cross_file/pubspec.yaml index 8e09b21d4536..66d3f46a84e3 100644 --- a/packages/cross_file/pubspec.yaml +++ b/packages/cross_file/pubspec.yaml @@ -1,7 +1,7 @@ name: cross_file description: An abstraction to allow working with files across multiple platforms. homepage: https://github.com/flutter/plugins/tree/master/packages/cross_file -version: 0.3.0 +version: 0.3.1 dependencies: flutter: From bc11badd441bebe2a28f8e9d5c63effae8eb133b Mon Sep 17 00:00:00 2001 From: Rahul Raj <64.rahulraj@gmail.com> Date: Thu, 25 Feb 2021 10:45:42 +0530 Subject: [PATCH 0212/1565] [in_app_purchase] Add support for InApp subscription upgrade/downgrade (#2822) --- AUTHORS | 1 + packages/in_app_purchase/CHANGELOG.md | 4 + packages/in_app_purchase/README.md | 24 +++ .../inapppurchase/MethodCallHandlerImpl.java | 50 +++++- packages/in_app_purchase/example/README.md | 3 +- .../inapppurchase/MethodCallHandlerTest.java | 167 +++++++++++++++++- .../in_app_purchase/example/lib/main.dart | 43 ++++- .../billing_client_wrapper.dart | 55 +++++- .../enum_converters.dart | 22 +++ .../enum_converters.g.dart | 13 +- .../in_app_purchase/app_store_connection.dart | 9 + .../google_play_connection.dart | 6 +- .../src/in_app_purchase/purchase_details.dart | 35 +++- packages/in_app_purchase/pubspec.yaml | 2 +- .../billing_client_wrapper_test.dart | 58 ++++++ .../purchase_wrapper_test.dart | 14 ++ 16 files changed, 491 insertions(+), 15 deletions(-) diff --git a/AUTHORS b/AUTHORS index 1f2b9cba2f16..dbf9d190931b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -62,3 +62,4 @@ Juan Alvarez Aleksandr Yurkovskiy Anton Borries Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/CHANGELOG.md index 79f64d5bda53..0dbc2427ccd6 100644 --- a/packages/in_app_purchase/CHANGELOG.md +++ b/packages/in_app_purchase/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.1 + +* Support InApp subscription upgrade/downgrade. + ## 0.4.0 * Migrate to nullsafety. diff --git a/packages/in_app_purchase/README.md b/packages/in_app_purchase/README.md index 431f2810c165..321864b2a233 100644 --- a/packages/in_app_purchase/README.md +++ b/packages/in_app_purchase/README.md @@ -178,6 +178,30 @@ and `AppStore` that the purchase has been finished. WARNING! Failure to call `InAppPurchaseConnection.completePurchase` and get a successful response within 3 days of the purchase will result a refund. +### Upgrading or Downgrading an existing InApp Subscription + +In order to upgrade/downgrade an existing InApp subscription on `PlayStore`, +you need to provide an instance of `ChangeSubscriptionParam` with the old +`PurchaseDetails` that the user needs to migrate from, and an optional `ProrationMode` +with the `PurchaseParam` object while calling `InAppPurchaseConnection.buyNonConsumable`. +`AppStore` does not require this since they provides a subscription grouping mechanism. +Each subscription you offer must be assigned to a subscription group. +So the developers can group related subscriptions together to prevents users from +accidentally purchasing multiple subscriptions. +Please refer to the 'Creating a Subscription Group' sections of [Apple's subscription guide](https://developer.apple.com/app-store/subscriptions/) + + +```dart +final PurchaseDetails oldPurchaseDetails = ...; +PurchaseParam purchaseParam = PurchaseParam( + productDetails: productDetails, + changeSubscriptionParam: ChangeSubscriptionParam( + oldPurchaseDetails: oldPurchaseDetails, + prorationMode: ProrationMode.immediateWithTimeProration)); +InAppPurchaseConnection.instance + .buyNonConsumable(purchaseParam: purchaseParam); +``` + ## Development This plugin uses diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java index f1e715e239a2..58d077673a03 100644 --- a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java +++ b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java @@ -20,6 +20,7 @@ import com.android.billingclient.api.BillingClient; import com.android.billingclient.api.BillingClientStateListener; import com.android.billingclient.api.BillingFlowParams; +import com.android.billingclient.api.BillingFlowParams.ProrationMode; import com.android.billingclient.api.BillingResult; import com.android.billingclient.api.ConsumeParams; import com.android.billingclient.api.ConsumeResponseListener; @@ -39,6 +40,8 @@ class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler, Application.ActivityLifecycleCallbacks { private static final String TAG = "InAppPurchasePlugin"; + private static final String LOAD_SKU_DOC_URL = + "https://github.com/flutter/plugins/blob/master/packages/in_app_purchase/README.md#loading-products-for-sale"; @Nullable private BillingClient billingClient; private final BillingClientFactory billingClientFactory; @@ -120,7 +123,13 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) { break; case InAppPurchasePlugin.MethodNames.LAUNCH_BILLING_FLOW: launchBillingFlow( - (String) call.argument("sku"), (String) call.argument("accountId"), result); + (String) call.argument("sku"), + (String) call.argument("accountId"), + (String) call.argument("oldSku"), + call.hasArgument("prorationMode") + ? (int) call.argument("prorationMode") + : ProrationMode.UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY, + result); break; case InAppPurchasePlugin.MethodNames.QUERY_PURCHASES: queryPurchases((String) call.argument("skuType"), result); @@ -189,7 +198,11 @@ public void onSkuDetailsResponse( } private void launchBillingFlow( - String sku, @Nullable String accountId, MethodChannel.Result result) { + String sku, + @Nullable String accountId, + @Nullable String oldSku, + int prorationMode, + MethodChannel.Result result) { if (billingClientError(result)) { return; } @@ -198,7 +211,26 @@ private void launchBillingFlow( if (skuDetails == null) { result.error( "NOT_FOUND", - "Details for sku " + sku + " are not available. Has this ID already been fetched?", + String.format( + "Details for sku %s are not available. It might because skus were not fetched prior to the call. Please fetch the skus first. An example of how to fetch the skus could be found here: %s", + sku, LOAD_SKU_DOC_URL), + null); + return; + } + + if (oldSku == null + && prorationMode != ProrationMode.UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY) { + result.error( + "IN_APP_PURCHASE_REQUIRE_OLD_SKU", + "launchBillingFlow failed because oldSku is null. You must provide a valid oldSku in order to use a proration mode.", + null); + return; + } else if (oldSku != null && !cachedSkus.containsKey(oldSku)) { + result.error( + "IN_APP_PURCHASE_INVALID_OLD_SKU", + String.format( + "Details for sku %s are not available. It might because skus were not fetched prior to the call. Please fetch the skus first. An example of how to fetch the skus could be found here: %s", + oldSku, LOAD_SKU_DOC_URL), null); return; } @@ -218,6 +250,12 @@ private void launchBillingFlow( if (accountId != null && !accountId.isEmpty()) { paramsBuilder.setAccountId(accountId); } + if (oldSku != null && !oldSku.isEmpty()) { + paramsBuilder.setOldSku(oldSku); + } + // The proration mode value has to match one of the following declared in + // https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.ProrationMode + paramsBuilder.setReplaceSkusProrationMode(prorationMode); result.success( Translator.fromBillingResult( billingClient.launchBillingFlow(activity, paramsBuilder.build()))); @@ -252,7 +290,8 @@ private void queryPurchases(String skuType, MethodChannel.Result result) { return; } - // Like in our connect call, consider the billing client responding a "success" here regardless of status code. + // Like in our connect call, consider the billing client responding a "success" here regardless + // of status code. result.success(fromPurchasesResult(billingClient.queryPurchases(skuType))); } @@ -295,7 +334,8 @@ public void onBillingSetupFinished(BillingResult billingResult) { return; } alreadyFinished = true; - // Consider the fact that we've finished a success, leave it to the Dart side to validate the responseCode. + // Consider the fact that we've finished a success, leave it to the Dart side to + // validate the responseCode. result.success(Translator.fromBillingResult(billingResult)); } diff --git a/packages/in_app_purchase/example/README.md b/packages/in_app_purchase/example/README.md index 9fcad23d19ae..6dd5b38d7003 100644 --- a/packages/in_app_purchase/example/README.md +++ b/packages/in_app_purchase/example/README.md @@ -30,7 +30,8 @@ below. - `consumable`: A managed product. - `upgrade`: A managed product. - - `subscription`: A subscription. + - `subscription_silver`: A lower level subscription. + - `subscription_gold`: A higher level subscription. Make sure that all of the products are set to `ACTIVE`. diff --git a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java index c6a9b4114a75..cc7bc4a9b9b1 100644 --- a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java +++ b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java @@ -18,6 +18,7 @@ import static io.flutter.plugins.inapppurchase.Translator.fromSkuDetailsList; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; +import static java.util.Collections.unmodifiableList; import static java.util.stream.Collectors.toList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @@ -261,7 +262,7 @@ public void querySkuDetailsAsync_clientDisconnected() { } @Test - public void launchBillingFlow_ok_nullAccountId() { + public void launchBillingFlow_ok_null_AccountId() { // Fetch the sku details first and then prepare the launch billing flow call String skuId = "foo"; queryForSkus(singletonList(skuId)); @@ -292,6 +293,40 @@ public void launchBillingFlow_ok_nullAccountId() { verify(result, times(1)).success(fromBillingResult(billingResult)); } + @Test + public void launchBillingFlow_ok_null_OldSku() { + // Fetch the sku details first and then prepare the launch billing flow call + String skuId = "foo"; + String accountId = "account"; + queryForSkus(singletonList(skuId)); + HashMap arguments = new HashMap<>(); + arguments.put("sku", skuId); + arguments.put("accountId", accountId); + arguments.put("oldSku", null); + MethodCall launchCall = new MethodCall(LAUNCH_BILLING_FLOW, arguments); + + // Launch the billing flow + BillingResult billingResult = + BillingResult.newBuilder() + .setResponseCode(100) + .setDebugMessage("dummy debug message") + .build(); + when(mockBillingClient.launchBillingFlow(any(), any())).thenReturn(billingResult); + methodChannelHandler.onMethodCall(launchCall, result); + + // Verify we pass the arguments to the billing flow + ArgumentCaptor billingFlowParamsCaptor = + ArgumentCaptor.forClass(BillingFlowParams.class); + verify(mockBillingClient).launchBillingFlow(any(), billingFlowParamsCaptor.capture()); + BillingFlowParams params = billingFlowParamsCaptor.getValue(); + assertEquals(params.getSku(), skuId); + assertEquals(params.getAccountId(), accountId); + assertNull(params.getOldSku()); + // Verify we pass the response code to result + verify(result, never()).error(any(), any(), any()); + verify(result, times(1)).success(fromBillingResult(billingResult)); + } + @Test public void launchBillingFlow_ok_null_Activity() { methodChannelHandler.setActivity(null); @@ -311,6 +346,42 @@ public void launchBillingFlow_ok_null_Activity() { verify(result, never()).success(any()); } + @Test + public void launchBillingFlow_ok_oldSku() { + // Fetch the sku details first and query the method call + String skuId = "foo"; + String accountId = "account"; + String oldSkuId = "oldFoo"; + queryForSkus(unmodifiableList(asList(skuId, oldSkuId))); + HashMap arguments = new HashMap<>(); + arguments.put("sku", skuId); + arguments.put("accountId", accountId); + arguments.put("oldSku", oldSkuId); + MethodCall launchCall = new MethodCall(LAUNCH_BILLING_FLOW, arguments); + + // Launch the billing flow + BillingResult billingResult = + BillingResult.newBuilder() + .setResponseCode(100) + .setDebugMessage("dummy debug message") + .build(); + when(mockBillingClient.launchBillingFlow(any(), any())).thenReturn(billingResult); + methodChannelHandler.onMethodCall(launchCall, result); + + // Verify we pass the arguments to the billing flow + ArgumentCaptor billingFlowParamsCaptor = + ArgumentCaptor.forClass(BillingFlowParams.class); + verify(mockBillingClient).launchBillingFlow(any(), billingFlowParamsCaptor.capture()); + BillingFlowParams params = billingFlowParamsCaptor.getValue(); + assertEquals(params.getSku(), skuId); + assertEquals(params.getAccountId(), accountId); + assertEquals(params.getOldSku(), oldSkuId); + + // Verify we pass the response code to result + verify(result, never()).error(any(), any(), any()); + verify(result, times(1)).success(fromBillingResult(billingResult)); + } + @Test public void launchBillingFlow_ok_AccountId() { // Fetch the sku details first and query the method call @@ -344,6 +415,79 @@ public void launchBillingFlow_ok_AccountId() { verify(result, times(1)).success(fromBillingResult(billingResult)); } + @Test + public void launchBillingFlow_ok_Proration() { + // Fetch the sku details first and query the method call + String skuId = "foo"; + String oldSkuId = "oldFoo"; + String accountId = "account"; + int prorationMode = BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE; + queryForSkus(unmodifiableList(asList(skuId, oldSkuId))); + HashMap arguments = new HashMap<>(); + arguments.put("sku", skuId); + arguments.put("accountId", accountId); + arguments.put("oldSku", oldSkuId); + arguments.put("prorationMode", prorationMode); + MethodCall launchCall = new MethodCall(LAUNCH_BILLING_FLOW, arguments); + + // Launch the billing flow + BillingResult billingResult = + BillingResult.newBuilder() + .setResponseCode(100) + .setDebugMessage("dummy debug message") + .build(); + when(mockBillingClient.launchBillingFlow(any(), any())).thenReturn(billingResult); + methodChannelHandler.onMethodCall(launchCall, result); + + // Verify we pass the arguments to the billing flow + ArgumentCaptor billingFlowParamsCaptor = + ArgumentCaptor.forClass(BillingFlowParams.class); + verify(mockBillingClient).launchBillingFlow(any(), billingFlowParamsCaptor.capture()); + BillingFlowParams params = billingFlowParamsCaptor.getValue(); + assertEquals(params.getSku(), skuId); + assertEquals(params.getAccountId(), accountId); + assertEquals(params.getOldSku(), oldSkuId); + assertEquals(params.getReplaceSkusProrationMode(), prorationMode); + + // Verify we pass the response code to result + verify(result, never()).error(any(), any(), any()); + verify(result, times(1)).success(fromBillingResult(billingResult)); + } + + @Test + public void launchBillingFlow_ok_Proration_with_null_OldSku() { + // Fetch the sku details first and query the method call + String skuId = "foo"; + String accountId = "account"; + String queryOldSkuId = "oldFoo"; + String oldSkuId = null; + int prorationMode = BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE; + queryForSkus(unmodifiableList(asList(skuId, queryOldSkuId))); + HashMap arguments = new HashMap<>(); + arguments.put("sku", skuId); + arguments.put("accountId", accountId); + arguments.put("oldSku", oldSkuId); + arguments.put("prorationMode", prorationMode); + MethodCall launchCall = new MethodCall(LAUNCH_BILLING_FLOW, arguments); + + // Launch the billing flow + BillingResult billingResult = + BillingResult.newBuilder() + .setResponseCode(100) + .setDebugMessage("dummy debug message") + .build(); + when(mockBillingClient.launchBillingFlow(any(), any())).thenReturn(billingResult); + methodChannelHandler.onMethodCall(launchCall, result); + + // Assert that we sent an error back. + verify(result) + .error( + contains("IN_APP_PURCHASE_REQUIRE_OLD_SKU"), + contains("launchBillingFlow failed because oldSku is null"), + any()); + verify(result, never()).success(any()); + } + @Test public void launchBillingFlow_clientDisconnected() { // Prepare the launch call after disconnecting the client @@ -381,6 +525,27 @@ public void launchBillingFlow_skuNotFound() { verify(result, never()).success(any()); } + @Test + public void launchBillingFlow_oldSkuNotFound() { + // Try to launch the billing flow for a random sku ID + establishConnectedBillingClient(null, null); + String skuId = "foo"; + String accountId = "account"; + String oldSkuId = "oldSku"; + queryForSkus(singletonList(skuId)); + HashMap arguments = new HashMap<>(); + arguments.put("sku", skuId); + arguments.put("accountId", accountId); + arguments.put("oldSku", oldSkuId); + MethodCall launchCall = new MethodCall(LAUNCH_BILLING_FLOW, arguments); + + methodChannelHandler.onMethodCall(launchCall, result); + + // Assert that we sent an error back. + verify(result).error(contains("IN_APP_PURCHASE_INVALID_OLD_SKU"), contains(oldSkuId), any()); + verify(result, never()).success(any()); + } + @Test public void queryPurchases() { establishConnectedBillingClient(null, null); diff --git a/packages/in_app_purchase/example/lib/main.dart b/packages/in_app_purchase/example/lib/main.dart index 82cd509b30be..c9f0bb6ece25 100644 --- a/packages/in_app_purchase/example/lib/main.dart +++ b/packages/in_app_purchase/example/lib/main.dart @@ -19,10 +19,14 @@ void main() { const bool _kAutoConsume = true; const String _kConsumableId = 'consumable'; +const String _kUpgradeId = 'upgrade'; +const String _kSilverSubscriptionId = 'subscription_silver'; +const String _kGoldSubscriptionId = 'subscription_gold'; const List _kProductIds = [ _kConsumableId, - 'upgrade', - 'subscription' + _kUpgradeId, + _kSilverSubscriptionId, + _kGoldSubscriptionId, ]; class _MyApp extends StatefulWidget { @@ -252,9 +256,22 @@ class _MyAppState extends State<_MyApp> { primary: Colors.white, ), onPressed: () { + // NOTE: If you are making a subscription purchase/upgrade/downgrade, we recommend you to + // verify the latest status of you your subscription by using server side receipt validation + // and update the UI accordingly. The subscription purchase status shown + // inside the app may not be accurate. + final oldSubscription = + _getOldSubscription(productDetails, purchases); PurchaseParam purchaseParam = PurchaseParam( productDetails: productDetails, - applicationUserName: null); + applicationUserName: null, + changeSubscriptionParam: Platform.isAndroid && + oldSubscription != null + ? ChangeSubscriptionParam( + oldPurchaseDetails: oldSubscription, + prorationMode: + ProrationMode.immediateWithTimeProration) + : null); if (productDetails.id == _kConsumableId) { _connection.buyConsumable( purchaseParam: purchaseParam, @@ -387,4 +404,24 @@ class _MyAppState extends State<_MyApp> { } }); } + + PurchaseDetails? _getOldSubscription( + ProductDetails productDetails, Map purchases) { + // This is just to demonstrate a subscription upgrade or downgrade. + // This method assumes that you have only 2 subscriptions under a group, 'subscription_silver' & 'subscription_gold'. + // The 'subscription_silver' subscription can be upgraded to 'subscription_gold' and + // the 'subscription_gold' subscription can be downgraded to 'subscription_silver'. + // Please remember to replace the logic of finding the old subscription Id as per your app. + // The old subscription is only required on Android since Apple handles this internally + // by using the subscription group feature in iTunesConnect. + PurchaseDetails? oldSubscription; + if (productDetails.id == _kSilverSubscriptionId && + purchases[_kGoldSubscriptionId] != null) { + oldSubscription = purchases[_kGoldSubscriptionId]; + } else if (productDetails.id == _kGoldSubscriptionId && + purchases[_kSilverSubscriptionId] != null) { + oldSubscription = purchases[_kSilverSubscriptionId]; + } + return oldSubscription; + } } diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart index 9f96c05e15f9..a0ba91556094 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart @@ -173,12 +173,25 @@ class BillingClient { /// skuDetails](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.Builder.html#setskudetails) /// and [the given /// accountId](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.Builder.html#setAccountId(java.lang.String)). + /// + /// When this method is called to purchase a subscription, an optional `oldSku` + /// can be passed in. This will tell Google Play that rather than purchasing a new subscription, + /// the user needs to upgrade/downgrade the existing subscription. + /// The [oldSku](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.Builder#setoldsku) is the SKU id that the user is upgrading or downgrading from. + /// The [prorationMode](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.Builder#setreplaceskusprorationmode) is the mode of proration during subscription upgrade/downgrade. + /// This value will only be effective if the `oldSku` is also set. Future launchBillingFlow( - {required String sku, String? accountId}) async { + {required String sku, + String? accountId, + String? oldSku, + ProrationMode? prorationMode}) async { assert(sku != null); final Map arguments = { 'sku': sku, 'accountId': accountId, + 'oldSku': oldSku, + 'prorationMode': ProrationModeConverter().toJson(prorationMode ?? + ProrationMode.unknownSubscriptionUpgradeDowngradePolicy) }; return BillingResultWrapper.fromJson( (await channel.invokeMapMethod( @@ -390,3 +403,43 @@ enum SkuType { @JsonValue('subs') subs, } + +/// Enum representing the proration mode. +/// +/// When upgrading or downgrading a subscription, set this mode to provide details +/// about the proration that will be applied when the subscription changes. +/// +/// Wraps [`BillingFlowParams.ProrationMode`](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.ProrationMode) +/// See the linked documentation for an explanation of the different constants. +enum ProrationMode { +// WARNING: Changes to this class need to be reflected in our generated code. +// Run `flutter packages pub run build_runner watch` to rebuild and watch for +// further changes. + + /// Unknown upgrade or downgrade policy. + @JsonValue(0) + unknownSubscriptionUpgradeDowngradePolicy, + + /// Replacement takes effect immediately, and the remaining time will be prorated and credited to the user. + /// + /// This is the current default behavior. + @JsonValue(1) + immediateWithTimeProration, + + /// Replacement takes effect immediately, and the billing cycle remains the same. + /// + /// The price for the remaining period will be charged. + /// This option is only available for subscription upgrade. + @JsonValue(2) + immediateAndChargeProratedPrice, + + /// Replacement takes effect immediately, and the new price will be charged on next recurrence time. + /// + /// The billing cycle stays the same. + @JsonValue(3) + immediateWithoutProration, + + /// Replacement takes effect when the old plan expires, and the new price will be charged at the same time. + @JsonValue(4) + deferred, +} diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart index 30828d8882a7..469d71b63637 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart @@ -50,12 +50,34 @@ class SkuTypeConverter implements JsonConverter { String toJson(SkuType object) => _$SkuTypeEnumMap[object]!; } +/// Serializer for [ProrationMode]. +/// +/// Use these in `@JsonSerializable()` classes by annotating them with +/// `@ProrationModeConverter()`. +class ProrationModeConverter implements JsonConverter { + /// Default const constructor. + const ProrationModeConverter(); + + @override + ProrationMode fromJson(int? json) { + if (json == null) { + return ProrationMode.unknownSubscriptionUpgradeDowngradePolicy; + } + return _$enumDecode( + _$ProrationModeEnumMap.cast(), json); + } + + @override + int toJson(ProrationMode object) => _$ProrationModeEnumMap[object]!; +} + // Define a class so we generate serializer helper methods for the enums @JsonSerializable() class _SerializedEnums { late BillingResponse response; late SkuType type; late PurchaseStateWrapper purchaseState; + late ProrationMode prorationMode; } /// Serializer for [PurchaseStateWrapper]. diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.g.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.g.dart index 5d59dd8888b7..4186a2a24252 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.g.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.g.dart @@ -11,7 +11,9 @@ _SerializedEnums _$_SerializedEnumsFromJson(Map json) { ..response = _$enumDecode(_$BillingResponseEnumMap, json['response']) ..type = _$enumDecode(_$SkuTypeEnumMap, json['type']) ..purchaseState = - _$enumDecode(_$PurchaseStateWrapperEnumMap, json['purchaseState']); + _$enumDecode(_$PurchaseStateWrapperEnumMap, json['purchaseState']) + ..prorationMode = + _$enumDecode(_$ProrationModeEnumMap, json['prorationMode']); } Map _$_SerializedEnumsToJson(_SerializedEnums instance) => @@ -19,6 +21,7 @@ Map _$_SerializedEnumsToJson(_SerializedEnums instance) => 'response': _$BillingResponseEnumMap[instance.response], 'type': _$SkuTypeEnumMap[instance.type], 'purchaseState': _$PurchaseStateWrapperEnumMap[instance.purchaseState], + 'prorationMode': _$ProrationModeEnumMap[instance.prorationMode], }; K _$enumDecode( @@ -72,3 +75,11 @@ const _$PurchaseStateWrapperEnumMap = { PurchaseStateWrapper.purchased: 1, PurchaseStateWrapper.pending: 2, }; + +const _$ProrationModeEnumMap = { + ProrationMode.unknownSubscriptionUpgradeDowngradePolicy: 0, + ProrationMode.immediateWithTimeProration: 1, + ProrationMode.immediateAndChargeProratedPrice: 2, + ProrationMode.immediateWithoutProration: 3, + ProrationMode.deferred: 4, +}; diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart b/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart index 50560a666a40..d4601fd809db 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart @@ -56,6 +56,15 @@ class AppStoreConnection implements InAppPurchaseConnection { @override Future buyNonConsumable({required PurchaseParam purchaseParam}) async { + assert( + purchaseParam.changeSubscriptionParam == null, + "`purchaseParam.changeSubscriptionParam` must be null. It is not supported on iOS " + "as Apple provides a subscription grouping mechanism. " + "Each subscription you offer must be assigned to a subscription group. " + "So the developers can group related subscriptions together to prevents users " + "from accidentally purchasing multiple subscriptions. " + "Please refer to the 'Creating a Subscription Group' sections of " + "Apple's subscription guide (https://developer.apple.com/app-store/subscriptions/)"); await _skPaymentQueueWrapper.addPayment(SKPaymentWrapper( productIdentifier: purchaseParam.productDetails.id, quantity: 1, diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart b/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart index ef0b7d2efa59..1a47f3ebd095 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart @@ -63,7 +63,11 @@ class GooglePlayConnection BillingResultWrapper billingResultWrapper = await billingClient.launchBillingFlow( sku: purchaseParam.productDetails.id, - accountId: purchaseParam.applicationUserName); + accountId: purchaseParam.applicationUserName, + oldSku: purchaseParam + .changeSubscriptionParam?.oldPurchaseDetails.productID, + prorationMode: + purchaseParam.changeSubscriptionParam?.prorationMode); return billingResultWrapper.responseCode == BillingResponse.ok; } diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart b/packages/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart index c211d2a4cdb8..b4a509055f14 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart @@ -90,7 +90,8 @@ class PurchaseParam { {required this.productDetails, this.applicationUserName, this.sandboxTesting = false, - this.simulatesAskToBuyInSandbox = false}); + this.simulatesAskToBuyInSandbox = false, + this.changeSubscriptionParam}); /// The product to create payment for. /// @@ -117,6 +118,38 @@ class PurchaseParam { /// /// See also [SKPaymentWrapper.simulatesAskToBuyInSandbox]. final bool simulatesAskToBuyInSandbox; + + /// The 'changeSubscriptionParam' is only available on Android, for upgrading or + /// downgrading an existing subscription. + /// + /// This does not require on iOS since Apple provides a way to group related subscriptions + /// together in iTunesConnect. So when a subscription upgrade or downgrade is requested, + /// Apple finds the old subscription details from the group and handle it automatically. + final ChangeSubscriptionParam? changeSubscriptionParam; +} + +/// This parameter object which is only applicable on Android for upgrading or downgrading an existing subscription. +/// +/// This does not require on iOS since iTunesConnect provides a subscription grouping mechanism. +/// Each subscription you offer must be assigned to a subscription group. +/// So the developers can group related subscriptions together to prevent users from +/// accidentally purchasing multiple subscriptions. +/// +/// Please refer to the 'Creating a Subscription Group' sections of [Apple's subscription guide](https://developer.apple.com/app-store/subscriptions/) +class ChangeSubscriptionParam { + /// Creates a new change subscription param object with given data + ChangeSubscriptionParam( + {required this.oldPurchaseDetails, this.prorationMode}); + + /// The purchase object of the existing subscription that the user needs to + /// upgrade/downgrade from. + final PurchaseDetails oldPurchaseDetails; + + /// The proration mode. + /// + /// This is an optional parameter that indicates how to handle the existing + /// subscription when the new subscription comes into effect. + final ProrationMode? prorationMode; } /// Represents the transaction details of a purchase. diff --git a/packages/in_app_purchase/pubspec.yaml b/packages/in_app_purchase/pubspec.yaml index f847a81291be..6175e8cbf1dc 100644 --- a/packages/in_app_purchase/pubspec.yaml +++ b/packages/in_app_purchase/pubspec.yaml @@ -1,7 +1,7 @@ name: in_app_purchase description: A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases through the App Store and Google Play. homepage: https://github.com/flutter/plugins/tree/master/packages/in_app_purchase -version: 0.4.0 +version: 0.4.1 dependencies: flutter: diff --git a/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart b/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart index d415007284c8..3aa62ddd96a1 100644 --- a/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart +++ b/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart @@ -207,6 +207,64 @@ void main() { expect(arguments['accountId'], equals(accountId)); }); + test( + 'serializes and deserializes data on change subscription without proration', + () async { + const String debugMessage = 'dummy message'; + final BillingResponse responseCode = BillingResponse.ok; + final BillingResultWrapper expectedBillingResult = BillingResultWrapper( + responseCode: responseCode, debugMessage: debugMessage); + stubPlatform.addResponse( + name: launchMethodName, + value: buildBillingResultMap(expectedBillingResult), + ); + final SkuDetailsWrapper skuDetails = dummySkuDetails; + final String accountId = "hashedAccountId"; + + expect( + await billingClient.launchBillingFlow( + sku: skuDetails.sku, + accountId: accountId, + oldSku: dummyOldPurchase.sku), + equals(expectedBillingResult)); + Map arguments = + stubPlatform.previousCallMatching(launchMethodName).arguments; + expect(arguments['sku'], equals(skuDetails.sku)); + expect(arguments['accountId'], equals(accountId)); + expect(arguments['oldSku'], equals(dummyOldPurchase.sku)); + }); + + test( + 'serializes and deserializes data on change subscription with proration', + () async { + const String debugMessage = 'dummy message'; + final BillingResponse responseCode = BillingResponse.ok; + final BillingResultWrapper expectedBillingResult = BillingResultWrapper( + responseCode: responseCode, debugMessage: debugMessage); + stubPlatform.addResponse( + name: launchMethodName, + value: buildBillingResultMap(expectedBillingResult), + ); + final SkuDetailsWrapper skuDetails = dummySkuDetails; + final String accountId = "hashedAccountId"; + final prorationMode = ProrationMode.immediateAndChargeProratedPrice; + + expect( + await billingClient.launchBillingFlow( + sku: skuDetails.sku, + accountId: accountId, + oldSku: dummyOldPurchase.sku, + prorationMode: prorationMode), + equals(expectedBillingResult)); + Map arguments = + stubPlatform.previousCallMatching(launchMethodName).arguments; + expect(arguments['sku'], equals(skuDetails.sku)); + expect(arguments['accountId'], equals(accountId)); + expect(arguments['oldSku'], equals(dummyOldPurchase.sku)); + expect(arguments['prorationMode'], + ProrationModeConverter().toJson(prorationMode)); + }); + test('handles null accountId', () async { const String debugMessage = 'dummy message'; final BillingResponse responseCode = BillingResponse.ok; diff --git a/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart b/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart index 7f3de2742603..df5b8f5bde22 100644 --- a/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart +++ b/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart @@ -46,6 +46,20 @@ final PurchaseHistoryRecordWrapper dummyPurchaseHistoryRecord = developerPayload: 'dummy payload', ); +final PurchaseWrapper dummyOldPurchase = PurchaseWrapper( + orderId: 'oldOrderId', + packageName: 'oldPackageName', + purchaseTime: 0, + signature: 'oldSignature', + sku: 'oldSku', + purchaseToken: 'oldPurchaseToken', + isAutoRenewing: false, + originalJson: '', + developerPayload: 'old dummy payload', + isAcknowledged: true, + purchaseState: PurchaseStateWrapper.purchased, +); + void main() { group('PurchaseWrapper', () { test('converts from map', () { From a109b3c76fd01c3e09befe6535c7331d4a79543d Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Wed, 24 Feb 2021 21:39:20 -0800 Subject: [PATCH 0213/1565] [wifi_info_flutter] null safety stable (#3627) --- packages/wifi_info_flutter/wifi_info_flutter/CHANGELOG.md | 2 +- .../wifi_info_flutter/example/lib/main.dart | 8 ++++---- .../wifi_info_flutter/example/pubspec.yaml | 5 ++--- .../test_driver/integration_test/wifi_info_test.dart | 1 + .../example/test_driver/test/integration_test.dart | 1 + packages/wifi_info_flutter/wifi_info_flutter/pubspec.yaml | 6 +++--- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/wifi_info_flutter/wifi_info_flutter/CHANGELOG.md b/packages/wifi_info_flutter/wifi_info_flutter/CHANGELOG.md index c98140eedcf0..c76009ec95fb 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/CHANGELOG.md +++ b/packages/wifi_info_flutter/wifi_info_flutter/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.0.0-nullsafety +## 2.0.0 * Migrate to null safety. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/lib/main.dart b/packages/wifi_info_flutter/wifi_info_flutter/example/lib/main.dart index 8c64c5d9a421..b92e55028a45 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/lib/main.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/lib/main.dart @@ -42,7 +42,7 @@ class MyApp extends StatelessWidget { } class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); + MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @@ -54,7 +54,7 @@ class _MyHomePageState extends State { String _connectionStatus = 'Unknown'; final Connectivity _connectivity = Connectivity(); final WifiInfo _wifiInfo = WifiInfo(); - StreamSubscription _connectivitySubscription; + late StreamSubscription _connectivitySubscription; @override void initState() { @@ -72,7 +72,7 @@ class _MyHomePageState extends State { // Platform messages are asynchronous, so we initialize in an async method. Future initConnectivity() async { - ConnectivityResult result; + late ConnectivityResult result; // Platform messages may fail, so we use a try/catch PlatformException. try { result = await _connectivity.checkConnectivity(); @@ -103,7 +103,7 @@ class _MyHomePageState extends State { Future _updateConnectionStatus(ConnectivityResult result) async { switch (result) { case ConnectivityResult.wifi: - String wifiName, wifiBSSID, wifiIP; + String? wifiName, wifiBSSID, wifiIP; try { if (!kIsWeb && Platform.isIOS) { diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/pubspec.yaml b/packages/wifi_info_flutter/wifi_info_flutter/example/pubspec.yaml index 0f0adbf7b4a1..bd424859abf2 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/pubspec.yaml +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/pubspec.yaml @@ -3,10 +3,10 @@ description: Demonstrates how to use the wifi_info_flutter plugin. publish_to: 'none' environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" dependencies: - connectivity: 0.4.9+3 + connectivity: ^3.0.0 flutter: sdk: flutter wifi_info_flutter: @@ -16,7 +16,6 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - cupertino_icons: ^1.0.0 dev_dependencies: integration_test: diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/integration_test/wifi_info_test.dart b/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/integration_test/wifi_info_test.dart index 103dc54a1eaa..6fe4737ae7a1 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/integration_test/wifi_info_test.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/integration_test/wifi_info_test.dart @@ -2,6 +2,7 @@ // 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 'package:integration_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/test/integration_test.dart b/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/test/integration_test.dart index 8a77ec87bbac..d59272c77431 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/test/integration_test.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/test/integration_test.dart @@ -2,6 +2,7 @@ // 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:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; diff --git a/packages/wifi_info_flutter/wifi_info_flutter/pubspec.yaml b/packages/wifi_info_flutter/wifi_info_flutter/pubspec.yaml index 0fbc27866201..7b58d481f6c7 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/pubspec.yaml +++ b/packages/wifi_info_flutter/wifi_info_flutter/pubspec.yaml @@ -1,16 +1,16 @@ name: wifi_info_flutter description: A new flutter plugin project. -version: 2.0.0-nullsafety homepage: https://github.com/flutter/plugins/tree/master/packages/wifi_info_flutter/wifi_info_flutter +version: 2.0.0 environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.20.0" dependencies: flutter: sdk: flutter - wifi_info_flutter_platform_interface: ^2.0.0-nullsafety + wifi_info_flutter_platform_interface: ^2.0.0 dev_dependencies: integration_test: From fff1420b2860e18ab3738ec065ae97891a83b552 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 25 Feb 2021 09:54:42 +0100 Subject: [PATCH 0214/1565] [camera_platform_interface] Stable null safety release. (#3610) * Stable null safety release camera_platform_interface * Update minimum plugin_platform_interface version * Update version of cross_file to 0.3.1 --- .../camera_platform_interface/CHANGELOG.md | 4 ++-- .../camera_platform_interface/pubspec.yaml | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/camera/camera_platform_interface/CHANGELOG.md b/packages/camera/camera_platform_interface/CHANGELOG.md index ab3d559bf2fb..f7f78197d204 100644 --- a/packages/camera/camera_platform_interface/CHANGELOG.md +++ b/packages/camera/camera_platform_interface/CHANGELOG.md @@ -1,6 +1,6 @@ -## 2.0.0-nullsafety +## 2.0.0 -- Migrate to null safety. +- Stable null safety release. ## 1.6.0 diff --git a/packages/camera/camera_platform_interface/pubspec.yaml b/packages/camera/camera_platform_interface/pubspec.yaml index 5817ce5c3fb0..10897073dc5c 100644 --- a/packages/camera/camera_platform_interface/pubspec.yaml +++ b/packages/camera/camera_platform_interface/pubspec.yaml @@ -3,22 +3,22 @@ description: A common platform interface for the camera plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0-nullsafety +version: 2.0.0 dependencies: flutter: sdk: flutter - meta: ^1.3.0-nullsafety.6 - plugin_platform_interface: ^1.1.0-nullsafety.2 - cross_file: ^0.3.0-nullsafety - stream_transform: ^2.0.0-nullsafety.0 + meta: ^1.3.0 + plugin_platform_interface: ">=1.0.0 <3.0.0" + cross_file: ^0.3.1 + stream_transform: ^2.0.0 dev_dependencies: flutter_test: sdk: flutter - async: ^2.5.0-nullsafety.3 - pedantic: ^1.10.0-nullsafety.3 + async: ^2.5.0 + pedantic: ^1.10.0 environment: - sdk: '>=2.12.0-0 <3.0.0' + sdk: '>=2.12.0-259.9.beta <3.0.0' flutter: ">=1.22.0" From 1de6d96f5b06b0657a21680a2a55a77b1be95808 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Thu, 25 Feb 2021 08:42:04 -0800 Subject: [PATCH 0215/1565] [file_selector] Migrate to null safety (#3631) Migrates the app-facing package to null safety. Includes replacing Mockito with a custom fake/mock. Fixes an issue where the example didn't handle dialogs being canceled, which was highlighted by the NNBD migration. (Previously, they would cause null assertions at runtime, which wasn't noticed during development. NNBD for the win!) Fixes flutter/flutter#75235 --- .../file_selector/file_selector/CHANGELOG.md | 4 + .../example/lib/get_directory_page.dart | 6 +- .../example/lib/open_image_page.dart | 4 + .../lib/open_multiple_images_page.dart | 4 + .../example/lib/open_text_page.dart | 6 +- .../example/lib/save_text_page.dart | 6 +- .../file_selector/example/pubspec.yaml | 57 +---- .../file_selector/lib/file_selector.dart | 30 +-- .../file_selector/file_selector/pubspec.yaml | 15 +- .../test/file_selector_test.dart | 203 +++++++++++++----- 10 files changed, 197 insertions(+), 138 deletions(-) diff --git a/packages/file_selector/file_selector/CHANGELOG.md b/packages/file_selector/file_selector/CHANGELOG.md index fe01ffec47b6..64ac5959a7c0 100644 --- a/packages/file_selector/file_selector/CHANGELOG.md +++ b/packages/file_selector/file_selector/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.8.0 + +Migrate to null safety. + ## 0.7.0+2 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. diff --git a/packages/file_selector/file_selector/example/lib/get_directory_page.dart b/packages/file_selector/file_selector/example/lib/get_directory_page.dart index 6463fb532957..cf4cde9fa9a8 100644 --- a/packages/file_selector/file_selector/example/lib/get_directory_page.dart +++ b/packages/file_selector/file_selector/example/lib/get_directory_page.dart @@ -5,9 +5,13 @@ import 'package:flutter/material.dart'; class GetDirectoryPage extends StatelessWidget { void _getDirectoryPath(BuildContext context) async { final String confirmButtonText = 'Choose'; - final String directoryPath = await getDirectoryPath( + final String? directoryPath = await getDirectoryPath( confirmButtonText: confirmButtonText, ); + if (directoryPath == null) { + // Operation was canceled by the user. + return; + } await showDialog( context: context, builder: (context) => TextDisplay(directoryPath), diff --git a/packages/file_selector/file_selector/example/lib/open_image_page.dart b/packages/file_selector/file_selector/example/lib/open_image_page.dart index 593a1d60aed8..986bfe712893 100644 --- a/packages/file_selector/file_selector/example/lib/open_image_page.dart +++ b/packages/file_selector/file_selector/example/lib/open_image_page.dart @@ -11,6 +11,10 @@ class OpenImagePage extends StatelessWidget { extensions: ['jpg', 'png'], ); final List files = await openFiles(acceptedTypeGroups: [typeGroup]); + if (files.isEmpty) { + // Operation was canceled by the user. + return; + } final XFile file = files[0]; final String fileName = file.name; final String filePath = file.path; diff --git a/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart b/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart index 58b59cd91b03..c6f73f5aed12 100644 --- a/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart +++ b/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart @@ -18,6 +18,10 @@ class OpenMultipleImagesPage extends StatelessWidget { jpgsTypeGroup, pngTypeGroup, ]); + if (files.isEmpty) { + // Operation was canceled by the user. + return; + } await showDialog( context: context, builder: (context) => MultipleImagesDisplay(files), diff --git a/packages/file_selector/file_selector/example/lib/open_text_page.dart b/packages/file_selector/file_selector/example/lib/open_text_page.dart index 299d0e2dc21a..74d79dd72b19 100644 --- a/packages/file_selector/file_selector/example/lib/open_text_page.dart +++ b/packages/file_selector/file_selector/example/lib/open_text_page.dart @@ -8,7 +8,11 @@ class OpenTextPage extends StatelessWidget { label: 'text', extensions: ['txt', 'json'], ); - final XFile file = await openFile(acceptedTypeGroups: [typeGroup]); + final XFile? file = await openFile(acceptedTypeGroups: [typeGroup]); + if (file == null) { + // Operation was canceled by the user. + return; + } final String fileName = file.name; final String fileContent = await file.readAsString(); diff --git a/packages/file_selector/file_selector/example/lib/save_text_page.dart b/packages/file_selector/file_selector/example/lib/save_text_page.dart index 47408662ecee..82046c35128a 100644 --- a/packages/file_selector/file_selector/example/lib/save_text_page.dart +++ b/packages/file_selector/file_selector/example/lib/save_text_page.dart @@ -8,7 +8,11 @@ class SaveTextPage extends StatelessWidget { final TextEditingController _contentController = TextEditingController(); void _saveFile() async { - final String path = await getSavePath(); + String? path = await getSavePath(); + if (path == null) { + // Operation was canceled by the user. + return; + } final String text = _contentController.text; final String fileName = _nameController.text; final Uint8List fileData = Uint8List.fromList(text.codeUnits); diff --git a/packages/file_selector/file_selector/example/pubspec.yaml b/packages/file_selector/file_selector/example/pubspec.yaml index 3af2a67e9e93..580237cad5ac 100644 --- a/packages/file_selector/file_selector/example/pubspec.yaml +++ b/packages/file_selector/file_selector/example/pubspec.yaml @@ -1,24 +1,12 @@ name: example description: A new Flutter project. -# The following line prevents the package from being accidentally published to -# pub.dev using `pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html version: 1.0.0+1 environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" dependencies: flutter: @@ -32,52 +20,9 @@ dependencies: # the parent directory to use the current plugin's version. path: ../ - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - dev_dependencies: flutter_test: sdk: flutter -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/packages/file_selector/file_selector/lib/file_selector.dart b/packages/file_selector/file_selector/lib/file_selector.dart index 080eac4460ac..cdb2bf9c726d 100644 --- a/packages/file_selector/file_selector/lib/file_selector.dart +++ b/packages/file_selector/file_selector/lib/file_selector.dart @@ -10,10 +10,10 @@ export 'package:file_selector_platform_interface/file_selector_platform_interfac show XFile, XTypeGroup; /// Open file dialog for loading files and return a file path -Future openFile({ - List acceptedTypeGroups, - String initialDirectory, - String confirmButtonText, +Future openFile({ + List acceptedTypeGroups = const [], + String? initialDirectory, + String? confirmButtonText, }) { return FileSelectorPlatform.instance.openFile( acceptedTypeGroups: acceptedTypeGroups, @@ -23,9 +23,9 @@ Future openFile({ /// Open file dialog for loading files and return a list of file paths Future> openFiles({ - List acceptedTypeGroups, - String initialDirectory, - String confirmButtonText, + List acceptedTypeGroups = const [], + String? initialDirectory, + String? confirmButtonText, }) { return FileSelectorPlatform.instance.openFiles( acceptedTypeGroups: acceptedTypeGroups, @@ -34,11 +34,11 @@ Future> openFiles({ } /// Saves File to user's file system -Future getSavePath({ - List acceptedTypeGroups, - String initialDirectory, - String suggestedName, - String confirmButtonText, +Future getSavePath({ + List acceptedTypeGroups = const [], + String? initialDirectory, + String? suggestedName, + String? confirmButtonText, }) async { return FileSelectorPlatform.instance.getSavePath( acceptedTypeGroups: acceptedTypeGroups, @@ -48,9 +48,9 @@ Future getSavePath({ } /// Gets a directory path from a user's file system -Future getDirectoryPath({ - String initialDirectory, - String confirmButtonText, +Future getDirectoryPath({ + String? initialDirectory, + String? confirmButtonText, }) async { return FileSelectorPlatform.instance.getDirectoryPath( initialDirectory: initialDirectory, confirmButtonText: confirmButtonText); diff --git a/packages/file_selector/file_selector/pubspec.yaml b/packages/file_selector/file_selector/pubspec.yaml index a55b7f4e06e7..34b459cca720 100644 --- a/packages/file_selector/file_selector/pubspec.yaml +++ b/packages/file_selector/file_selector/pubspec.yaml @@ -1,21 +1,20 @@ name: file_selector description: Flutter plugin for opening and saving files. homepage: https://github.com/flutter/plugins/tree/master/packages/file_selector/file_selector -version: 0.7.0+2 +version: 0.8.0 dependencies: flutter: sdk: flutter - file_selector_platform_interface: ^1.0.0 + file_selector_platform_interface: ^2.0.0 dev_dependencies: flutter_test: sdk: flutter - test: ^1.3.0 - mockito: ^4.1.1 - plugin_platform_interface: ^1.0.0 - pedantic: ^1.8.0 + test: ^1.16.3 + plugin_platform_interface: ">=1.0.0 <3.0.0" + pedantic: ^1.10.0 environment: - sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" diff --git a/packages/file_selector/file_selector/test/file_selector_test.dart b/packages/file_selector/file_selector/test/file_selector_test.dart index 15756cc2b622..b16f234bb3b8 100644 --- a/packages/file_selector/file_selector/test/file_selector_test.dart +++ b/packages/file_selector/file_selector/test/file_selector_test.dart @@ -3,13 +3,13 @@ // found in the LICENSE file. import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'package:file_selector/file_selector.dart'; import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; +import 'package:test/fake.dart'; void main() { - MockFileSelector mock; + late FakeFileSelector fakePlatformImplementation; final initialDirectory = '/home/flutteruser'; final confirmButtonText = 'Use this profile picture'; final suggestedName = 'suggested_name'; @@ -25,19 +25,20 @@ void main() { ]; setUp(() { - mock = MockFileSelector(); - FileSelectorPlatform.instance = mock; + fakePlatformImplementation = FakeFileSelector(); + FileSelectorPlatform.instance = fakePlatformImplementation; }); group('openFile', () { final expectedFile = XFile('path'); test('works', () async { - when(mock.openFile( - initialDirectory: initialDirectory, - confirmButtonText: confirmButtonText, - acceptedTypeGroups: acceptedTypeGroups, - )).thenAnswer((_) => Future.value(expectedFile)); + fakePlatformImplementation + ..setExpectations( + initialDirectory: initialDirectory, + confirmButtonText: confirmButtonText, + acceptedTypeGroups: acceptedTypeGroups) + ..setFileResponse([expectedFile]); final file = await openFile( initialDirectory: initialDirectory, @@ -49,7 +50,7 @@ void main() { }); test('works with no arguments', () async { - when(mock.openFile()).thenAnswer((_) => Future.value(expectedFile)); + fakePlatformImplementation.setFileResponse([expectedFile]); final file = await openFile(); @@ -57,24 +58,27 @@ void main() { }); test('sets the initial directory', () async { - when(mock.openFile(initialDirectory: initialDirectory)) - .thenAnswer((_) => Future.value(expectedFile)); + fakePlatformImplementation + ..setExpectations(initialDirectory: initialDirectory) + ..setFileResponse([expectedFile]); final file = await openFile(initialDirectory: initialDirectory); expect(file, expectedFile); }); test('sets the button confirmation label', () async { - when(mock.openFile(confirmButtonText: confirmButtonText)) - .thenAnswer((_) => Future.value(expectedFile)); + fakePlatformImplementation + ..setExpectations(confirmButtonText: confirmButtonText) + ..setFileResponse([expectedFile]); final file = await openFile(confirmButtonText: confirmButtonText); expect(file, expectedFile); }); test('sets the accepted type groups', () async { - when(mock.openFile(acceptedTypeGroups: acceptedTypeGroups)) - .thenAnswer((_) => Future.value(expectedFile)); + fakePlatformImplementation + ..setExpectations(acceptedTypeGroups: acceptedTypeGroups) + ..setFileResponse([expectedFile]); final file = await openFile(acceptedTypeGroups: acceptedTypeGroups); expect(file, expectedFile); @@ -85,11 +89,12 @@ void main() { final expectedFiles = [XFile('path')]; test('works', () async { - when(mock.openFiles( - initialDirectory: initialDirectory, - confirmButtonText: confirmButtonText, - acceptedTypeGroups: acceptedTypeGroups, - )).thenAnswer((_) => Future.value(expectedFiles)); + fakePlatformImplementation + ..setExpectations( + initialDirectory: initialDirectory, + confirmButtonText: confirmButtonText, + acceptedTypeGroups: acceptedTypeGroups) + ..setFileResponse(expectedFiles); final file = await openFiles( initialDirectory: initialDirectory, @@ -101,7 +106,7 @@ void main() { }); test('works with no arguments', () async { - when(mock.openFiles()).thenAnswer((_) => Future.value(expectedFiles)); + fakePlatformImplementation.setFileResponse(expectedFiles); final files = await openFiles(); @@ -109,24 +114,27 @@ void main() { }); test('sets the initial directory', () async { - when(mock.openFiles(initialDirectory: initialDirectory)) - .thenAnswer((_) => Future.value(expectedFiles)); + fakePlatformImplementation + ..setExpectations(initialDirectory: initialDirectory) + ..setFileResponse(expectedFiles); final files = await openFiles(initialDirectory: initialDirectory); expect(files, expectedFiles); }); test('sets the button confirmation label', () async { - when(mock.openFiles(confirmButtonText: confirmButtonText)) - .thenAnswer((_) => Future.value(expectedFiles)); + fakePlatformImplementation + ..setExpectations(confirmButtonText: confirmButtonText) + ..setFileResponse(expectedFiles); final files = await openFiles(confirmButtonText: confirmButtonText); expect(files, expectedFiles); }); test('sets the accepted type groups', () async { - when(mock.openFiles(acceptedTypeGroups: acceptedTypeGroups)) - .thenAnswer((_) => Future.value(expectedFiles)); + fakePlatformImplementation + ..setExpectations(acceptedTypeGroups: acceptedTypeGroups) + ..setFileResponse(expectedFiles); final files = await openFiles(acceptedTypeGroups: acceptedTypeGroups); expect(files, expectedFiles); @@ -137,12 +145,13 @@ void main() { final expectedSavePath = '/example/path'; test('works', () async { - when(mock.getSavePath( - initialDirectory: initialDirectory, - confirmButtonText: confirmButtonText, - acceptedTypeGroups: acceptedTypeGroups, - suggestedName: suggestedName, - )).thenAnswer((_) => Future.value(expectedSavePath)); + fakePlatformImplementation + ..setExpectations( + initialDirectory: initialDirectory, + confirmButtonText: confirmButtonText, + acceptedTypeGroups: acceptedTypeGroups, + suggestedName: suggestedName) + ..setPathResponse(expectedSavePath); final savePath = await getSavePath( initialDirectory: initialDirectory, @@ -155,32 +164,34 @@ void main() { }); test('works with no arguments', () async { - when(mock.getSavePath()) - .thenAnswer((_) => Future.value(expectedSavePath)); + fakePlatformImplementation.setPathResponse(expectedSavePath); final savePath = await getSavePath(); expect(savePath, expectedSavePath); }); test('sets the initial directory', () async { - when(mock.getSavePath(initialDirectory: initialDirectory)) - .thenAnswer((_) => Future.value(expectedSavePath)); + fakePlatformImplementation + ..setExpectations(initialDirectory: initialDirectory) + ..setPathResponse(expectedSavePath); final savePath = await getSavePath(initialDirectory: initialDirectory); expect(savePath, expectedSavePath); }); test('sets the button confirmation label', () async { - when(mock.getSavePath(confirmButtonText: confirmButtonText)) - .thenAnswer((_) => Future.value(expectedSavePath)); + fakePlatformImplementation + ..setExpectations(confirmButtonText: confirmButtonText) + ..setPathResponse(expectedSavePath); final savePath = await getSavePath(confirmButtonText: confirmButtonText); expect(savePath, expectedSavePath); }); test('sets the accepted type groups', () async { - when(mock.getSavePath(acceptedTypeGroups: acceptedTypeGroups)) - .thenAnswer((_) => Future.value(expectedSavePath)); + fakePlatformImplementation + ..setExpectations(acceptedTypeGroups: acceptedTypeGroups) + ..setPathResponse(expectedSavePath); final savePath = await getSavePath(acceptedTypeGroups: acceptedTypeGroups); @@ -188,8 +199,9 @@ void main() { }); test('sets the suggested name', () async { - when(mock.getSavePath(suggestedName: suggestedName)) - .thenAnswer((_) => Future.value(expectedSavePath)); + fakePlatformImplementation + ..setExpectations(suggestedName: suggestedName) + ..setPathResponse(expectedSavePath); final savePath = await getSavePath(suggestedName: suggestedName); expect(savePath, expectedSavePath); @@ -200,10 +212,11 @@ void main() { final expectedDirectoryPath = '/example/path'; test('works', () async { - when(mock.getDirectoryPath( - initialDirectory: initialDirectory, - confirmButtonText: confirmButtonText, - )).thenAnswer((_) => Future.value(expectedDirectoryPath)); + fakePlatformImplementation + ..setExpectations( + initialDirectory: initialDirectory, + confirmButtonText: confirmButtonText) + ..setPathResponse(expectedDirectoryPath); final directoryPath = await getDirectoryPath( initialDirectory: initialDirectory, @@ -214,16 +227,16 @@ void main() { }); test('works with no arguments', () async { - when(mock.getDirectoryPath()) - .thenAnswer((_) => Future.value(expectedDirectoryPath)); + fakePlatformImplementation.setPathResponse(expectedDirectoryPath); final directoryPath = await getDirectoryPath(); expect(directoryPath, expectedDirectoryPath); }); test('sets the initial directory', () async { - when(mock.getDirectoryPath(initialDirectory: initialDirectory)) - .thenAnswer((_) => Future.value(expectedDirectoryPath)); + fakePlatformImplementation + ..setExpectations(initialDirectory: initialDirectory) + ..setPathResponse(expectedDirectoryPath); final directoryPath = await getDirectoryPath(initialDirectory: initialDirectory); @@ -231,8 +244,9 @@ void main() { }); test('sets the button confirmation label', () async { - when(mock.getDirectoryPath(confirmButtonText: confirmButtonText)) - .thenAnswer((_) => Future.value(expectedDirectoryPath)); + fakePlatformImplementation + ..setExpectations(confirmButtonText: confirmButtonText) + ..setPathResponse(expectedDirectoryPath); final directoryPath = await getDirectoryPath(confirmButtonText: confirmButtonText); @@ -241,6 +255,83 @@ void main() { }); } -class MockFileSelector extends Mock +class FakeFileSelector extends Fake with MockPlatformInterfaceMixin - implements FileSelectorPlatform {} + implements FileSelectorPlatform { + // Expectations. + List? acceptedTypeGroups = const []; + String? initialDirectory; + String? confirmButtonText; + String? suggestedName; + // Return values. + List? files; + String? path; + + void setExpectations({ + List acceptedTypeGroups = const [], + String? initialDirectory, + String? suggestedName, + String? confirmButtonText, + }) { + this.acceptedTypeGroups = acceptedTypeGroups; + this.initialDirectory = initialDirectory; + this.suggestedName = suggestedName; + this.confirmButtonText = confirmButtonText; + } + + void setFileResponse(List files) { + this.files = files; + } + + void setPathResponse(String path) { + this.path = path; + } + + @override + Future openFile({ + List? acceptedTypeGroups, + String? initialDirectory, + String? confirmButtonText, + }) async { + expect(acceptedTypeGroups, this.acceptedTypeGroups); + expect(initialDirectory, this.initialDirectory); + expect(suggestedName, this.suggestedName); + return files?[0]; + } + + @override + Future> openFiles({ + List? acceptedTypeGroups, + String? initialDirectory, + String? confirmButtonText, + }) async { + expect(acceptedTypeGroups, this.acceptedTypeGroups); + expect(initialDirectory, this.initialDirectory); + expect(suggestedName, this.suggestedName); + return files!; + } + + @override + Future getSavePath({ + List? acceptedTypeGroups, + String? initialDirectory, + String? suggestedName, + String? confirmButtonText, + }) async { + expect(acceptedTypeGroups, this.acceptedTypeGroups); + expect(initialDirectory, this.initialDirectory); + expect(suggestedName, this.suggestedName); + expect(confirmButtonText, this.confirmButtonText); + return path; + } + + @override + Future getDirectoryPath({ + String? initialDirectory, + String? confirmButtonText, + }) async { + expect(initialDirectory, this.initialDirectory); + expect(confirmButtonText, this.confirmButtonText); + return path; + } +} From a03b66f072ff230718565de4efbfb26856ba2e71 Mon Sep 17 00:00:00 2001 From: Floris Devreese Date: Thu, 25 Feb 2021 21:08:00 +0100 Subject: [PATCH 0216/1565] embedded_views_preview not required since v1.0.0 (#3625) `io.flutter.embedded_views_preview` is not required since version `1.0.0`, so doesn't need to be in the example. --- .../google_maps_flutter/example/ios/Runner/Info.plist | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/Info.plist b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/Info.plist index 372490e1a367..0fa9c73c5d42 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/Info.plist +++ b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/Info.plist @@ -47,7 +47,5 @@ UIViewControllerBasedStatusBarAppearance - io.flutter.embedded_views_preview - From eab25525f702be43f6b492848afde5a65575444d Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Thu, 25 Feb 2021 21:09:38 +0100 Subject: [PATCH 0217/1565] Fix typo in image_picker_for_web README.md (#2835) --- packages/image_picker/image_picker_for_web/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker_for_web/README.md b/packages/image_picker/image_picker_for_web/README.md index 074053c9b956..8c9f2c73b8fe 100644 --- a/packages/image_picker/image_picker_for_web/README.md +++ b/packages/image_picker/image_picker_for_web/README.md @@ -5,7 +5,7 @@ A web implementation of [`image_picker`][1]. ## Limitations on the web platform Since Web Browsers don't offer direct access to their users' file system, -this plugin provides a `PickedFile` abstraction to make access access uniform +this plugin provides a `PickedFile` abstraction to make access uniform across platforms. The web version of the plugin puts network-accessible URIs as the `path` From f61498008e73334600a5728a72ee962e1f9c4be1 Mon Sep 17 00:00:00 2001 From: K K Date: Fri, 26 Feb 2021 01:43:29 +0530 Subject: [PATCH 0218/1565] [url_launcher] Added a note to the README (#2031) The action won't work on the simulator works on physical iOS device which was not mentioned here so it was added Co-authored-by: Michael Klimushyn Co-authored-by: Stuart Morgan --- packages/url_launcher/url_launcher/CHANGELOG.md | 1 + packages/url_launcher/url_launcher/README.md | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index 01f3e787fc9c..2d188366dfa5 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,6 +1,7 @@ ## 6.0.1 * Update result to `True` on iOS when the url was loaded successfully. +* Added a README note about required applications. ## 6.0.0 diff --git a/packages/url_launcher/url_launcher/README.md b/packages/url_launcher/url_launcher/README.md index bc399c73df7d..daf21738d9b7 100644 --- a/packages/url_launcher/url_launcher/README.md +++ b/packages/url_launcher/url_launcher/README.md @@ -51,6 +51,10 @@ Common schemes supported by both iOS and Android: More details can be found here for [iOS](https://developer.apple.com/library/content/featuredarticles/iPhoneURLScheme_Reference/Introduction/Introduction.html) and [Android](https://developer.android.com/guide/components/intents-common.html) +**Note**: URL schemes are only supported if there are apps installed on the device that can +support them. For example, iOS simulators don't have a default email or phone +apps installed, so can't open `tel:` or `mailto:` links. + ### Encoding URLs URLs must be properly encoded, especially when including spaces or other special characters. This can be done using the [`Uri` class](https://api.dart.dev/stable/2.7.1/dart-core/Uri-class.html): From cb64042b577f23c86316b48d1e136e6495a4af66 Mon Sep 17 00:00:00 2001 From: Emmanuel Garcia Date: Thu, 25 Feb 2021 13:46:03 -0800 Subject: [PATCH 0219/1565] Make executor an instance property (#3633) --- .gitignore | 3 +++ packages/shared_preferences/shared_preferences/CHANGELOG.md | 4 ++++ .../plugins/sharedpreferences/MethodCallHandlerImpl.java | 6 ++++-- packages/shared_preferences/shared_preferences/pubspec.yaml | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index d7560505f166..3582a15fae57 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,6 @@ build/ .project .classpath .settings + +# Downloaded by the plugin tools. +google-java-format-1.3-all-deps.jar diff --git a/packages/shared_preferences/shared_preferences/CHANGELOG.md b/packages/shared_preferences/shared_preferences/CHANGELOG.md index 74555f59c27f..63c042a1194e 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.2 + +* Don't create additional thread pools when method channel is called. + ## 2.0.1 * Removed deprecated [AsyncTask](https://developer.android.com/reference/android/os/AsyncTask) was deprecated in API level 30 ([#3481](https://github.com/flutter/plugins/pull/3481)) diff --git a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java index f2c0f298578c..d58cc32ed625 100644 --- a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java +++ b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java @@ -43,12 +43,16 @@ class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { private final android.content.SharedPreferences preferences; + private final ExecutorService executor; + /** * Constructs a {@link MethodCallHandlerImpl} instance. Creates a {@link * android.content.SharedPreferences} based on the {@code context}. */ MethodCallHandlerImpl(Context context) { preferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); + executor = + new ThreadPoolExecutor(0, 1, 30L, TimeUnit.SECONDS, new SynchronousQueue()); } @Override @@ -123,8 +127,6 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) { private void commitAsync( final SharedPreferences.Editor editor, final MethodChannel.Result result) { - final ExecutorService executor = - new ThreadPoolExecutor(0, 1, 30L, TimeUnit.SECONDS, new SynchronousQueue()); final Handler handler = new Handler(Looper.getMainLooper()); executor.execute( diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index 1809a979c6f3..6f6ab1fee6e8 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -2,7 +2,7 @@ name: shared_preferences description: Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences -version: 2.0.1 +version: 2.0.2 flutter: plugin: From a0d99ee3de7c8e6a23301ac6d99ea88c4038f3ed Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Thu, 25 Feb 2021 14:26:03 -0800 Subject: [PATCH 0220/1565] [google_sign_in_web] Migrate to null-safety (#3628) --- .../google_sign_in_web/CHANGELOG.md | 4 + .../google_sign_in_web/example/README.md | 21 + .../integration_test/auth2_test.dart} | 19 +- .../integration_test/gapi_load_test.dart} | 7 +- .../gapi_mocks/gapi_mocks.dart | 0 .../gapi_mocks/src/auth2_init.dart | 0 .../gapi_mocks/src/gapi.dart | 0 .../gapi_mocks/src/google_user.dart | 0 .../gapi_mocks/src/test_iife.dart | 0 .../integration_test/gapi_utils_test.dart} | 52 ++- .../integration_test}/src/test_utils.dart | 0 .../{test => example}/lib/main.dart | 0 .../{test => example}/pubspec.yaml | 12 +- .../{test/run_test => example/run_test.sh} | 7 +- .../test_driver/integration_driver.dart} | 0 .../{test => example}/web/index.html | 0 .../lib/google_sign_in_web.dart | 64 +-- .../lib/src/generated/gapi.dart | 435 +----------------- .../lib/src/generated/gapiauth2.dart | 257 ++++++----- .../google_sign_in_web/lib/src/load_gapi.dart | 2 +- .../google_sign_in_web/lib/src/utils.dart | 35 +- .../google_sign_in_web/pubspec.yaml | 18 +- .../google_sign_in_web/test/README.md | 18 +- .../gapi_load_integration_test.dart | 7 - .../gapi_utils_integration_test.dart | 7 - .../test/tests_exist_elsewhere_test.dart | 10 + 26 files changed, 322 insertions(+), 653 deletions(-) create mode 100644 packages/google_sign_in/google_sign_in_web/example/README.md rename packages/google_sign_in/google_sign_in_web/{test/test_driver/auth2_integration.dart => example/integration_test/auth2_test.dart} (91%) rename packages/google_sign_in/google_sign_in_web/{test/test_driver/gapi_load_integration.dart => example/integration_test/gapi_load_test.dart} (92%) rename packages/google_sign_in/google_sign_in_web/{test/test_driver => example/integration_test}/gapi_mocks/gapi_mocks.dart (100%) rename packages/google_sign_in/google_sign_in_web/{test/test_driver => example/integration_test}/gapi_mocks/src/auth2_init.dart (100%) rename packages/google_sign_in/google_sign_in_web/{test/test_driver => example/integration_test}/gapi_mocks/src/gapi.dart (100%) rename packages/google_sign_in/google_sign_in_web/{test/test_driver => example/integration_test}/gapi_mocks/src/google_user.dart (100%) rename packages/google_sign_in/google_sign_in_web/{test/test_driver => example/integration_test}/gapi_mocks/src/test_iife.dart (100%) rename packages/google_sign_in/google_sign_in_web/{test/test_driver/gapi_utils_integration.dart => example/integration_test/gapi_utils_test.dart} (54%) rename packages/google_sign_in/google_sign_in_web/{test/test_driver => example/integration_test}/src/test_utils.dart (100%) rename packages/google_sign_in/google_sign_in_web/{test => example}/lib/main.dart (100%) rename packages/google_sign_in/google_sign_in_web/{test => example}/pubspec.yaml (57%) rename packages/google_sign_in/google_sign_in_web/{test/run_test => example/run_test.sh} (57%) rename packages/google_sign_in/google_sign_in_web/{test/test_driver/auth2_integration_test.dart => example/test_driver/integration_driver.dart} (100%) rename packages/google_sign_in/google_sign_in_web/{test => example}/web/index.html (100%) delete mode 100644 packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_load_integration_test.dart delete mode 100644 packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_utils_integration_test.dart create mode 100644 packages/google_sign_in/google_sign_in_web/test/tests_exist_elsewhere_test.dart diff --git a/packages/google_sign_in/google_sign_in_web/CHANGELOG.md b/packages/google_sign_in/google_sign_in_web/CHANGELOG.md index d1353f723fd5..a5c9e9d2f2bb 100644 --- a/packages/google_sign_in/google_sign_in_web/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in_web/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.10.0 + +* Migrate to null-safety. + ## 0.9.2+1 * Update Flutter SDK constraint. diff --git a/packages/google_sign_in/google_sign_in_web/example/README.md b/packages/google_sign_in/google_sign_in_web/example/README.md new file mode 100644 index 000000000000..0ec01e025570 --- /dev/null +++ b/packages/google_sign_in/google_sign_in_web/example/README.md @@ -0,0 +1,21 @@ +# Testing + +This package utilizes the `integration_test` package to run its tests in a web browser. + +See [flutter.dev > Integration testing](https://flutter.dev/docs/testing/integration-tests) for more info. + +## Running the tests + +Make sure you have updated to the latest Flutter master. + +1. Check what version of Chrome is running on the machine you're running tests on. + +2. Download and install driver for that version from here: + * + +3. Start the driver using `chromedriver --port=4444` + +4. Run tests: `flutter drive -d web-server --browser-name=chrome --driver=test_driver/integration_driver.dart --target=integration_test/TEST_NAME.dart`, or (in Linux): + + * Single: `./run_test.sh integration_test/TEST_NAME.dart` + * All: `./run_test.sh` diff --git a/packages/google_sign_in/google_sign_in_web/test/test_driver/auth2_integration.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/auth2_test.dart similarity index 91% rename from packages/google_sign_in/google_sign_in_web/test/test_driver/auth2_integration.dart rename to packages/google_sign_in/google_sign_in_web/example/integration_test/auth2_test.dart index e2f16f2aee43..b80080935d42 100644 --- a/packages/google_sign_in/google_sign_in_web/test/test_driver/auth2_integration.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/auth2_test.dart @@ -3,11 +3,12 @@ // found in the LICENSE file. import 'package:flutter/services.dart'; -import 'package:integration_test/integration_test.dart'; - import 'package:flutter_test/flutter_test.dart'; import 'package:google_sign_in_platform_interface/google_sign_in_platform_interface.dart'; import 'package:google_sign_in_web/google_sign_in_web.dart'; +import 'package:integration_test/integration_test.dart'; +import 'package:js/js_util.dart' as js_util; + import 'gapi_mocks/gapi_mocks.dart' as gapi_mocks; import 'src/test_utils.dart'; @@ -25,7 +26,7 @@ void main() { idToken: expectedTokenData.idToken, ); - GoogleSignInPlugin plugin; + late GoogleSignInPlugin plugin; group('plugin.init() throws a catchable exception', () { setUp(() { @@ -54,7 +55,8 @@ void main() { ); fail('plugin.init should have thrown an exception!'); } catch (e) { - expect(e.code, 'idpiframe_initialization_failed'); + final String code = js_util.getProperty(e, 'code') as String; + expect(code, 'idpiframe_initialization_failed'); } }); }); @@ -62,7 +64,7 @@ void main() { group('other methods also throw catchable exceptions on init fail', () { // This function ensures that init gets called, but for some reason, we // ignored that it has thrown stuff... - void _discardInit() async { + Future _discardInit() async { try { await plugin.init( hostedDomain: 'foo', @@ -135,13 +137,13 @@ void main() { }); testWidgets('signInSilently', (WidgetTester tester) async { - GoogleSignInUserData actualUser = await plugin.signInSilently(); + GoogleSignInUserData actualUser = (await plugin.signInSilently())!; expect(actualUser, expectedUserData); }); testWidgets('signIn', (WidgetTester tester) async { - GoogleSignInUserData actualUser = await plugin.signIn(); + GoogleSignInUserData actualUser = (await plugin.signIn())!; expect(actualUser, expectedUserData); }); @@ -185,7 +187,8 @@ void main() { await plugin.signIn(); fail('plugin.signIn() should have thrown an exception!'); } catch (e) { - expect(e.code, 'popup_closed_by_user'); + final String code = js_util.getProperty(e, 'code') as String; + expect(code, 'popup_closed_by_user'); } }); }); diff --git a/packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_load_integration.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_load_test.dart similarity index 92% rename from packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_load_integration.dart rename to packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_load_test.dart index 540369cae370..e0729bcf9b5e 100644 --- a/packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_load_integration.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_load_test.dart @@ -4,18 +4,19 @@ import 'dart:html' as html; -import 'package:integration_test/integration_test.dart'; - import 'package:flutter_test/flutter_test.dart'; import 'package:google_sign_in_platform_interface/google_sign_in_platform_interface.dart'; import 'package:google_sign_in_web/google_sign_in_web.dart'; +import 'package:integration_test/integration_test.dart'; + import 'gapi_mocks/gapi_mocks.dart' as gapi_mocks; import 'src/test_utils.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - gapiUrl = toBase64Url(gapi_mocks.auth2InitSuccess(GoogleSignInUserData())); + gapiUrl = toBase64Url(gapi_mocks.auth2InitSuccess( + GoogleSignInUserData(email: 'test@test.com', id: '1234'))); testWidgets('Plugin is initialized after GAPI fully loads and init is called', (WidgetTester tester) async { diff --git a/packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_mocks/gapi_mocks.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/gapi_mocks.dart similarity index 100% rename from packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_mocks/gapi_mocks.dart rename to packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/gapi_mocks.dart diff --git a/packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_mocks/src/auth2_init.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/auth2_init.dart similarity index 100% rename from packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_mocks/src/auth2_init.dart rename to packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/auth2_init.dart diff --git a/packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_mocks/src/gapi.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/gapi.dart similarity index 100% rename from packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_mocks/src/gapi.dart rename to packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/gapi.dart diff --git a/packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_mocks/src/google_user.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/google_user.dart similarity index 100% rename from packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_mocks/src/google_user.dart rename to packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/google_user.dart diff --git a/packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_mocks/src/test_iife.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/test_iife.dart similarity index 100% rename from packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_mocks/src/test_iife.dart rename to packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/test_iife.dart diff --git a/packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_utils_integration.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_utils_test.dart similarity index 54% rename from packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_utils_integration.dart rename to packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_utils_test.dart index 55b942842b33..e03974a145b7 100644 --- a/packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_utils_integration.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_utils_test.dart @@ -1,27 +1,21 @@ // Copyright 2019 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. -import 'package:flutter_test/flutter_test.dart'; - -import 'package:integration_test/integration_test.dart'; +import 'package:flutter_test/flutter_test.dart'; import 'package:google_sign_in_web/src/generated/gapiauth2.dart' as gapi; import 'package:google_sign_in_web/src/utils.dart'; -import 'package:mockito/mockito.dart'; - -class MockGoogleUser extends Mock implements gapi.GoogleUser {} - -class MockBasicProfile extends Mock implements gapi.BasicProfile {} +import 'package:integration_test/integration_test.dart'; void main() { // The non-null use cases are covered by the auth2_test.dart file. IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('gapiUserToPluginUserData', () { - var mockUser; + late FakeGoogleUser fakeUser; setUp(() { - mockUser = MockGoogleUser(); + fakeUser = FakeGoogleUser(); }); testWidgets('null user -> null response', (WidgetTester tester) async { @@ -30,21 +24,45 @@ void main() { testWidgets('not signed-in user -> null response', (WidgetTester tester) async { - when(mockUser.isSignedIn()).thenReturn(false); - expect(gapiUserToPluginUserData(mockUser), isNull); + expect(gapiUserToPluginUserData(fakeUser), isNull); }); testWidgets('signed-in, but null profile user -> null response', (WidgetTester tester) async { - when(mockUser.isSignedIn()).thenReturn(true); - expect(gapiUserToPluginUserData(mockUser), isNull); + fakeUser.setIsSignedIn(true); + expect(gapiUserToPluginUserData(fakeUser), isNull); }); testWidgets('signed-in, null userId in profile user -> null response', (WidgetTester tester) async { - when(mockUser.isSignedIn()).thenReturn(true); - when(mockUser.getBasicProfile()).thenReturn(MockBasicProfile()); - expect(gapiUserToPluginUserData(mockUser), isNull); + fakeUser.setIsSignedIn(true); + fakeUser.setBasicProfile(FakeBasicProfile()); + expect(gapiUserToPluginUserData(fakeUser), isNull); }); }); } + +class FakeGoogleUser extends Fake implements gapi.GoogleUser { + bool _isSignedIn = false; + gapi.BasicProfile? _basicProfile; + + @override + bool isSignedIn() => _isSignedIn; + @override + gapi.BasicProfile? getBasicProfile() => _basicProfile; + + void setIsSignedIn(bool isSignedIn) { + _isSignedIn = isSignedIn; + } + + void setBasicProfile(gapi.BasicProfile basicProfile) { + _basicProfile = basicProfile; + } +} + +class FakeBasicProfile extends Fake implements gapi.BasicProfile { + String? _id; + + @override + String? getId() => _id; +} diff --git a/packages/google_sign_in/google_sign_in_web/test/test_driver/src/test_utils.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/src/test_utils.dart similarity index 100% rename from packages/google_sign_in/google_sign_in_web/test/test_driver/src/test_utils.dart rename to packages/google_sign_in/google_sign_in_web/example/integration_test/src/test_utils.dart diff --git a/packages/google_sign_in/google_sign_in_web/test/lib/main.dart b/packages/google_sign_in/google_sign_in_web/example/lib/main.dart similarity index 100% rename from packages/google_sign_in/google_sign_in_web/test/lib/main.dart rename to packages/google_sign_in/google_sign_in_web/example/lib/main.dart diff --git a/packages/google_sign_in/google_sign_in_web/test/pubspec.yaml b/packages/google_sign_in/google_sign_in_web/example/pubspec.yaml similarity index 57% rename from packages/google_sign_in/google_sign_in_web/test/pubspec.yaml rename to packages/google_sign_in/google_sign_in_web/example/pubspec.yaml index dd0354e81498..385b2ea0861e 100644 --- a/packages/google_sign_in/google_sign_in_web/test/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_web/example/pubspec.yaml @@ -1,23 +1,23 @@ -name: regular_integration_tests +name: google_sign_in_web_integration_tests publish_to: none environment: - sdk: ">=2.2.2 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.27.0-0" # For integration_test from sdk dependencies: flutter: sdk: flutter dev_dependencies: - google_sign_in: ^4.5.3 + http: ^0.13.0 + js: ^0.6.3 flutter_driver: sdk: flutter flutter_test: sdk: flutter - http: ^0.12.2 - mockito: ^4.1.1 integration_test: - path: ../../../integration_test + sdk: flutter dependency_overrides: google_sign_in_web: diff --git a/packages/google_sign_in/google_sign_in_web/test/run_test b/packages/google_sign_in/google_sign_in_web/example/run_test.sh similarity index 57% rename from packages/google_sign_in/google_sign_in_web/test/run_test rename to packages/google_sign_in/google_sign_in_web/example/run_test.sh index 74a8526a0fa3..0f76f4a47e16 100755 --- a/packages/google_sign_in/google_sign_in_web/test/run_test +++ b/packages/google_sign_in/google_sign_in_web/example/run_test.sh @@ -1,17 +1,20 @@ #!/usr/bin/bash + if pgrep -lf chromedriver > /dev/null; then echo "chromedriver is running." if [ $# -eq 0 ]; then echo "No target specified, running all tests..." - find test_driver/ -iname *_integration.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --target='{}' + find integration_test/ -iname *_test.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_driver.dart --target='{}' else echo "Running test target: $1..." set -x - flutter drive -d web-server --web-port=7357 --browser-name=chrome --target=$1 + flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_driver.dart --target=$1 fi else echo "chromedriver is not running." fi + + diff --git a/packages/google_sign_in/google_sign_in_web/test/test_driver/auth2_integration_test.dart b/packages/google_sign_in/google_sign_in_web/example/test_driver/integration_driver.dart similarity index 100% rename from packages/google_sign_in/google_sign_in_web/test/test_driver/auth2_integration_test.dart rename to packages/google_sign_in/google_sign_in_web/example/test_driver/integration_driver.dart diff --git a/packages/google_sign_in/google_sign_in_web/test/web/index.html b/packages/google_sign_in/google_sign_in_web/example/web/index.html similarity index 100% rename from packages/google_sign_in/google_sign_in_web/test/web/index.html rename to packages/google_sign_in/google_sign_in_web/example/web/index.html diff --git a/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart b/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart index dd82852fa350..41e8106802de 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart @@ -6,8 +6,8 @@ import 'dart:async'; import 'dart:html' as html; import 'package:flutter/services.dart'; -import 'package:google_sign_in_platform_interface/google_sign_in_platform_interface.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; +import 'package:google_sign_in_platform_interface/google_sign_in_platform_interface.dart'; import 'package:js/js.dart'; import 'package:meta/meta.dart'; @@ -37,8 +37,8 @@ class GoogleSignInPlugin extends GoogleSignInPlatform { _isGapiInitialized = gapi.inject(gapiUrl).then((_) => gapi.init()); } - Future _isGapiInitialized; - Future _isAuthInitialized; + late Future _isGapiInitialized; + late Future _isAuthInitialized; bool _isInitCalled = false; // This method throws if init hasn't been called at some point in the past. @@ -58,7 +58,7 @@ class GoogleSignInPlugin extends GoogleSignInPlatform { return Future.wait([_isGapiInitialized, _isAuthInitialized]); } - String _autoDetectedClientId; + String? _autoDetectedClientId; /// Factory method that initializes the plugin with [GoogleSignInPlatform]. static void registerWith(Registrar registrar) { @@ -66,12 +66,13 @@ class GoogleSignInPlugin extends GoogleSignInPlatform { } @override - Future init( - {@required String hostedDomain, - List scopes = const [], - SignInOption signInOption = SignInOption.standard, - String clientId}) async { - final String appClientId = clientId ?? _autoDetectedClientId; + Future init({ + List scopes = const [], + SignInOption signInOption = SignInOption.standard, + String? hostedDomain, + String? clientId, + }) async { + final String? appClientId = clientId ?? _autoDetectedClientId; assert( appClientId != null, 'ClientID not set. Either set it on a ' @@ -90,7 +91,7 @@ class GoogleSignInPlugin extends GoogleSignInPlatform { hosted_domain: hostedDomain, // The js lib wants a space-separated list of values scope: scopes.join(' '), - client_id: appClientId, + client_id: appClientId!, )); Completer isAuthInitialized = Completer(); @@ -119,18 +120,18 @@ class GoogleSignInPlugin extends GoogleSignInPlatform { } @override - Future signInSilently() async { + Future signInSilently() async { await initialized; return gapiUserToPluginUserData( - await auth2.getAuthInstance().currentUser.get()); + await auth2.getAuthInstance()?.currentUser?.get()); } @override - Future signIn() async { + Future signIn() async { await initialized; try { - return gapiUserToPluginUserData(await auth2.getAuthInstance().signIn()); + return gapiUserToPluginUserData(await auth2.getAuthInstance()?.signIn()); } on auth2.GoogleAuthSignInError catch (reason) { throw PlatformException( code: reason.error, @@ -143,30 +144,33 @@ class GoogleSignInPlugin extends GoogleSignInPlatform { @override Future getTokens( - {@required String email, bool shouldRecoverAuth}) async { + {required String email, bool? shouldRecoverAuth}) async { await initialized; - final auth2.GoogleUser currentUser = + final auth2.GoogleUser? currentUser = auth2.getAuthInstance()?.currentUser?.get(); - final auth2.AuthResponse response = currentUser.getAuthResponse(); + final auth2.AuthResponse? response = currentUser?.getAuthResponse(); return GoogleSignInTokenData( - idToken: response.id_token, accessToken: response.access_token); + idToken: response?.id_token, accessToken: response?.access_token); } @override Future signOut() async { await initialized; - return auth2.getAuthInstance().signOut(); + return auth2.getAuthInstance()?.signOut(); } @override Future disconnect() async { await initialized; - final auth2.GoogleUser currentUser = + final auth2.GoogleUser? currentUser = auth2.getAuthInstance()?.currentUser?.get(); + + if (currentUser == null) return; + return currentUser.disconnect(); } @@ -174,16 +178,19 @@ class GoogleSignInPlugin extends GoogleSignInPlatform { Future isSignedIn() async { await initialized; - final auth2.GoogleUser currentUser = + final auth2.GoogleUser? currentUser = auth2.getAuthInstance()?.currentUser?.get(); + + if (currentUser == null) return false; + return currentUser.isSignedIn(); } @override - Future clearAuthCache({String token}) async { + Future clearAuthCache({required String token}) async { await initialized; - return auth2.getAuthInstance().disconnect(); + return auth2.getAuthInstance()?.disconnect(); } @override @@ -194,14 +201,15 @@ class GoogleSignInPlugin extends GoogleSignInPlatform { if (currentUser == null) return false; - final grantedScopes = currentUser.getGrantedScopes(); + final grantedScopes = currentUser.getGrantedScopes() ?? ''; final missingScopes = scopes.where((scope) => !grantedScopes.contains(scope)); if (missingScopes.isEmpty) return true; - return currentUser - .grant(auth2.SigninOptions(scope: missingScopes.join(" "))) ?? - false; + final response = await currentUser + .grant(auth2.SigninOptions(scope: missingScopes.join(' '))); + + return response != null; } } diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart index 95f07490d3e6..f0f886ce7880 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart @@ -2,448 +2,53 @@ // 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, unused_element - -@JS() -library gapi; - -import "package:js/js.dart"; -import "package:js/js_util.dart" show promiseToFuture; - /// Type definitions for Google API Client /// Project: https://github.com/google/google-api-javascript-client /// Definitions by: Frank M , grant /// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped /// TypeScript Version: 2.3 -/// The OAuth 2.0 token object represents the OAuth 2.0 token and any associated data. -@anonymous -@JS() -abstract class GoogleApiOAuth2TokenObject { - /// The OAuth 2.0 token. Only present in successful responses - external String get access_token; - external set access_token(String v); - - /// Details about the error. Only present in error responses - external String get error; - external set error(String v); - - /// The duration, in seconds, the token is valid for. Only present in successful responses - external String get expires_in; - external set expires_in(String v); - external GoogleApiOAuth2TokenSessionState get session_state; - external set session_state(GoogleApiOAuth2TokenSessionState v); +// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/gapi - /// The Google API scopes related to this token - external String get state; - external set state(String v); - external factory GoogleApiOAuth2TokenObject( - {String access_token, - String error, - String expires_in, - GoogleApiOAuth2TokenSessionState session_state, - String state}); -} +// ignore_for_file: public_member_api_docs, unused_element -@anonymous @JS() -abstract class GoogleApiOAuth2TokenSessionState { - external dynamic /*{ - authuser: string, - }*/ - get extraQueryParams; - external set extraQueryParams( - dynamic - /*{ - authuser: string, - }*/ - v); - external factory GoogleApiOAuth2TokenSessionState( - {dynamic - /*{ - authuser: string, - }*/ - extraQueryParams}); -} +library gapi; -/// Fix for #8215 -/// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/8215 -/// Usage example: -/// https://developers.google.com/identity/sign-in/web/session-state +import 'package:js/js.dart'; // Module gapi typedef void LoadCallback( - [dynamic args1, - dynamic args2, - dynamic args3, - dynamic args4, - dynamic args5]); + [dynamic? args1, + dynamic? args2, + dynamic? args3, + dynamic? args4, + dynamic? args5]); @anonymous @JS() abstract class LoadConfig { external LoadCallback get callback; external set callback(LoadCallback v); - external Function get onerror; - external set onerror(Function v); - external num get timeout; - external set timeout(num v); - external Function get ontimeout; - external set ontimeout(Function v); + external Function? get onerror; + external set onerror(Function? v); + external num? get timeout; + external set timeout(num? v); + external Function? get ontimeout; + external set ontimeout(Function? v); external factory LoadConfig( {LoadCallback callback, - Function onerror, - num timeout, - Function ontimeout}); + Function? onerror, + num? timeout, + Function? ontimeout}); } /*type CallbackOrConfig = LoadConfig | LoadCallback;*/ /// Pragmatically initialize gapi class member. /// Reference: https://developers.google.com/api-client-library/javascript/reference/referencedocs#gapiloadlibraries-callbackorconfig -@JS("gapi.load") +@JS('gapi.load') external void load( String apiName, dynamic /*LoadConfig|LoadCallback*/ callback); // End module gapi -// Module gapi.auth -/// Initiates the OAuth 2.0 authorization process. The browser displays a popup window prompting the user authenticate and authorize. After the user authorizes, the popup closes and the callback function fires. -@JS("gapi.auth.authorize") -external void authorize( - dynamic - /*{ - /** - * The application's client ID. - */ - client_id?: string; - /** - * If true, then login uses "immediate mode", which means that the token is refreshed behind the scenes, and no UI is shown to the user. - */ - immediate?: boolean; - /** - * The OAuth 2.0 response type property. Default: token - */ - response_type?: string; - /** - * The auth scope or scopes to authorize. Auth scopes for individual APIs can be found in their documentation. - */ - scope?: any; - /** - * The user to sign in as. -1 to toggle a multi-account chooser, 0 to default to the user's current account, and 1 to automatically sign in if the user is signed into Google Plus. - */ - authuser?: number; - }*/ - params, - dynamic callback(GoogleApiOAuth2TokenObject token)); - -/// Initializes the authorization feature. Call this when the client loads to prevent popup blockers from blocking the auth window on gapi.auth.authorize calls. -@JS("gapi.auth.init") -external void init(dynamic callback()); - -/// Retrieves the OAuth 2.0 token for the application. -@JS("gapi.auth.getToken") -external GoogleApiOAuth2TokenObject getToken(); - -/// Sets the OAuth 2.0 token for the application. -@JS("gapi.auth.setToken") -external void setToken(GoogleApiOAuth2TokenObject token); - -/// Initiates the client-side Google+ Sign-In OAuth 2.0 flow. -/// When the method is called, the OAuth 2.0 authorization dialog is displayed to the user and when they accept, the callback function is called. -@JS("gapi.auth.signIn") -external void signIn( - dynamic - /*{ - /** - * Your OAuth 2.0 client ID that you obtained from the Google Developers Console. - */ - clientid?: string; - /** - * Directs the sign-in button to store user and session information in a session cookie and HTML5 session storage on the user's client for the purpose of minimizing HTTP traffic and distinguishing between multiple Google accounts a user might be signed into. - */ - cookiepolicy?: string; - /** - * A function in the global namespace, which is called when the sign-in button is rendered and also called after a sign-in flow completes. - */ - callback?: () => void; - /** - * If true, all previously granted scopes remain granted in each incremental request, for incremental authorization. The default value true is correct for most use cases; use false only if employing delegated auth, where you pass the bearer token to a less-trusted component with lower programmatic authority. - */ - includegrantedscopes?: boolean; - /** - * If your app will write moments, list the full URI of the types of moments that you intend to write. - */ - requestvisibleactions?: any; - /** - * The OAuth 2.0 scopes for the APIs that you would like to use as a space-delimited list. - */ - scope?: any; - /** - * If you have an Android app, you can drive automatic Android downloads from your web sign-in flow. - */ - apppackagename?: string; - }*/ - params); - -/// Signs a user out of your app without logging the user out of Google. This method will only work when the user is signed in with Google+ Sign-In. -@JS("gapi.auth.signOut") -external void signOut(); -// End module gapi.auth - -// Module gapi.client -@anonymous -@JS() -abstract class RequestOptions { - /// The URL to handle the request - external String get path; - external set path(String v); - - /// The HTTP request method to use. Default is GET - external String get method; - external set method(String v); - - /// URL params in key-value pair form - external dynamic get params; - external set params(dynamic v); - - /// Additional HTTP request headers - external dynamic get headers; - external set headers(dynamic v); - - /// The HTTP request body (applies to PUT or POST). - external dynamic get body; - external set body(dynamic v); - - /// If supplied, the request is executed immediately and no gapi.client.HttpRequest object is returned - external dynamic Function() get callback; - external set callback(dynamic Function() v); - external factory RequestOptions( - {String path, - String method, - dynamic params, - dynamic headers, - dynamic body, - dynamic Function() callback}); -} - -@anonymous -@JS() -abstract class _RequestOptions { - @JS("gapi.client.init") - external Promise client_init( - dynamic - /*{ - /** - * The API Key to use. - */ - apiKey?: string; - /** - * An array of discovery doc URLs or discovery doc JSON objects. - */ - discoveryDocs?: string[]; - /** - * The app's client ID, found and created in the Google Developers Console. - */ - clientId?: string; - /** - * The scopes to request, as a space-delimited string. - */ - scope?: string, - - hosted_domain?: string; - }*/ - args); -} - -extension RequestOptionsExtensions on RequestOptions {} - -@anonymous -@JS() -abstract class TokenObject { - /// The access token to use in requests. - external String get access_token; - external set access_token(String v); - external factory TokenObject({String access_token}); -} - -/// Creates a HTTP request for making RESTful requests. -/// An object encapsulating the various arguments for this method. -@JS("gapi.client.request") -external HttpRequest request(RequestOptions args); - -/// Creates an RPC Request directly. The method name and version identify the method to be executed and the RPC params are provided upon RPC creation. -@JS("gapi.client.rpcRequest") -external RpcRequest rpcRequest(String method, - [String version, dynamic rpcParams]); - -/// Sets the API key for the application. -@JS("gapi.client.setApiKey") -external void setApiKey(String apiKey); - -/// Retrieves the OAuth 2.0 token for the application. -@JS("gapi.client.getToken") -external GoogleApiOAuth2TokenObject client_getToken(); - -/// Sets the authentication token to use in requests. -/// Reference: https://developers.google.com/api-client-library/javascript/reference/referencedocs#gapiclientsettokentokenobject -@JS("gapi.client.setToken") -external void client_setToken(TokenObject /*TokenObject|Null*/ token); - -@anonymous -@JS() -abstract class HttpRequestFulfilled { - external T get result; - external set result(T v); - external String get body; - external set body(String v); - external List get headers; - external set headers(List v); - external num get status; - external set status(num v); - external String get statusText; - external set statusText(String v); - external factory HttpRequestFulfilled( - {T result, - String body, - List headers, - num status, - String statusText}); -} - -@anonymous -@JS() -abstract class _HttpRequestFulfilled { - /*external Promise client_load(String name, String version);*/ - /*external void client_load(String name, String version, dynamic callback(), - [String url]); -*/ - @JS("gapi.client.load") - external dynamic /*Promise|void*/ client_load( - String name, String version, - [dynamic callback(), String url]); -} - -extension HttpRequestFulfilledExtensions on HttpRequestFulfilled {} - -@anonymous -@JS() -abstract class HttpRequestRejected { - external dynamic /*dynamic|bool*/ get result; - external set result(dynamic /*dynamic|bool*/ v); - external String get body; - external set body(String v); - external List get headers; - external set headers(List v); - external num get status; - external set status(num v); - external String get statusText; - external set statusText(String v); - external factory HttpRequestRejected( - {dynamic /*dynamic|bool*/ result, - String body, - List headers, - num status, - String statusText}); -} - -/// HttpRequest supports promises. -/// See Google API Client JavaScript Using Promises https://developers.google.com/api-client-library/javascript/features/promises -@JS("gapi.client.HttpRequestPromise") -class HttpRequestPromise {} - -@JS("gapi.client.HttpRequestPromise") -abstract class _HttpRequestPromise { - /// Taken and adapted from https://github.com/Microsoft/TypeScript/blob/v2.3.1/lib/lib.es5.d.ts#L1343 - external Promise then/**/( - [dynamic /*TResult1|PromiseLike Function(HttpRequestFulfilled)|dynamic|Null*/ onfulfilled, - dynamic /*TResult2|PromiseLike Function(HttpRequestRejected)|dynamic|Null*/ onrejected, - dynamic opt_context]); -} - -extension HttpRequestPromiseExtensions on HttpRequestPromise { - Future then( - [dynamic /*TResult1|PromiseLike Function(HttpRequestFulfilled)|dynamic|Null*/ onfulfilled, - dynamic /*TResult2|PromiseLike Function(HttpRequestRejected)|dynamic|Null*/ onrejected, - dynamic opt_context]) { - final Object t = this; - final _HttpRequestPromise tt = t; - return promiseToFuture(tt.then(onfulfilled, onrejected, opt_context)); - } -} - -/// An object encapsulating an HTTP request. This object is not instantiated directly, rather it is returned by gapi.client.request. -@JS("gapi.client.HttpRequest") -class HttpRequest extends HttpRequestPromise { - /// Executes the request and runs the supplied callback on response. - external void execute( - dynamic callback( - - /// contains the response parsed as JSON. If the response is not JSON, this field will be false. - T jsonResp, - - /// is the HTTP response. It is JSON, and can be parsed to an object - dynamic - /*{ - body: string; - headers: any[]; - status: number; - statusText: string; - }*/ - rawResp)); -} - -/// Represents an HTTP Batch operation. Individual HTTP requests are added with the add method and the batch is executed using execute. -@JS("gapi.client.HttpBatch") -class HttpBatch { - /// Adds a gapi.client.HttpRequest to the batch. - external void add(HttpRequest httpRequest, - [dynamic - /*{ - /** - * Identifies the response for this request in the map of batch responses. If one is not provided, the system generates a random ID. - */ - id: string; - callback: ( - /** - * is the response for this request only. Its format is defined by the API method being called. - */ - individualResponse: any, - /** - * is the raw batch ID-response map as a string. It contains all responses to all requests in the batch. - */ - rawBatchResponse: any - ) => any - }*/ - opt_params]); - - /// Executes all requests in the batch. The supplied callback is executed on success or failure. - external void execute( - dynamic callback( - - /// is an ID-response map of each requests response. - dynamic responseMap, - - /// is the same response, but as an unparsed JSON-string. - String rawBatchResponse)); -} - -/// Similar to gapi.client.HttpRequest except this object encapsulates requests generated by registered methods. -@JS("gapi.client.RpcRequest") -class RpcRequest { - /// Executes the request and runs the supplied callback with the response. - external void callback( - void callback( - - /// contains the response parsed as JSON. If the response is not JSON, this field will be false. - dynamic jsonResp, - - /// is the same as jsonResp, except it is a raw string that has not been parsed. It is typically used when the response is not JSON. - String rawResp)); -} - -// End module gapi.client -@JS() -abstract class Promise { - external factory Promise( - void executor(void resolve(T result), Function reject)); - external Promise then(void onFulfilled(T result), [Function onRejected]); -} +// Manually removed gapi.auth and gapi.client, unused by this plugin. diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart index 8c8d23378e3e..b2b5c368b6ab 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart @@ -2,14 +2,6 @@ // 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, unused_element - -@JS() -library gapiauth2; - -import "package:js/js.dart"; -import "package:js/js_util.dart" show promiseToFuture; - /// Type definitions for non-npm package Google Sign-In API 0.0 /// Project: https://developers.google.com/identity/sign-in/web/ /// Definitions by: Derek Lawless @@ -18,14 +10,24 @@ import "package:js/js_util.dart" show promiseToFuture; /// +// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/gapi.auth2 + +// ignore_for_file: public_member_api_docs, unused_element + +@JS() +library gapiauth2; + +import 'package:js/js.dart'; +import 'package:js/js_util.dart' show promiseToFuture; + @anonymous @JS() class GoogleAuthInitFailureError { external String get error; - external set error(String value); + external set error(String? value); external String get details; - external set details(String value); + external set details(String? value); } @anonymous @@ -35,16 +37,23 @@ class GoogleAuthSignInError { external set error(String value); } +@anonymous +@JS() +class OfflineAccessResponse { + external String? get code; + external set code(String? value); +} + // Module gapi.auth2 /// GoogleAuth is a singleton class that provides methods to allow the user to sign in with a Google account, /// get the user's current sign-in status, get specific data from the user's Google profile, /// request additional scopes, and sign out from the current account. -@JS("gapi.auth2.GoogleAuth") +@JS('gapi.auth2.GoogleAuth') class GoogleAuth { external IsSignedIn get isSignedIn; external set isSignedIn(IsSignedIn v); - external CurrentUser get currentUser; - external set currentUser(CurrentUser v); + external CurrentUser? get currentUser; + external set currentUser(CurrentUser? v); /// Calls the onInit function when the GoogleAuth object is fully initialized, or calls the onFailure function if /// initialization fails. @@ -59,7 +68,7 @@ class GoogleAuth { /// Attaches the sign-in flow to the specified container's click handler. external dynamic attachClickHandler( - dynamic container, + dynamic? container, SigninOptions options, dynamic onsuccess(GoogleUser googleUser), dynamic onfailure(String reason)); @@ -70,22 +79,20 @@ class GoogleAuth { abstract class _GoogleAuth { external Promise signIn( [dynamic /*SigninOptions|SigninOptionsBuilder*/ options]); - external Promise grantOfflineAccess( - [OfflineAccessOptions options]); + external Promise grantOfflineAccess( + [OfflineAccessOptions? options]); } extension GoogleAuthExtensions on GoogleAuth { Future signIn( [dynamic /*SigninOptions|SigninOptionsBuilder*/ options]) { - final Object t = this; - final _GoogleAuth tt = t; + final _GoogleAuth tt = this as _GoogleAuth; return promiseToFuture(tt.signIn(options)); } - Future grantOfflineAccess( - [OfflineAccessOptions options]) { - final Object t = this; - final _GoogleAuth tt = t; + Future grantOfflineAccess( + [OfflineAccessOptions? options]) { + final _GoogleAuth tt = this as _GoogleAuth; return promiseToFuture(tt.grantOfflineAccess(options)); } } @@ -118,42 +125,52 @@ abstract class SigninOptions { /// The package name of the Android app to install over the air. /// See Android app installs from your web site: /// https://developers.google.com/identity/sign-in/web/android-app-installs - external String get app_package_name; - external set app_package_name(String v); + external String? get app_package_name; + external set app_package_name(String? v); /// Fetch users' basic profile information when they sign in. /// Adds 'profile', 'email' and 'openid' to the requested scopes. /// True if unspecified. - external bool get fetch_basic_profile; - external set fetch_basic_profile(bool v); + external bool? get fetch_basic_profile; + external set fetch_basic_profile(bool? v); /// Specifies whether to prompt the user for re-authentication. /// See OpenID Connect Request Parameters: /// https://openid.net/specs/openid-connect-basic-1_0.html#RequestParameters - external String get prompt; - external set prompt(String v); + external String? get prompt; + external set prompt(String? v); /// The scopes to request, as a space-delimited string. /// Optional if fetch_basic_profile is not set to false. - external String get scope; - external set scope(String v); + external String? get scope; + external set scope(String? v); /// The UX mode to use for the sign-in flow. /// By default, it will open the consent flow in a popup. - external String /*'popup'|'redirect'*/ get ux_mode; - external set ux_mode(String /*'popup'|'redirect'*/ v); + external String? /*'popup'|'redirect'*/ get ux_mode; + external set ux_mode(String? /*'popup'|'redirect'*/ v); /// If using ux_mode='redirect', this parameter allows you to override the default redirect_uri that will be used at the end of the consent flow. /// The default redirect_uri is the current URL stripped of query parameters and hash fragment. - external String get redirect_uri; - external set redirect_uri(String v); + external String? get redirect_uri; + external set redirect_uri(String? v); + + // When your app knows which user it is trying to authenticate, it can provide this parameter as a hint to the authentication server. + // Passing this hint suppresses the account chooser and either pre-fill the email box on the sign-in form, or select the proper session (if the user is using multiple sign-in), + // which can help you avoid problems that occur if your app logs in the wrong user account. The value can be either an email address or the sub string, + // which is equivalent to the user's Google ID. + // https://developers.google.com/identity/protocols/OpenIDConnect?hl=en#authenticationuriparameters + external String? get login_hint; + external set login_hint(String? v); + external factory SigninOptions( {String app_package_name, bool fetch_basic_profile, String prompt, String scope, String /*'popup'|'redirect'*/ ux_mode, - String redirect_uri}); + String redirect_uri, + String login_hint}); } /// Definitions by: John @@ -162,12 +179,12 @@ abstract class SigninOptions { @anonymous @JS() abstract class OfflineAccessOptions { - external String get scope; - external set scope(String v); - external String /*'select_account'|'consent'*/ get prompt; - external set prompt(String /*'select_account'|'consent'*/ v); - external String get app_package_name; - external set app_package_name(String v); + external String? get scope; + external set scope(String? v); + external String? /*'select_account'|'consent'*/ get prompt; + external set prompt(String? /*'select_account'|'consent'*/ v); + external String? get app_package_name; + external set app_package_name(String? v); external factory OfflineAccessOptions( {String scope, String /*'select_account'|'consent'*/ prompt, @@ -180,98 +197,99 @@ abstract class OfflineAccessOptions { @JS() abstract class ClientConfig { /// The app's client ID, found and created in the Google Developers Console. - external String get client_id; - external set client_id(String v); + external String? get client_id; + external set client_id(String? v); /// The domains for which to create sign-in cookies. Either a URI, single_host_origin, or none. /// Defaults to single_host_origin if unspecified. - external String get cookie_policy; - external set cookie_policy(String v); + external String? get cookie_policy; + external set cookie_policy(String? v); /// The scopes to request, as a space-delimited string. Optional if fetch_basic_profile is not set to false. - external String get scope; - external set scope(String v); + external String? get scope; + external set scope(String? v); /// Fetch users' basic profile information when they sign in. Adds 'profile' and 'email' to the requested scopes. True if unspecified. - external bool get fetch_basic_profile; - external set fetch_basic_profile(bool v); + external bool? get fetch_basic_profile; + external set fetch_basic_profile(bool? v); /// The Google Apps domain to which users must belong to sign in. This is susceptible to modification by clients, /// so be sure to verify the hosted domain property of the returned user. Use GoogleUser.getHostedDomain() on the client, /// and the hd claim in the ID Token on the server to verify the domain is what you expected. - external String get hosted_domain; - external set hosted_domain(String v); + external String? get hosted_domain; + external set hosted_domain(String? v); /// Used only for OpenID 2.0 client migration. Set to the value of the realm that you are currently using for OpenID 2.0, /// as described in OpenID 2.0 (Migration). - external String get openid_realm; - external set openid_realm(String v); + external String? get openid_realm; + external set openid_realm(String? v); /// The UX mode to use for the sign-in flow. /// By default, it will open the consent flow in a popup. - external String /*'popup'|'redirect'*/ get ux_mode; - external set ux_mode(String /*'popup'|'redirect'*/ v); + external String? /*'popup'|'redirect'*/ get ux_mode; + external set ux_mode(String? /*'popup'|'redirect'*/ v); /// If using ux_mode='redirect', this parameter allows you to override the default redirect_uri that will be used at the end of the consent flow. /// The default redirect_uri is the current URL stripped of query parameters and hash fragment. - external String get redirect_uri; - external set redirect_uri(String v); + external String? get redirect_uri; + external set redirect_uri(String? v); external factory ClientConfig( {String client_id, String cookie_policy, String scope, bool fetch_basic_profile, - String hosted_domain, + String? hosted_domain, String openid_realm, String /*'popup'|'redirect'*/ ux_mode, String redirect_uri}); } -@JS("gapi.auth2.SigninOptionsBuilder") +@JS('gapi.auth2.SigninOptionsBuilder') class SigninOptionsBuilder { external dynamic setAppPackageName(String name); external dynamic setFetchBasicProfile(bool fetch); external dynamic setPrompt(String prompt); external dynamic setScope(String scope); + external dynamic setLoginHint(String hint); } @anonymous @JS() abstract class BasicProfile { - external String getId(); - external String getName(); - external String getGivenName(); - external String getFamilyName(); - external String getImageUrl(); - external String getEmail(); + external String? getId(); + external String? getName(); + external String? getGivenName(); + external String? getFamilyName(); + external String? getImageUrl(); + external String? getEmail(); } /// Reference: https://developers.google.com/api-client-library/javascript/reference/referencedocs#gapiauth2authresponse @anonymous @JS() abstract class AuthResponse { - external String get access_token; - external set access_token(String v); - external String get id_token; - external set id_token(String v); - external String get login_hint; - external set login_hint(String v); - external String get scope; - external set scope(String v); - external num get expires_in; - external set expires_in(num v); - external num get first_issued_at; - external set first_issued_at(num v); - external num get expires_at; - external set expires_at(num v); + external String? get access_token; + external set access_token(String? v); + external String? get id_token; + external set id_token(String? v); + external String? get login_hint; + external set login_hint(String? v); + external String? get scope; + external set scope(String? v); + external num? get expires_in; + external set expires_in(num? v); + external num? get first_issued_at; + external set first_issued_at(num? v); + external num? get expires_at; + external set expires_at(num? v); external factory AuthResponse( - {String access_token, - String id_token, - String login_hint, - String scope, - num expires_in, - num first_issued_at, - num expires_at}); + {String? access_token, + String? id_token, + String? login_hint, + String? scope, + num? expires_in, + num? first_issued_at, + num? expires_at}); } /// Reference: https://developers.google.com/api-client-library/javascript/reference/referencedocs#gapiauth2authorizeconfig @@ -282,22 +300,22 @@ abstract class AuthorizeConfig { external set client_id(String v); external String get scope; external set scope(String v); - external String get response_type; - external set response_type(String v); - external String get prompt; - external set prompt(String v); - external String get cookie_policy; - external set cookie_policy(String v); - external String get hosted_domain; - external set hosted_domain(String v); - external String get login_hint; - external set login_hint(String v); - external String get app_package_name; - external set app_package_name(String v); - external String get openid_realm; - external set openid_realm(String v); - external bool get include_granted_scopes; - external set include_granted_scopes(bool v); + external String? get response_type; + external set response_type(String? v); + external String? get prompt; + external set prompt(String? v); + external String? get cookie_policy; + external set cookie_policy(String? v); + external String? get hosted_domain; + external set hosted_domain(String? v); + external String? get login_hint; + external set login_hint(String? v); + external String? get app_package_name; + external set app_package_name(String? v); + external String? get openid_realm; + external set openid_realm(String? v); + external bool? get include_granted_scopes; + external set include_granted_scopes(bool? v); external factory AuthorizeConfig( {String client_id, String scope, @@ -350,34 +368,31 @@ abstract class AuthorizeResponse { @JS() abstract class GoogleUser { /// Get the user's unique ID string. - external String getId(); + external String? getId(); /// Returns true if the user is signed in. external bool isSignedIn(); /// Get the user's Google Apps domain if the user signed in with a Google Apps account. - external String getHostedDomain(); + external String? getHostedDomain(); /// Get the scopes that the user granted as a space-delimited string. - external String getGrantedScopes(); + external String? getGrantedScopes(); /// Get the user's basic profile information. - external BasicProfile getBasicProfile(); + external BasicProfile? getBasicProfile(); /// Get the response object from the user's auth session. + // This returns an empty JS object when the user hasn't attempted to sign in. external AuthResponse getAuthResponse([bool includeAuthorizationData]); /// Returns true if the user granted the specified scopes. external bool hasGrantedScopes(String scopes); - /// Signs in the user. Use this method to request additional scopes for incremental - /// authorization or to sign in a user after the user has signed out. - /// When you use GoogleUser.signIn(), the sign-in flow skips the account chooser step. - /// See GoogleAuth.signIn(). - external dynamic signIn( - [dynamic /*SigninOptions|SigninOptionsBuilder*/ options]); - - /// See GoogleUser.signIn() + // Has the API for grant and grantOfflineAccess changed? + /// Request additional scopes to the user. + /// + /// See GoogleAuth.signIn() for the list of parameters and the error code. external dynamic grant( [dynamic /*SigninOptions|SigninOptionsBuilder*/ options]); @@ -393,35 +408,35 @@ abstract class GoogleUser { @anonymous @JS() abstract class _GoogleUser { + /// Forces a refresh of the access token, and then returns a Promise for the new AuthResponse. external Promise reloadAuthResponse(); } extension GoogleUserExtensions on GoogleUser { Future reloadAuthResponse() { - final Object t = this; - final _GoogleUser tt = t; + final _GoogleUser tt = this as _GoogleUser; return promiseToFuture(tt.reloadAuthResponse()); } } /// Initializes the GoogleAuth object. /// Reference: https://developers.google.com/api-client-library/javascript/reference/referencedocs#gapiauth2initparams -@JS("gapi.auth2.init") +@JS('gapi.auth2.init') external GoogleAuth init(ClientConfig params); /// Returns the GoogleAuth object. You must initialize the GoogleAuth object with gapi.auth2.init() before calling this method. -@JS("gapi.auth2.getAuthInstance") -external GoogleAuth getAuthInstance(); +@JS('gapi.auth2.getAuthInstance') +external GoogleAuth? getAuthInstance(); /// Performs a one time OAuth 2.0 authorization. /// Reference: https://developers.google.com/api-client-library/javascript/reference/referencedocs#gapiauth2authorizeparams-callback -@JS("gapi.auth2.authorize") +@JS('gapi.auth2.authorize') external void authorize( AuthorizeConfig params, void callback(AuthorizeResponse response)); // End module gapi.auth2 // Module gapi.signin2 -@JS("gapi.signin2.render") +@JS('gapi.signin2.render') external void render( dynamic id, dynamic diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/load_gapi.dart b/packages/google_sign_in/google_sign_in_web/lib/src/load_gapi.dart index f954ff1dce6b..0d3e4165227c 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/load_gapi.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/load_gapi.dart @@ -20,7 +20,7 @@ external set gapiOnloadCallback(Function callback); /// This is only exposed for testing. It shouldn't be accessed by users of the /// plugin as it could break at any point. @visibleForTesting -const String kGapiOnloadCallbackFunctionName = "gapiOnloadCallback"; +const String kGapiOnloadCallbackFunctionName = 'gapiOnloadCallback'; String _addOnloadToScript(String url) => url.startsWith('data:') ? url : '$url?onload=$kGapiOnloadCallbackFunctionName'; diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/utils.dart b/packages/google_sign_in/google_sign_in_web/lib/src/utils.dart index 36bb52dce0f3..98cb24efaeeb 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/utils.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/utils.dart @@ -9,13 +9,22 @@ import 'package:google_sign_in_platform_interface/google_sign_in_platform_interf import 'generated/gapiauth2.dart' as auth2; -/// Injects a bunch of libraries in the and returns a -/// Future that resolves when all load. -Future injectJSLibraries(List libraries, - {html.HtmlElement target /*, Duration timeout */}) { +/// Injects a list of JS [libraries] as `script` tags into a [target] [html.HtmlElement]. +/// +/// If [target] is not provided, it defaults to the web app's `head` tag (see `web/index.html`). +/// [libraries] is a list of URLs that are used as the `src` attribute of `script` tags +/// to which an `onLoad` listener is attached (one per URL). +/// +/// Returns a [Future] that resolves when all of the `script` tags `onLoad` events trigger. +Future injectJSLibraries( + List libraries, { + html.HtmlElement? target, +}) { final List> loading = >[]; final List tags = []; + final html.Element targetElement = target ?? html.querySelector('head')!; + libraries.forEach((String library) { final html.ScriptElement script = html.ScriptElement() ..async = true @@ -25,24 +34,26 @@ Future injectJSLibraries(List libraries, loading.add(script.onLoad.first); tags.add(script); }); - (target ?? html.querySelector('head')).children.addAll(tags); + + targetElement.children.addAll(tags); return Future.wait(loading); } -/// Utility method that converts `currentUser` to the equivalent -/// [GoogleSignInUserData]. +/// Utility method that converts `currentUser` to the equivalent [GoogleSignInUserData]. +/// /// This method returns `null` when the [currentUser] is not signed in. -GoogleSignInUserData gapiUserToPluginUserData(auth2.GoogleUser currentUser) { +GoogleSignInUserData? gapiUserToPluginUserData(auth2.GoogleUser? currentUser) { final bool isSignedIn = currentUser?.isSignedIn() ?? false; - final auth2.BasicProfile profile = currentUser?.getBasicProfile(); + final auth2.BasicProfile? profile = currentUser?.getBasicProfile(); if (!isSignedIn || profile?.getId() == null) { return null; } + return GoogleSignInUserData( displayName: profile?.getName(), - email: profile?.getEmail(), - id: profile?.getId(), + email: profile?.getEmail() ?? '', + id: profile?.getId() ?? '', photoUrl: profile?.getImageUrl(), - idToken: currentUser.getAuthResponse()?.id_token, + idToken: currentUser?.getAuthResponse().id_token, ); } diff --git a/packages/google_sign_in/google_sign_in_web/pubspec.yaml b/packages/google_sign_in/google_sign_in_web/pubspec.yaml index ac9d36bd15be..ae6807cd9231 100644 --- a/packages/google_sign_in/google_sign_in_web/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_web/pubspec.yaml @@ -2,7 +2,7 @@ name: google_sign_in_web description: Flutter plugin for Google Sign-In, a secure authentication system for signing in with a Google account on Android, iOS and Web. homepage: https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in_web -version: 0.9.2+1 +version: 0.10.0 flutter: plugin: @@ -12,23 +12,19 @@ flutter: fileName: google_sign_in_web.dart dependencies: - google_sign_in_platform_interface: ^1.1.0 + google_sign_in_platform_interface: ^2.0.0 flutter: sdk: flutter flutter_web_plugins: sdk: flutter - meta: ^1.1.7 - js: ^0.6.1 + meta: ^1.3.0 + js: ^0.6.3 dev_dependencies: flutter_test: sdk: flutter - google_sign_in: ^4.0.14 - pedantic: ^1.8.0 - mockito: ^4.1.1 - integration_test: - path: ../../integration_test + pedantic: ^1.10.0 environment: - sdk: ">=2.6.0 <3.0.0" - flutter: ">=1.12.13+hotfix.4" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" diff --git a/packages/google_sign_in/google_sign_in_web/test/README.md b/packages/google_sign_in/google_sign_in_web/test/README.md index 7c48d024ba57..7c5b4ad682ba 100644 --- a/packages/google_sign_in/google_sign_in_web/test/README.md +++ b/packages/google_sign_in/google_sign_in_web/test/README.md @@ -1,17 +1,5 @@ -# Running browser_tests +## test -Make sure you have updated to the latest Flutter master. +This package uses integration tests for testing. -1. Check what version of Chrome is running on the machine you're running tests on. - -2. Download and install driver for that version from here: - * - -3. Start the driver using `chromedriver --port=4444` - -4. Change into the `test` directory of your clone. - -5. Run tests: `flutter drive -d web-server --browser-name=chrome --target=test_driver/TEST_NAME_integration.dart`, or (in Linux): - - * Single: `./run_test test_driver/TEST_NAME_integration.dart` - * All: `./run_test` +See `example/README.md` for more info. diff --git a/packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_load_integration_test.dart b/packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_load_integration_test.dart deleted file mode 100644 index 39444c0daa24..000000000000 --- a/packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_load_integration_test.dart +++ /dev/null @@ -1,7 +0,0 @@ -// 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. - -import 'package:integration_test/integration_test_driver.dart'; - -Future main() async => integrationDriver(); diff --git a/packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_utils_integration_test.dart b/packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_utils_integration_test.dart deleted file mode 100644 index 39444c0daa24..000000000000 --- a/packages/google_sign_in/google_sign_in_web/test/test_driver/gapi_utils_integration_test.dart +++ /dev/null @@ -1,7 +0,0 @@ -// 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. - -import 'package:integration_test/integration_test_driver.dart'; - -Future main() async => integrationDriver(); diff --git a/packages/google_sign_in/google_sign_in_web/test/tests_exist_elsewhere_test.dart b/packages/google_sign_in/google_sign_in_web/test/tests_exist_elsewhere_test.dart new file mode 100644 index 000000000000..334f52186d9d --- /dev/null +++ b/packages/google_sign_in/google_sign_in_web/test/tests_exist_elsewhere_test.dart @@ -0,0 +1,10 @@ +import 'package:flutter_test/flutter_test.dart'; + +void main() { + test('Tell the user where to find the real tests', () { + print('---'); + print('This package uses integration_test for its tests.'); + print('See `example/README.md` for more info.'); + print('---'); + }); +} From 7668398fc4f8c3f61905cd23bfef138b2ba77685 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 26 Feb 2021 04:10:06 -0800 Subject: [PATCH 0221/1565] [google_sign_in] Bump app-facing version for NNBD stable (#3637) --- .../google_sign_in/CHANGELOG.md | 9 +---- .../google_sign_in/example/lib/main.dart | 39 ++++++++++--------- .../google_sign_in/example/pubspec.yaml | 6 +-- .../google_sign_in/pubspec.yaml | 17 ++++---- 4 files changed, 34 insertions(+), 37 deletions(-) diff --git a/packages/google_sign_in/google_sign_in/CHANGELOG.md b/packages/google_sign_in/google_sign_in/CHANGELOG.md index 85c8cc491105..57d1c9be3743 100644 --- a/packages/google_sign_in/google_sign_in/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in/CHANGELOG.md @@ -1,11 +1,6 @@ -## 5.0.0-nullsafety.1 +## 5.0.0 -* Document that the web plugin is not endorsed in the `nullsafety` prerelease for now. - -## 5.0.0-nullsafety - -* Migrate to nnbd. -* **Breaking change**: web plugins aren't endorsed in null-safe plugins yet. +* Migrate to null safety. ## 4.5.9 diff --git a/packages/google_sign_in/google_sign_in/example/lib/main.dart b/packages/google_sign_in/google_sign_in/example/lib/main.dart index a738c248a4a4..e003225af5cc 100755 --- a/packages/google_sign_in/google_sign_in/example/lib/main.dart +++ b/packages/google_sign_in/google_sign_in/example/lib/main.dart @@ -33,31 +33,31 @@ class SignInDemo extends StatefulWidget { } class SignInDemoState extends State { - GoogleSignInAccount _currentUser; - String _contactText; + GoogleSignInAccount? _currentUser; + String _contactText = ''; @override void initState() { super.initState(); - _googleSignIn.onCurrentUserChanged.listen((GoogleSignInAccount account) { + _googleSignIn.onCurrentUserChanged.listen((GoogleSignInAccount? account) { setState(() { _currentUser = account; }); if (_currentUser != null) { - _handleGetContact(); + _handleGetContact(_currentUser!); } }); _googleSignIn.signInSilently(); } - Future _handleGetContact() async { + Future _handleGetContact(GoogleSignInAccount user) async { setState(() { _contactText = "Loading contact info..."; }); final http.Response response = await http.get( - 'https://people.googleapis.com/v1/people/me/connections' - '?requestMask.includeField=person.names', - headers: await _currentUser.authHeaders, + Uri.parse('https://people.googleapis.com/v1/people/me/connections' + '?requestMask.includeField=person.names'), + headers: await user.authHeaders, ); if (response.statusCode != 200) { setState(() { @@ -68,7 +68,7 @@ class SignInDemoState extends State { return; } final Map data = json.decode(response.body); - final String namedContact = _pickFirstNamedContact(data); + final String? namedContact = _pickFirstNamedContact(data); setState(() { if (namedContact != null) { _contactText = "I see you know $namedContact!"; @@ -78,14 +78,14 @@ class SignInDemoState extends State { }); } - String _pickFirstNamedContact(Map data) { - final List connections = data['connections']; - final Map contact = connections?.firstWhere( + String? _pickFirstNamedContact(Map data) { + final List? connections = data['connections']; + final Map? contact = connections?.firstWhere( (dynamic contact) => contact['names'] != null, orElse: () => null, ); if (contact != null) { - final Map name = contact['names'].firstWhere( + final Map? name = contact['names'].firstWhere( (dynamic name) => name['displayName'] != null, orElse: () => null, ); @@ -107,26 +107,27 @@ class SignInDemoState extends State { Future _handleSignOut() => _googleSignIn.disconnect(); Widget _buildBody() { - if (_currentUser != null) { + GoogleSignInAccount? user = _currentUser; + if (user != null) { return Column( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ ListTile( leading: GoogleUserCircleAvatar( - identity: _currentUser, + identity: user, ), - title: Text(_currentUser.displayName ?? ''), - subtitle: Text(_currentUser.email ?? ''), + title: Text(user.displayName ?? ''), + subtitle: Text(user.email), ), const Text("Signed in successfully."), - Text(_contactText ?? ''), + Text(_contactText), ElevatedButton( child: const Text('SIGN OUT'), onPressed: _handleSignOut, ), ElevatedButton( child: const Text('REFRESH'), - onPressed: _handleGetContact, + onPressed: () => _handleGetContact(user), ), ], ); diff --git a/packages/google_sign_in/google_sign_in/example/pubspec.yaml b/packages/google_sign_in/google_sign_in/example/pubspec.yaml index e35aa9ace6a3..b5a1f3e1c2cc 100755 --- a/packages/google_sign_in/google_sign_in/example/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/example/pubspec.yaml @@ -11,10 +11,10 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - http: ^0.12.0 + http: ^0.13.0 dev_dependencies: - pedantic: ^1.8.0 + pedantic: ^1.10.0 integration_test: path: ../../../integration_test flutter_driver: @@ -24,5 +24,5 @@ flutter: uses-material-design: true environment: - sdk: ">=2.0.0-dev.28.0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.4" diff --git a/packages/google_sign_in/google_sign_in/pubspec.yaml b/packages/google_sign_in/google_sign_in/pubspec.yaml index ca1fe8d829b8..06fa12c0f4c0 100644 --- a/packages/google_sign_in/google_sign_in/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/pubspec.yaml @@ -2,7 +2,7 @@ name: google_sign_in description: Flutter plugin for Google Sign-In, a secure authentication system for signing in with a Google account on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in -version: 5.0.0-nullsafety.1 +version: 5.0.0 flutter: plugin: @@ -12,25 +12,26 @@ flutter: pluginClass: GoogleSignInPlugin ios: pluginClass: FLTGoogleSignInPlugin - #web: - # default_package: google_sign_in_web + web: + default_package: google_sign_in_web dependencies: - google_sign_in_platform_interface: ^2.0.0-nullsafety + google_sign_in_platform_interface: ^2.0.0 + google_sign_in_web: ^0.10.0 flutter: sdk: flutter - meta: ^1.3.0-nullsafety.6 + meta: ^1.3.0 dev_dependencies: - http: ^0.12.0 + http: ^0.13.0 flutter_driver: sdk: flutter flutter_test: sdk: flutter - pedantic: ^1.10.0-nullsafety.1 + pedantic: ^1.10.0 integration_test: path: ../../integration_test environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.5" From ad650f94f95664a913fc913147fa03a8e0057c91 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 26 Feb 2021 09:29:05 -0800 Subject: [PATCH 0222/1565] [file_selector] Endorse web (#3643) --- packages/file_selector/file_selector/CHANGELOG.md | 4 ++++ packages/file_selector/file_selector/pubspec.yaml | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/file_selector/file_selector/CHANGELOG.md b/packages/file_selector/file_selector/CHANGELOG.md index 64ac5959a7c0..cea752e51558 100644 --- a/packages/file_selector/file_selector/CHANGELOG.md +++ b/packages/file_selector/file_selector/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.8.1 + +Endorse the web implementation. + ## 0.8.0 Migrate to null safety. diff --git a/packages/file_selector/file_selector/pubspec.yaml b/packages/file_selector/file_selector/pubspec.yaml index 34b459cca720..3d03de09e9f2 100644 --- a/packages/file_selector/file_selector/pubspec.yaml +++ b/packages/file_selector/file_selector/pubspec.yaml @@ -1,12 +1,19 @@ name: file_selector description: Flutter plugin for opening and saving files. homepage: https://github.com/flutter/plugins/tree/master/packages/file_selector/file_selector -version: 0.8.0 +version: 0.8.1 + +flutter: + plugin: + platforms: + web: + default_package: file_selector_web dependencies: flutter: sdk: flutter file_selector_platform_interface: ^2.0.0 + file_selector_web: ^0.8.1 dev_dependencies: flutter_test: From aead5acb35c6fe2798986e9caf2c89379ec519bc Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 26 Feb 2021 10:19:07 -0800 Subject: [PATCH 0223/1565] [extension_google_sign_in_as_googleapis_auth] Migrate to null safety (#3642) Migrates to NNBD. Replaces Mockito-based fakes with test's Fake. --- .../CHANGELOG.md | 5 +++ .../example/lib/main.dart | 3 +- .../example/pubspec.yaml | 6 +-- ...ion_google_sign_in_as_googleapis_auth.dart | 15 ++++--- .../pubspec.yaml | 16 +++---- ...oogle_sign_in_as_googleapis_auth_test.dart | 42 +++++++++++-------- 6 files changed, 53 insertions(+), 34 deletions(-) diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md index 4afb1a0e98bf..5e29f340599b 100644 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md +++ b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.0.0 + +* Migrate to null safety. +* Fixes the requested scopes to use the `GoogleSignIn` instance's `scopes`. + ## 1.0.4 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/lib/main.dart b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/lib/main.dart index 597ab563ae5b..0ec62a832648 100755 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/lib/main.dart +++ b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/lib/main.dart @@ -56,7 +56,8 @@ class SignInDemoState extends State { _contactText = 'Loading contact info...'; }); - final peopleApi = PeopleApi(await _googleSignIn.authenticatedClient()); + final peopleApi = + PeopleServiceApi(await _googleSignIn.authenticatedClient()); final response = await peopleApi.people.connections.list( 'people/me', personFields: 'names', diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml index 48dfef644a5c..d3b428d190c9 100755 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml +++ b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml @@ -4,7 +4,7 @@ description: Example of Google Sign-In plugin and googleapis. dependencies: flutter: sdk: flutter - google_sign_in: ^4.4.1 + google_sign_in: ^5.0.0 extension_google_sign_in_as_googleapis_auth: # When depending on this package from a real application you should use: # extension_google_sign_in_as_googleapis_auth: ^x.y.z @@ -12,10 +12,10 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - googleapis: ^0.55.0 + googleapis: ^1.0.0 dev_dependencies: - pedantic: ^1.8.0 + pedantic: ^1.10.0 integration_test: path: ../../../integration_test flutter_driver: diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/lib/extension_google_sign_in_as_googleapis_auth.dart b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/lib/extension_google_sign_in_as_googleapis_auth.dart index eec45cc0e89a..8c8ede5eee1a 100644 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/lib/extension_google_sign_in_as_googleapis_auth.dart +++ b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/lib/extension_google_sign_in_as_googleapis_auth.dart @@ -15,15 +15,20 @@ import 'package:http/http.dart' as http; /// client that can be used with the rest of the `googleapis` libraries. extension GoogleApisGoogleSignInAuth on GoogleSignIn { /// Retrieve a `googleapis` authenticated client. - Future authenticatedClient({ - @visibleForTesting GoogleSignInAuthentication debugAuthentication, - @visibleForTesting List debugScopes = const [], + Future authenticatedClient({ + @visibleForTesting GoogleSignInAuthentication? debugAuthentication, + @visibleForTesting List? debugScopes, }) async { - final auth = debugAuthentication ?? await currentUser.authentication; + final GoogleSignInAuthentication? auth = + debugAuthentication ?? await currentUser?.authentication; + final String? oathTokenString = auth?.accessToken; + if (oathTokenString == null) { + return null; + } final credentials = googleapis_auth.AccessCredentials( googleapis_auth.AccessToken( 'Bearer', - auth.accessToken, + oathTokenString, // We don't know when the token expires, so we assume "never" DateTime.now().toUtc().add(Duration(days: 365)), ), diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/pubspec.yaml b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/pubspec.yaml index 9da5f0baa848..7d86b67196d0 100644 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/pubspec.yaml +++ b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/pubspec.yaml @@ -6,23 +6,23 @@ name: extension_google_sign_in_as_googleapis_auth description: A bridge package between google_sign_in and googleapis_auth, to create Authenticated Clients from google_sign_in user credentials. -version: 1.0.4 +version: 2.0.0 homepage: https://github.com/flutter/plugins/google_sign_in/extension_google_sign_in_as_googleapis_auth dependencies: flutter: sdk: flutter - google_sign_in: ^4.4.1 - googleapis_auth: ^0.2.11+1 - meta: ^1.1.8 - http: ^0.12.1 + google_sign_in: ^5.0.0 + googleapis_auth: ^1.0.0 + meta: ^1.3.0 + http: ^0.13.0 dev_dependencies: - mockito: ^4.1.1 - pedantic: ^1.9.0 + pedantic: ^1.10.0 + test: ^1.16.3 flutter_test: sdk: flutter environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.12.13+hotfix.4" diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/test/extension_google_sign_in_as_googleapis_auth_test.dart b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/test/extension_google_sign_in_as_googleapis_auth_test.dart index 9f86703d4bb8..508f366eacde 100644 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/test/extension_google_sign_in_as_googleapis_auth_test.dart +++ b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/test/extension_google_sign_in_as_googleapis_auth_test.dart @@ -7,25 +7,25 @@ import 'package:google_sign_in/google_sign_in.dart'; import 'package:googleapis_auth/auth.dart' as auth; import 'package:extension_google_sign_in_as_googleapis_auth/extension_google_sign_in_as_googleapis_auth.dart'; -import 'package:mockito/mockito.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:test/fake.dart'; -// Mocks so I don't have to prepare all the GoogleSignIn environment. -class MockGoogleSignIn extends Mock implements GoogleSignIn {} +const SOME_FAKE_ACCESS_TOKEN = 'this-is-something-not-null'; +const DEBUG_FAKE_SCOPES = ['some-scope', 'another-scope']; +const SIGN_IN_FAKE_SCOPES = ['some-scope', 'another-scope']; -class MockGoogleSignInAuthentication extends Mock - implements GoogleSignInAuthentication {} +class FakeGoogleSignIn extends Fake implements GoogleSignIn { + final List scopes = SIGN_IN_FAKE_SCOPES; +} -const SOME_FAKE_ACCESS_TOKEN = 'this-is-something-not-null'; -const SOME_FAKE_SCOPES = ['some-scope', 'another-scope']; +class FakeGoogleSignInAuthentication extends Fake + implements GoogleSignInAuthentication { + final String accessToken = SOME_FAKE_ACCESS_TOKEN; +} void main() { - GoogleSignIn signIn = MockGoogleSignIn(); - final authMock = MockGoogleSignInAuthentication(); - - setUp(() { - when(authMock.accessToken).thenReturn(SOME_FAKE_ACCESS_TOKEN); - }); + GoogleSignIn signIn = FakeGoogleSignIn(); + final authMock = FakeGoogleSignInAuthentication(); test('authenticatedClient returns an authenticated client', () async { final client = await signIn.authenticatedClient( @@ -34,13 +34,21 @@ void main() { expect(client, isA()); }); + test('authenticatedClient uses GoogleSignIn scopes by default', () async { + final client = (await signIn.authenticatedClient( + debugAuthentication: authMock, + ))!; + expect(client.credentials.accessToken.data, equals(SOME_FAKE_ACCESS_TOKEN)); + expect(client.credentials.scopes, equals(SIGN_IN_FAKE_SCOPES)); + }); + test('authenticatedClient returned client contains the passed-in credentials', () async { - final client = await signIn.authenticatedClient( + final client = (await signIn.authenticatedClient( debugAuthentication: authMock, - debugScopes: SOME_FAKE_SCOPES, - ); + debugScopes: DEBUG_FAKE_SCOPES, + ))!; expect(client.credentials.accessToken.data, equals(SOME_FAKE_ACCESS_TOKEN)); - expect(client.credentials.scopes, equals(SOME_FAKE_SCOPES)); + expect(client.credentials.scopes, equals(DEBUG_FAKE_SCOPES)); }); } From 4afca62b46315dcdbfa2b043d703aaf4ebf6960c Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 26 Feb 2021 11:40:19 -0800 Subject: [PATCH 0224/1565] Fix Cirrus script for firebase testlab tests (#3634) --- .cirrus.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 6b3614178b11..5a25b773ea33 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -105,11 +105,11 @@ task: - export CIRRUS_COMMIT_MESSAGE="" - ./script/incremental_build.sh build-examples --apk - ./script/incremental_build.sh java-test # must come after apk build - - if [[ $GCLOUD_FIREBASE_TESTLAB_KEY == ENCRYPTED* ]]; then - - echo "This user does not have permission to run Firebase Test Lab tests." - - else + - if [[ -n "$GCLOUD_FIREBASE_TESTLAB_KEY" ]]; then - echo $GCLOUD_FIREBASE_TESTLAB_KEY > ${HOME}/gcloud-service-key.json - ./script/incremental_build.sh firebase-test-lab --device model=flame,version=29 --device model=starqlteue,version=26 + - else + - echo "This user does not have permission to run Firebase Test Lab tests." - fi - export CIRRUS_CHANGE_MESSAGE=`cat /tmp/cirrus_change_message.txt` - export CIRRUS_COMMIT_MESSAGE=`cat /tmp/cirrus_commit_message.txt` From 4b4913c8dd82be0b3ff847edbc81b78c033ea67f Mon Sep 17 00:00:00 2001 From: Juanjo Tugores Date: Fri, 26 Feb 2021 16:31:02 -0600 Subject: [PATCH 0225/1565] [file_selector_platform_interface]: Verify that extensions don't have leading dots. (#3451) --- .../file_selector_platform_interface/CHANGELOG.md | 4 ++++ .../lib/src/types/x_type_group/x_type_group.dart | 7 +++++-- .../file_selector_platform_interface/pubspec.yaml | 2 +- .../test/method_channel_file_selector_test.dart | 12 ++++++------ .../test/x_type_group_test.dart | 9 ++++++++- 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/packages/file_selector/file_selector_platform_interface/CHANGELOG.md b/packages/file_selector/file_selector_platform_interface/CHANGELOG.md index ed720ca0515d..8fcc3e06ef49 100644 --- a/packages/file_selector/file_selector_platform_interface/CHANGELOG.md +++ b/packages/file_selector/file_selector_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +* Replace extensions with leading dots. + ## 2.0.0 * Migration to null-safety diff --git a/packages/file_selector/file_selector_platform_interface/lib/src/types/x_type_group/x_type_group.dart b/packages/file_selector/file_selector_platform_interface/lib/src/types/x_type_group/x_type_group.dart index f3f05e2ab3a6..7b3cb12be9f1 100644 --- a/packages/file_selector/file_selector_platform_interface/lib/src/types/x_type_group/x_type_group.dart +++ b/packages/file_selector/file_selector_platform_interface/lib/src/types/x_type_group/x_type_group.dart @@ -10,11 +10,11 @@ class XTypeGroup { /// allowed. XTypeGroup({ this.label, - this.extensions, + List? extensions, this.mimeTypes, this.macUTIs, this.webWildCards, - }); + }) : this.extensions = _removeLeadingDots(extensions); /// The 'name' or reference to this group of types final String? label; @@ -41,4 +41,7 @@ class XTypeGroup { 'webWildCards': webWildCards, }; } + + static List? _removeLeadingDots(List? exts) => + exts?.map((ext) => ext.startsWith('.') ? ext.substring(1) : ext).toList(); } diff --git a/packages/file_selector/file_selector_platform_interface/pubspec.yaml b/packages/file_selector/file_selector_platform_interface/pubspec.yaml index 30398a2f0d23..980730eb2676 100644 --- a/packages/file_selector/file_selector_platform_interface/pubspec.yaml +++ b/packages/file_selector/file_selector_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the file_selector plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/file_selector/file_selector_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0 +version: 2.0.1 dependencies: flutter: diff --git a/packages/file_selector/file_selector_platform_interface/test/method_channel_file_selector_test.dart b/packages/file_selector/file_selector_platform_interface/test/method_channel_file_selector_test.dart index 99f9fe0f0e3b..c863ad361112 100644 --- a/packages/file_selector/file_selector_platform_interface/test/method_channel_file_selector_test.dart +++ b/packages/file_selector/file_selector_platform_interface/test/method_channel_file_selector_test.dart @@ -29,14 +29,14 @@ void main() { test('passes the accepted type groups correctly', () async { final group = XTypeGroup( label: 'text', - extensions: ['.txt'], + extensions: ['txt'], mimeTypes: ['text/plain'], macUTIs: ['public.text'], ); final groupTwo = XTypeGroup( label: 'image', - extensions: ['.jpg'], + extensions: ['jpg'], mimeTypes: ['image/jpg'], macUTIs: ['public.image'], webWildCards: ['image/*']); @@ -90,14 +90,14 @@ void main() { test('passes the accepted type groups correctly', () async { final group = XTypeGroup( label: 'text', - extensions: ['.txt'], + extensions: ['txt'], mimeTypes: ['text/plain'], macUTIs: ['public.text'], ); final groupTwo = XTypeGroup( label: 'image', - extensions: ['.jpg'], + extensions: ['jpg'], mimeTypes: ['image/jpg'], macUTIs: ['public.image'], webWildCards: ['image/*']); @@ -152,14 +152,14 @@ void main() { test('passes the accepted type groups correctly', () async { final group = XTypeGroup( label: 'text', - extensions: ['.txt'], + extensions: ['txt'], mimeTypes: ['text/plain'], macUTIs: ['public.text'], ); final groupTwo = XTypeGroup( label: 'image', - extensions: ['.jpg'], + extensions: ['jpg'], mimeTypes: ['image/jpg'], macUTIs: ['public.image'], webWildCards: ['image/*']); diff --git a/packages/file_selector/file_selector_platform_interface/test/x_type_group_test.dart b/packages/file_selector/file_selector_platform_interface/test/x_type_group_test.dart index bde89f46405d..21bbac5d0f90 100644 --- a/packages/file_selector/file_selector_platform_interface/test/x_type_group_test.dart +++ b/packages/file_selector/file_selector_platform_interface/test/x_type_group_test.dart @@ -9,7 +9,7 @@ void main() { group('XTypeGroup', () { test('toJSON() creates correct map', () { final label = 'test group'; - final extensions = ['.txt', '.jpg']; + final extensions = ['txt', 'jpg']; final mimeTypes = ['text/plain']; final macUTIs = ['public.plain-text']; final webWildCards = ['image/*']; @@ -41,5 +41,12 @@ void main() { expect(jsonMap['macUTIs'], null); expect(jsonMap['webWildCards'], null); }); + + test('Leading dots are removed from extensions', () { + final extensions = ['.txt', '.jpg']; + final group = XTypeGroup(extensions: extensions); + + expect(group.extensions, ['txt', 'jpg']); + }); }); } From c1c4514b9967960c9a33e73d5ca6037385f240ef Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Fri, 26 Feb 2021 14:36:05 -0800 Subject: [PATCH 0226/1565] [image_picker_for_web] Bump version for NNBD stable (#3635) --- .../image_picker/image_picker_for_web/CHANGELOG.md | 7 ++----- .../image_picker/image_picker_for_web/pubspec.yaml | 13 ++++++------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/CHANGELOG.md b/packages/image_picker/image_picker_for_web/CHANGELOG.md index fcc6c9980c29..7b2c4077e28d 100644 --- a/packages/image_picker/image_picker_for_web/CHANGELOG.md +++ b/packages/image_picker/image_picker_for_web/CHANGELOG.md @@ -1,10 +1,7 @@ -# 2.0.0-nullsafety.1 - -* Add doc comments to point out that some arguments aren't supported on the web. - -# 2.0.0-nullsafety +# 2.0.0 * Migrate to null safety. +* Add doc comments to point out that some arguments aren't supported on the web. # 0.1.0+3 diff --git a/packages/image_picker/image_picker_for_web/pubspec.yaml b/packages/image_picker/image_picker_for_web/pubspec.yaml index adc636192c69..045be48eb1c5 100644 --- a/packages/image_picker/image_picker_for_web/pubspec.yaml +++ b/packages/image_picker/image_picker_for_web/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker_for_web description: Web platform implementation of image_picker homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker_for_web -version: 2.0.0-nullsafety.1 +version: 2.0.0 flutter: plugin: @@ -12,19 +12,18 @@ flutter: fileName: image_picker_for_web.dart dependencies: - image_picker_platform_interface: ^2.0.0-nullsafety + image_picker_platform_interface: ^2.0.0 + meta: ^1.3.0 flutter: sdk: flutter flutter_web_plugins: sdk: flutter - meta: ^1.3.0-nullsafety.6 - js: ^0.6.3-nullsafety.3 dev_dependencies: + pedantic: ^1.10.0 flutter_test: sdk: flutter - pedantic: ^1.10.0 environment: - sdk: ">=2.12.0-0 <3.0.0" - flutter: ">=1.10.0" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" From a0fe2225e2550d4a1a4214c7582dad90feff5d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petrus=20Nguy=E1=BB=85n=20Th=C3=A1i=20H=E1=BB=8Dc?= Date: Sat, 27 Feb 2021 07:31:04 +0700 Subject: [PATCH 0227/1565] [shared_preferences] Don't create additional Handler when method channel is called. (#3639) --- .../shared_preferences/shared_preferences/CHANGELOG.md | 4 ++++ .../plugins/sharedpreferences/MethodCallHandlerImpl.java | 9 +++++++-- .../sharedpreferences/SharedPreferencesPlugin.java | 5 ++++- .../shared_preferences/shared_preferences/pubspec.yaml | 2 +- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/shared_preferences/shared_preferences/CHANGELOG.md b/packages/shared_preferences/shared_preferences/CHANGELOG.md index 63c042a1194e..1516163b8807 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.3 + +* Android: don't create additional Handler when method channel is called. + ## 2.0.2 * Don't create additional thread pools when method channel is called. diff --git a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java index d58cc32ed625..4f55d882005f 100644 --- a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java +++ b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java @@ -44,6 +44,7 @@ class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { private final android.content.SharedPreferences preferences; private final ExecutorService executor; + private final Handler handler; /** * Constructs a {@link MethodCallHandlerImpl} instance. Creates a {@link @@ -53,6 +54,7 @@ class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { preferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); executor = new ThreadPoolExecutor(0, 1, 30L, TimeUnit.SECONDS, new SynchronousQueue()); + handler = new Handler(Looper.getMainLooper()); } @Override @@ -125,10 +127,13 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) { } } + public void teardown() { + handler.removeCallbacksAndMessages(null); + executor.shutdown(); + } + private void commitAsync( final SharedPreferences.Editor editor, final MethodChannel.Result result) { - final Handler handler = new Handler(Looper.getMainLooper()); - executor.execute( new Runnable() { @Override diff --git a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java index be627f3ce613..83163f82d9ec 100644 --- a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java +++ b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java @@ -13,6 +13,7 @@ public class SharedPreferencesPlugin implements FlutterPlugin { private static final String CHANNEL_NAME = "plugins.flutter.io/shared_preferences"; private MethodChannel channel; + private MethodCallHandlerImpl handler; @SuppressWarnings("deprecation") public static void registerWith(io.flutter.plugin.common.PluginRegistry.Registrar registrar) { @@ -32,11 +33,13 @@ public void onDetachedFromEngine(FlutterPlugin.FlutterPluginBinding binding) { private void setupChannel(BinaryMessenger messenger, Context context) { channel = new MethodChannel(messenger, CHANNEL_NAME); - MethodCallHandlerImpl handler = new MethodCallHandlerImpl(context); + handler = new MethodCallHandlerImpl(context); channel.setMethodCallHandler(handler); } private void teardownChannel() { + handler.teardown(); + handler = null; channel.setMethodCallHandler(null); channel = null; } diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index 6f6ab1fee6e8..899266a4d6f0 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -2,7 +2,7 @@ name: shared_preferences description: Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences -version: 2.0.2 +version: 2.0.3 flutter: plugin: From 4155c431a93a946f18f5399799706ed147ce2a37 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 1 Mar 2021 09:23:54 -0800 Subject: [PATCH 0228/1565] migrate tests to null safety (#3645) --- packages/connectivity/connectivity/CHANGELOG.md | 4 ++++ packages/connectivity/connectivity/pubspec.yaml | 2 +- .../connectivity/connectivity/test/connectivity_test.dart | 6 ++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/connectivity/connectivity/CHANGELOG.md b/packages/connectivity/connectivity/CHANGELOG.md index c4566ae73fd0..2f471890695a 100644 --- a/packages/connectivity/connectivity/CHANGELOG.md +++ b/packages/connectivity/connectivity/CHANGELOG.md @@ -1,3 +1,7 @@ +## 3.0.1 + +* Migrate tests to null safety. + ## 3.0.0 * Migrate to null safety. diff --git a/packages/connectivity/connectivity/pubspec.yaml b/packages/connectivity/connectivity/pubspec.yaml index 254e325203d1..3aec6274f4b9 100644 --- a/packages/connectivity/connectivity/pubspec.yaml +++ b/packages/connectivity/connectivity/pubspec.yaml @@ -2,7 +2,7 @@ name: connectivity description: Flutter plugin for discovering the state of the network (WiFi & mobile/cellular) connectivity on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity -version: 3.0.0 +version: 3.0.1 flutter: plugin: diff --git a/packages/connectivity/connectivity/test/connectivity_test.dart b/packages/connectivity/connectivity/test/connectivity_test.dart index 6747c79bb64a..c95d0862444f 100644 --- a/packages/connectivity/connectivity/test/connectivity_test.dart +++ b/packages/connectivity/connectivity/test/connectivity_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(cyanglaz): Remove once Mockito is migrated to null safety. -// @dart = 2.9 import 'package:connectivity/connectivity.dart'; import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -18,8 +16,8 @@ const LocationAuthorizationStatus kGetLocationResult = void main() { group('Connectivity', () { - Connectivity connectivity; - MockConnectivityPlatform fakePlatform; + late Connectivity connectivity; + late MockConnectivityPlatform fakePlatform; setUp(() async { fakePlatform = MockConnectivityPlatform(); ConnectivityPlatform.instance = fakePlatform; From c42db71b8f805fffaddf6641b764098a50cc49bb Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 1 Mar 2021 09:25:52 -0800 Subject: [PATCH 0229/1565] Update pull_request_label.yml (#3647) --- .github/workflows/pull_request_label.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull_request_label.yml b/.github/workflows/pull_request_label.yml index 7b048d33e669..6b93864d3f3a 100644 --- a/.github/workflows/pull_request_label.yml +++ b/.github/workflows/pull_request_label.yml @@ -16,7 +16,7 @@ jobs: label: runs-on: ubuntu-latest steps: - - uses: actions/labeler@v3 + - uses: actions/labeler@9794b1493b6f1fa7b006c5f8635a19c76c98be95 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" sync-labels: true @@ -25,7 +25,7 @@ jobs: if: github.event.action == 'closed' && github.event.pull_request.merged == true runs-on: ubuntu-latest steps: - - uses: actions/labeler@v3 + - uses: actions/labeler@9794b1493b6f1fa7b006c5f8635a19c76c98be95 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" configuration-path: .github/post_merge_labeler.yml From 98a90d65564e123aa1877f1c0f31489020ebe6fd Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Mon, 1 Mar 2021 11:46:33 -0800 Subject: [PATCH 0230/1565] Update plugin_platform_interface min version (#3650) To avoid intra-repo plugin conflicts during the NNBD stable migration, `plugin_platform_interface` allowed either 1.x or 2.0. However, 1.0.x isn't null-safe so this can cause apps that don't have all their packages fully updated can fail to run in strong mode (due to having an old local `plugin_platform_interface`. Now that everything has been updated, we can bump all the minimums so that people updating their plugins will get new versions of the dependency. --- packages/battery/battery/CHANGELOG.md | 4 ++++ packages/battery/battery/pubspec.yaml | 4 ++-- packages/battery/battery_platform_interface/CHANGELOG.md | 4 ++++ packages/battery/battery_platform_interface/pubspec.yaml | 4 ++-- packages/camera/camera_platform_interface/CHANGELOG.md | 6 +++++- packages/camera/camera_platform_interface/pubspec.yaml | 4 ++-- packages/connectivity/connectivity/CHANGELOG.md | 4 ++++ packages/connectivity/connectivity/pubspec.yaml | 4 ++-- .../connectivity_platform_interface/CHANGELOG.md | 6 +++++- .../connectivity_platform_interface/pubspec.yaml | 4 ++-- .../device_info/device_info_platform_interface/CHANGELOG.md | 4 ++++ .../device_info/device_info_platform_interface/pubspec.yaml | 4 ++-- packages/file_selector/file_selector/CHANGELOG.md | 4 ++++ packages/file_selector/file_selector/pubspec.yaml | 4 ++-- .../file_selector_platform_interface/CHANGELOG.md | 4 ++++ .../file_selector_platform_interface/pubspec.yaml | 4 ++-- .../google_maps_flutter/google_maps_flutter/CHANGELOG.md | 4 ++++ .../google_maps_flutter/google_maps_flutter/pubspec.yaml | 4 ++-- .../google_maps_flutter_platform_interface/CHANGELOG.md | 4 ++++ .../google_maps_flutter_platform_interface/pubspec.yaml | 4 ++-- packages/image_picker/image_picker/CHANGELOG.md | 4 ++++ packages/image_picker/image_picker/pubspec.yaml | 4 ++-- .../image_picker_platform_interface/CHANGELOG.md | 4 ++++ .../image_picker_platform_interface/pubspec.yaml | 4 ++-- packages/path_provider/path_provider/CHANGELOG.md | 4 ++++ packages/path_provider/path_provider/pubspec.yaml | 4 ++-- .../path_provider_platform_interface/CHANGELOG.md | 4 ++++ .../path_provider_platform_interface/pubspec.yaml | 4 ++-- packages/url_launcher/url_launcher/CHANGELOG.md | 4 ++++ packages/url_launcher/url_launcher/example/pubspec.yaml | 2 +- packages/url_launcher/url_launcher/pubspec.yaml | 4 ++-- .../url_launcher_platform_interface/CHANGELOG.md | 4 ++++ .../url_launcher_platform_interface/pubspec.yaml | 4 ++-- .../wifi_info_flutter_platform_interface/CHANGELOG.md | 4 ++++ .../wifi_info_flutter_platform_interface/pubspec.yaml | 4 ++-- 35 files changed, 105 insertions(+), 37 deletions(-) diff --git a/packages/battery/battery/CHANGELOG.md b/packages/battery/battery/CHANGELOG.md index ae9e798c364d..ab1d98c7962f 100644 --- a/packages/battery/battery/CHANGELOG.md +++ b/packages/battery/battery/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +* Update platform_plugin_interface version requirement. + ## 2.0.0 * Migrate to null safety. diff --git a/packages/battery/battery/pubspec.yaml b/packages/battery/battery/pubspec.yaml index a987bd8c45a6..b705955efdef 100644 --- a/packages/battery/battery/pubspec.yaml +++ b/packages/battery/battery/pubspec.yaml @@ -2,7 +2,7 @@ name: battery description: Flutter plugin for accessing information about the battery state (full, charging, discharging) on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/battery/battery -version: 2.0.0 +version: 2.0.1 flutter: plugin: @@ -22,7 +22,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - plugin_platform_interface: ">=1.0.0 <3.0.0" + plugin_platform_interface: ^2.0.0 integration_test: path: ../../integration_test pedantic: ^1.10.0 diff --git a/packages/battery/battery_platform_interface/CHANGELOG.md b/packages/battery/battery_platform_interface/CHANGELOG.md index 2c51f2c2d352..a9106dd78ce9 100644 --- a/packages/battery/battery_platform_interface/CHANGELOG.md +++ b/packages/battery/battery_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +* Update platform_plugin_interface version requirement. + ## 2.0.0 * Migrate to null safety. diff --git a/packages/battery/battery_platform_interface/pubspec.yaml b/packages/battery/battery_platform_interface/pubspec.yaml index 61edad6cc04b..1303c22b5614 100644 --- a/packages/battery/battery_platform_interface/pubspec.yaml +++ b/packages/battery/battery_platform_interface/pubspec.yaml @@ -3,13 +3,13 @@ description: A common platform interface for the battery plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/battery # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0 +version: 2.0.1 dependencies: flutter: sdk: flutter meta: ^1.3.0 - plugin_platform_interface: ">=1.0.0 <3.0.0" + plugin_platform_interface: ^2.0.0 dev_dependencies: flutter_test: diff --git a/packages/camera/camera_platform_interface/CHANGELOG.md b/packages/camera/camera_platform_interface/CHANGELOG.md index f7f78197d204..49214d24d18e 100644 --- a/packages/camera/camera_platform_interface/CHANGELOG.md +++ b/packages/camera/camera_platform_interface/CHANGELOG.md @@ -1,10 +1,14 @@ +## 2.0.1 + +* Update platform_plugin_interface version requirement. + ## 2.0.0 - Stable null safety release. ## 1.6.0 -- Added VideoRecordedEvent to support ending a video recording in the native implementation. +- Added VideoRecordedEvent to support ending a video recording in the native implementation. ## 1.5.0 diff --git a/packages/camera/camera_platform_interface/pubspec.yaml b/packages/camera/camera_platform_interface/pubspec.yaml index 10897073dc5c..12c5bc48b9ec 100644 --- a/packages/camera/camera_platform_interface/pubspec.yaml +++ b/packages/camera/camera_platform_interface/pubspec.yaml @@ -3,13 +3,13 @@ description: A common platform interface for the camera plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0 +version: 2.0.1 dependencies: flutter: sdk: flutter meta: ^1.3.0 - plugin_platform_interface: ">=1.0.0 <3.0.0" + plugin_platform_interface: ^2.0.0 cross_file: ^0.3.1 stream_transform: ^2.0.0 diff --git a/packages/connectivity/connectivity/CHANGELOG.md b/packages/connectivity/connectivity/CHANGELOG.md index 2f471890695a..57de797ff045 100644 --- a/packages/connectivity/connectivity/CHANGELOG.md +++ b/packages/connectivity/connectivity/CHANGELOG.md @@ -1,3 +1,7 @@ +## 3.0.2 + +* Update platform_plugin_interface version requirement. + ## 3.0.1 * Migrate tests to null safety. diff --git a/packages/connectivity/connectivity/pubspec.yaml b/packages/connectivity/connectivity/pubspec.yaml index 3aec6274f4b9..eeef53c4faa4 100644 --- a/packages/connectivity/connectivity/pubspec.yaml +++ b/packages/connectivity/connectivity/pubspec.yaml @@ -2,7 +2,7 @@ name: connectivity description: Flutter plugin for discovering the state of the network (WiFi & mobile/cellular) connectivity on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity -version: 3.0.1 +version: 3.0.2 flutter: plugin: @@ -35,7 +35,7 @@ dev_dependencies: test: ^1.16.3 integration_test: path: ../../integration_test - plugin_platform_interface: ">=1.0.0 <3.0.0" + plugin_platform_interface: ^2.0.0 pedantic: ^1.10.0 environment: diff --git a/packages/connectivity/connectivity_platform_interface/CHANGELOG.md b/packages/connectivity/connectivity_platform_interface/CHANGELOG.md index 0b26cd52c9e9..ee75d03ccc65 100644 --- a/packages/connectivity/connectivity_platform_interface/CHANGELOG.md +++ b/packages/connectivity/connectivity_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +* Update platform_plugin_interface version requirement. + ## 2.0.0 * Migrate to null safety. @@ -12,7 +16,7 @@ ## 1.0.5 -* Remove dart:io Platform checks from the MethodChannel implementation. This is +* Remove dart:io Platform checks from the MethodChannel implementation. This is tripping the analysis of other versions of the plugin. ## 1.0.4 diff --git a/packages/connectivity/connectivity_platform_interface/pubspec.yaml b/packages/connectivity/connectivity_platform_interface/pubspec.yaml index 1e89972dd816..5cc953aeb1b4 100644 --- a/packages/connectivity/connectivity_platform_interface/pubspec.yaml +++ b/packages/connectivity/connectivity_platform_interface/pubspec.yaml @@ -3,13 +3,13 @@ description: A common platform interface for the connectivity plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0 +version: 2.0.1 dependencies: flutter: sdk: flutter meta: ^1.3.0 - plugin_platform_interface: ">=1.0.0 <3.0.0" + plugin_platform_interface: ^2.0.0 dev_dependencies: flutter_test: diff --git a/packages/device_info/device_info_platform_interface/CHANGELOG.md b/packages/device_info/device_info_platform_interface/CHANGELOG.md index 23e9bc770c95..438d5bccad40 100644 --- a/packages/device_info/device_info_platform_interface/CHANGELOG.md +++ b/packages/device_info/device_info_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +* Update platform_plugin_interface version requirement. + ## 2.0.0 * Migrate to null safety. diff --git a/packages/device_info/device_info_platform_interface/pubspec.yaml b/packages/device_info/device_info_platform_interface/pubspec.yaml index 3887aea3eff2..4753c70984a4 100644 --- a/packages/device_info/device_info_platform_interface/pubspec.yaml +++ b/packages/device_info/device_info_platform_interface/pubspec.yaml @@ -3,13 +3,13 @@ description: A common platform interface for the device_info plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/device_info # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0 +version: 2.0.1 dependencies: flutter: sdk: flutter meta: ^1.3.0 - plugin_platform_interface: ">=1.0.0 <3.0.0" + plugin_platform_interface: ^2.0.0 dev_dependencies: flutter_test: diff --git a/packages/file_selector/file_selector/CHANGELOG.md b/packages/file_selector/file_selector/CHANGELOG.md index cea752e51558..2f8a4d0754f1 100644 --- a/packages/file_selector/file_selector/CHANGELOG.md +++ b/packages/file_selector/file_selector/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.8.2 + +* Update platform_plugin_interface version requirement. + ## 0.8.1 Endorse the web implementation. diff --git a/packages/file_selector/file_selector/pubspec.yaml b/packages/file_selector/file_selector/pubspec.yaml index 3d03de09e9f2..d8d610266641 100644 --- a/packages/file_selector/file_selector/pubspec.yaml +++ b/packages/file_selector/file_selector/pubspec.yaml @@ -1,7 +1,7 @@ name: file_selector description: Flutter plugin for opening and saving files. homepage: https://github.com/flutter/plugins/tree/master/packages/file_selector/file_selector -version: 0.8.1 +version: 0.8.2 flutter: plugin: @@ -19,7 +19,7 @@ dev_dependencies: flutter_test: sdk: flutter test: ^1.16.3 - plugin_platform_interface: ">=1.0.0 <3.0.0" + plugin_platform_interface: ^2.0.0 pedantic: ^1.10.0 environment: diff --git a/packages/file_selector/file_selector_platform_interface/CHANGELOG.md b/packages/file_selector/file_selector_platform_interface/CHANGELOG.md index 8fcc3e06ef49..ba595addfcaf 100644 --- a/packages/file_selector/file_selector_platform_interface/CHANGELOG.md +++ b/packages/file_selector/file_selector_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.2 + +* Update platform_plugin_interface version requirement. + ## 2.0.1 * Replace extensions with leading dots. diff --git a/packages/file_selector/file_selector_platform_interface/pubspec.yaml b/packages/file_selector/file_selector_platform_interface/pubspec.yaml index 980730eb2676..74b9d08c77ec 100644 --- a/packages/file_selector/file_selector_platform_interface/pubspec.yaml +++ b/packages/file_selector/file_selector_platform_interface/pubspec.yaml @@ -3,14 +3,14 @@ description: A common platform interface for the file_selector plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/file_selector/file_selector_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.1 +version: 2.0.2 dependencies: flutter: sdk: flutter meta: ^1.3.0 http: ^0.13.0 - plugin_platform_interface: ">=1.0.0 <3.0.0" + plugin_platform_interface: ^2.0.0 cross_file: ^0.3.0 dev_dependencies: diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index dae5caf89a60..eb16024575bb 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +* Update platform_plugin_interface version requirement. + ## 2.0.0 * Migrate to null-safety diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index 3d0e79473a33..d30c9d030de6 100644 --- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: google_maps_flutter description: A Flutter plugin for integrating Google Maps in iOS and Android applications. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter -version: 2.0.0 +version: 2.0.1 dependencies: flutter: @@ -19,7 +19,7 @@ dev_dependencies: sdk: flutter test: ^1.16.0 pedantic: ^1.10.0 - plugin_platform_interface: ">=1.0.0 <3.0.0" + plugin_platform_interface: ^2.0.0 stream_transform: ^2.0.0 flutter: diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md index 0d5748d13f79..b0ad668c8ddc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +* Update platform_plugin_interface version requirement. + ## 2.0.0 * Migrated to null-safety. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml index 602efe3e6c62..0796b71fbb62 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml @@ -3,13 +3,13 @@ description: A common platform interface for the google_maps_flutter plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0 +version: 2.0.1 dependencies: flutter: sdk: flutter meta: ^1.3.0 - plugin_platform_interface: ">=1.0.0 <3.0.0" + plugin_platform_interface: ^2.0.0 stream_transform: ^2.0.0 collection: ^1.15.0 diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md index 97aba4536000..4673c01f506e 100644 --- a/packages/image_picker/image_picker/CHANGELOG.md +++ b/packages/image_picker/image_picker/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.1 + +* Update platform_plugin_interface version requirement. + ## 0.7.0 * Migrate to nullsafety diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index 96881e6f2c65..fb351b3ece75 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker description: Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker -version: 0.7.0 +version: 0.7.1 flutter: plugin: @@ -26,7 +26,7 @@ dev_dependencies: path: ../../integration_test mockito: ^5.0.0-nullsafety.7 pedantic: ^1.10.0 - plugin_platform_interface: ">=1.0.0 <3.0.0" + plugin_platform_interface: ^2.0.0 environment: sdk: ">=2.12.0-259.9.beta <3.0.0" diff --git a/packages/image_picker/image_picker_platform_interface/CHANGELOG.md b/packages/image_picker/image_picker_platform_interface/CHANGELOG.md index f2e017e190c5..598f83b4b09b 100644 --- a/packages/image_picker/image_picker_platform_interface/CHANGELOG.md +++ b/packages/image_picker/image_picker_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +* Update platform_plugin_interface version requirement. + ## 2.0.0 * Migrate to null safety. diff --git a/packages/image_picker/image_picker_platform_interface/pubspec.yaml b/packages/image_picker/image_picker_platform_interface/pubspec.yaml index 9befba90215a..3443f158dc56 100644 --- a/packages/image_picker/image_picker_platform_interface/pubspec.yaml +++ b/packages/image_picker/image_picker_platform_interface/pubspec.yaml @@ -3,14 +3,14 @@ description: A common platform interface for the image_picker plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0 +version: 2.0.1 dependencies: flutter: sdk: flutter meta: ^1.3.0 http: ^0.13.0 - plugin_platform_interface: ">=1.0.0 <3.0.0" + plugin_platform_interface: ^2.0.0 dev_dependencies: flutter_test: diff --git a/packages/path_provider/path_provider/CHANGELOG.md b/packages/path_provider/path_provider/CHANGELOG.md index c28c617bbea4..ad812266139a 100644 --- a/packages/path_provider/path_provider/CHANGELOG.md +++ b/packages/path_provider/path_provider/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +* Update platform_plugin_interface version requirement. + ## 2.0.0 * Migrate to null safety. diff --git a/packages/path_provider/path_provider/pubspec.yaml b/packages/path_provider/path_provider/pubspec.yaml index 81941dac67b1..3ee67007f97d 100644 --- a/packages/path_provider/path_provider/pubspec.yaml +++ b/packages/path_provider/path_provider/pubspec.yaml @@ -1,7 +1,7 @@ name: path_provider description: Flutter plugin for getting commonly used locations on host platform file systems, such as the temp and app data directories. homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider -version: 2.0.0 +version: 2.0.1 flutter: plugin: @@ -34,7 +34,7 @@ dev_dependencies: flutter_driver: sdk: flutter pedantic: ^1.10.0 - plugin_platform_interface: ">=1.0.0 <3.0.0" + plugin_platform_interface: ^2.0.0 test: ^1.16.0 environment: diff --git a/packages/path_provider/path_provider_platform_interface/CHANGELOG.md b/packages/path_provider/path_provider_platform_interface/CHANGELOG.md index 08dc9f69c7df..eec0fe3866b5 100644 --- a/packages/path_provider/path_provider_platform_interface/CHANGELOG.md +++ b/packages/path_provider/path_provider_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +* Update platform_plugin_interface version requirement. + ## 2.0.0 * Migrate to null safety. diff --git a/packages/path_provider/path_provider_platform_interface/pubspec.yaml b/packages/path_provider/path_provider_platform_interface/pubspec.yaml index 3feb4e0a8ebd..eb445c9b8873 100644 --- a/packages/path_provider/path_provider_platform_interface/pubspec.yaml +++ b/packages/path_provider/path_provider_platform_interface/pubspec.yaml @@ -3,14 +3,14 @@ description: A common platform interface for the path_provider plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0 +version: 2.0.1 dependencies: flutter: sdk: flutter meta: ^1.3.0 platform: ^3.0.0 - plugin_platform_interface: ">=1.0.0 <3.0.0" + plugin_platform_interface: ^2.0.0 dev_dependencies: flutter_test: diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index 2d188366dfa5..9741f53ed329 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.0.2 + +* Update platform_plugin_interface version requirement. + ## 6.0.1 * Update result to `True` on iOS when the url was loaded successfully. diff --git a/packages/url_launcher/url_launcher/example/pubspec.yaml b/packages/url_launcher/url_launcher/example/pubspec.yaml index 5f313f3870c5..0bc027de90a8 100644 --- a/packages/url_launcher/url_launcher/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher/example/pubspec.yaml @@ -19,7 +19,7 @@ dev_dependencies: sdk: flutter pedantic: ^1.10.0 mockito: ^5.0.0-nullsafety.7 - plugin_platform_interface: ">=1.0.0 <3.0.0" + plugin_platform_interface: ^2.0.0 flutter: uses-material-design: true diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index 4036748a2d2e..f337c8bed525 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -2,7 +2,7 @@ name: url_launcher description: Flutter plugin for launching a URL. Supports web, phone, SMS, and email schemes. homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher -version: 6.0.1 +version: 6.0.2 flutter: plugin: @@ -40,7 +40,7 @@ dev_dependencies: sdk: flutter test: ^1.16.3 mockito: ^5.0.0-nullsafety.7 - plugin_platform_interface: ">=1.0.0 <3.0.0" + plugin_platform_interface: ^2.0.0 pedantic: ^1.10.0 environment: diff --git a/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md b/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md index d617e514035e..72fa83157377 100644 --- a/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.2 + +* Update platform_plugin_interface version requirement. + ## 2.0.1 * Fix SDK range. diff --git a/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml b/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml index d3ec0aafd126..ee334f0e9a47 100644 --- a/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml +++ b/packages/url_launcher/url_launcher_platform_interface/pubspec.yaml @@ -3,12 +3,12 @@ description: A common platform interface for the url_launcher plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.1 +version: 2.0.2 dependencies: flutter: sdk: flutter - plugin_platform_interface: ">=1.0.0 <3.0.0" + plugin_platform_interface: ^2.0.0 dev_dependencies: flutter_test: diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/CHANGELOG.md b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/CHANGELOG.md index cb770cb2d279..34f8e84cd780 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/CHANGELOG.md +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +* Update platform_plugin_interface version requirement. + ## 2.0.0 * Migrate to null safety. diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/pubspec.yaml b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/pubspec.yaml index 8e2eff392df7..b39f01ac4096 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/pubspec.yaml +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/pubspec.yaml @@ -1,6 +1,6 @@ name: wifi_info_flutter_platform_interface description: A common platform interface for the wifi_info_flutter plugin. -version: 2.0.0 +version: 2.0.1 # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes homepage: https://github.com/flutter/plugins/tree/master/packages/wifi_info_flutter/wifi_info_flutter_platform_interface @@ -10,7 +10,7 @@ environment: flutter: ">=1.17.0" dependencies: - plugin_platform_interface: ">=1.0.0 <3.0.0" + plugin_platform_interface: ^2.0.0 flutter: sdk: flutter From 088bdee478d9a33a1b398f8da2595bf359041cc6 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 1 Mar 2021 12:16:04 -0800 Subject: [PATCH 0231/1565] [in_app_purchase] migrate playing billing library to v3 (#3636) --- packages/in_app_purchase/CHANGELOG.md | 13 ++++ packages/in_app_purchase/android/build.gradle | 4 +- .../inapppurchase/MethodCallHandlerImpl.java | 35 ++++----- .../plugins/inapppurchase/Translator.java | 1 - .../example/android/app/build.gradle | 4 +- .../inapppurchase/MethodCallHandlerTest.java | 42 ++++++----- .../billing_client_wrapper.dart | 37 +++++----- .../purchase_wrapper.dart | 2 + .../sku_details_wrapper.dart | 14 +--- .../sku_details_wrapper.g.dart | 4 +- .../in_app_purchase/app_store_connection.dart | 7 +- .../google_play_connection.dart | 19 +++-- .../in_app_purchase_connection.dart | 10 +-- .../billing_client_wrapper_test.dart | 74 +++++++++++++++---- .../sku_details_wrapper_test.dart | 4 +- .../google_play_connection_test.dart | 5 +- 16 files changed, 160 insertions(+), 115 deletions(-) diff --git a/packages/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/CHANGELOG.md index 0dbc2427ccd6..535295a2f8af 100644 --- a/packages/in_app_purchase/CHANGELOG.md +++ b/packages/in_app_purchase/CHANGELOG.md @@ -1,3 +1,16 @@ +## 0.5.0 + +* Migrate to Google Billing Library 3.0 + * Add `obfuscatedProfileId`, `purchaseToken` in [BillingClientWrapper.launchBillingFlow]. + * **Breaking Change** + * Removed `developerPayload` in [BillingClientWrapper.acknowledgePurchase], [BillingClientWrapper.consumeAsync], [InAppPurchaseConnection.completePurchase], [InAppPurchaseConnection.consumePurchase]. + * Removed `isRewarded` from [SkuDetailsWrapper]. + * [SkuDetailsWrapper.introductoryPriceCycles] now returns `int` instead of `String`. + * Above breaking changes are inline with the breaking changes introduced in [Google Play Billing 3.0 release](https://developer.android.com/google/play/billing/release-notes#3-0). + * Additional information on some the changes: + * [Dropping reward SKU support](https://support.google.com/googleplay/android-developer/answer/9155268?hl=en) + * [Developer payload](https://developer.android.com/google/play/billing/developer-payload) + ## 0.4.1 * Support InApp subscription upgrade/downgrade. diff --git a/packages/in_app_purchase/android/build.gradle b/packages/in_app_purchase/android/build.gradle index 2539f507ed26..8d5840b4daff 100644 --- a/packages/in_app_purchase/android/build.gradle +++ b/packages/in_app_purchase/android/build.gradle @@ -35,9 +35,9 @@ android { dependencies { implementation 'androidx.annotation:annotation:1.0.0' - implementation 'com.android.billingclient:billing:2.0.3' + implementation 'com.android.billingclient:billing:3.0.2' testImplementation 'junit:junit:4.12' - testImplementation 'org.mockito:mockito-core:2.17.0' + testImplementation 'org.mockito:mockito-core:3.6.0' androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' } diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java index 58d077673a03..d90fc6040454 100644 --- a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java +++ b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java @@ -125,7 +125,9 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) { launchBillingFlow( (String) call.argument("sku"), (String) call.argument("accountId"), + (String) call.argument("obfuscatedProfileId"), (String) call.argument("oldSku"), + (String) call.argument("purchaseToken"), call.hasArgument("prorationMode") ? (int) call.argument("prorationMode") : ProrationMode.UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY, @@ -138,16 +140,10 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) { queryPurchaseHistoryAsync((String) call.argument("skuType"), result); break; case InAppPurchasePlugin.MethodNames.CONSUME_PURCHASE_ASYNC: - consumeAsync( - (String) call.argument("purchaseToken"), - (String) call.argument("developerPayload"), - result); + consumeAsync((String) call.argument("purchaseToken"), result); break; case InAppPurchasePlugin.MethodNames.ACKNOWLEDGE_PURCHASE: - acknowledgePurchase( - (String) call.argument("purchaseToken"), - (String) call.argument("developerPayload"), - result); + acknowledgePurchase((String) call.argument("purchaseToken"), result); break; default: result.notImplemented(); @@ -200,7 +196,9 @@ public void onSkuDetailsResponse( private void launchBillingFlow( String sku, @Nullable String accountId, + @Nullable String obfuscatedProfileId, @Nullable String oldSku, + @Nullable String purchaseToken, int prorationMode, MethodChannel.Result result) { if (billingClientError(result)) { @@ -248,10 +246,13 @@ private void launchBillingFlow( BillingFlowParams.Builder paramsBuilder = BillingFlowParams.newBuilder().setSkuDetails(skuDetails); if (accountId != null && !accountId.isEmpty()) { - paramsBuilder.setAccountId(accountId); + paramsBuilder.setObfuscatedAccountId(accountId); + } + if (obfuscatedProfileId != null && !obfuscatedProfileId.isEmpty()) { + paramsBuilder.setObfuscatedProfileId(obfuscatedProfileId); } if (oldSku != null && !oldSku.isEmpty()) { - paramsBuilder.setOldSku(oldSku); + paramsBuilder.setOldSku(oldSku, purchaseToken); } // The proration mode value has to match one of the following declared in // https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.ProrationMode @@ -261,8 +262,7 @@ private void launchBillingFlow( billingClient.launchBillingFlow(activity, paramsBuilder.build()))); } - private void consumeAsync( - String purchaseToken, String developerPayload, final MethodChannel.Result result) { + private void consumeAsync(String purchaseToken, final MethodChannel.Result result) { if (billingClientError(result)) { return; } @@ -277,9 +277,6 @@ public void onConsumeResponse(BillingResult billingResult, String outToken) { ConsumeParams.Builder paramsBuilder = ConsumeParams.newBuilder().setPurchaseToken(purchaseToken); - if (developerPayload != null) { - paramsBuilder.setDeveloperPayload(developerPayload); - } ConsumeParams params = paramsBuilder.build(); billingClient.consumeAsync(params, listener); @@ -348,16 +345,12 @@ public void onBillingServiceDisconnected() { }); } - private void acknowledgePurchase( - String purchaseToken, @Nullable String developerPayload, final MethodChannel.Result result) { + private void acknowledgePurchase(String purchaseToken, final MethodChannel.Result result) { if (billingClientError(result)) { return; } AcknowledgePurchaseParams params = - AcknowledgePurchaseParams.newBuilder() - .setDeveloperPayload(developerPayload) - .setPurchaseToken(purchaseToken) - .build(); + AcknowledgePurchaseParams.newBuilder().setPurchaseToken(purchaseToken).build(); billingClient.acknowledgePurchase( params, new AcknowledgePurchaseResponseListener() { diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java index 80b6f1362255..73180ec5ec05 100644 --- a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java +++ b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java @@ -31,7 +31,6 @@ static HashMap fromSkuDetail(SkuDetails detail) { info.put("priceCurrencyCode", detail.getPriceCurrencyCode()); info.put("sku", detail.getSku()); info.put("type", detail.getType()); - info.put("isRewarded", detail.isRewarded()); info.put("subscriptionPeriod", detail.getSubscriptionPeriod()); info.put("originalPrice", detail.getOriginalPrice()); info.put("originalPriceAmountMicros", detail.getOriginalPriceAmountMicros()); diff --git a/packages/in_app_purchase/example/android/app/build.gradle b/packages/in_app_purchase/example/android/app/build.gradle index 261c7f0fe58e..c95804685219 100644 --- a/packages/in_app_purchase/example/android/app/build.gradle +++ b/packages/in_app_purchase/example/android/app/build.gradle @@ -106,9 +106,9 @@ flutter { } dependencies { - implementation 'com.android.billingclient:billing:1.2' + implementation 'com.android.billingclient:billing:3.0.2' testImplementation 'junit:junit:4.12' - testImplementation 'org.mockito:mockito-core:2.17.0' + testImplementation 'org.mockito:mockito-core:3.6.0' testImplementation 'org.json:json:20180813' androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' diff --git a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java index cc7bc4a9b9b1..eef43346f655 100644 --- a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java +++ b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java @@ -22,6 +22,7 @@ import static java.util.stream.Collectors.toList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.contains; import static org.mockito.ArgumentMatchers.eq; @@ -60,6 +61,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.json.JSONException; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -79,7 +81,7 @@ public class MethodCallHandlerTest { @Before public void setUp() { - MockitoAnnotations.initMocks(this); + MockitoAnnotations.openMocks(this); factory = (@NonNull Context context, @NonNull MethodChannel channel, @@ -261,14 +263,18 @@ public void querySkuDetailsAsync_clientDisconnected() { verify(result, never()).success(any()); } + // Test launchBillingFlow not crash if `accountId` is `null` + // Ideally, we should check if the `accountId` is null in the parameter; however, + // since PBL 3.0, the `accountId` variable is not public. @Test - public void launchBillingFlow_ok_null_AccountId() { + public void launchBillingFlow_null_AccountId_do_not_crash() { // Fetch the sku details first and then prepare the launch billing flow call String skuId = "foo"; queryForSkus(singletonList(skuId)); HashMap arguments = new HashMap<>(); arguments.put("sku", skuId); arguments.put("accountId", null); + arguments.put("obfuscatedProfileId", null); MethodCall launchCall = new MethodCall(LAUNCH_BILLING_FLOW, arguments); // Launch the billing flow @@ -286,7 +292,6 @@ public void launchBillingFlow_ok_null_AccountId() { verify(mockBillingClient).launchBillingFlow(any(), billingFlowParamsCaptor.capture()); BillingFlowParams params = billingFlowParamsCaptor.getValue(); assertEquals(params.getSku(), skuId); - assertNull(params.getAccountId()); // Verify we pass the response code to result verify(result, never()).error(any(), any(), any()); @@ -320,7 +325,6 @@ public void launchBillingFlow_ok_null_OldSku() { verify(mockBillingClient).launchBillingFlow(any(), billingFlowParamsCaptor.capture()); BillingFlowParams params = billingFlowParamsCaptor.getValue(); assertEquals(params.getSku(), skuId); - assertEquals(params.getAccountId(), accountId); assertNull(params.getOldSku()); // Verify we pass the response code to result verify(result, never()).error(any(), any(), any()); @@ -374,7 +378,6 @@ public void launchBillingFlow_ok_oldSku() { verify(mockBillingClient).launchBillingFlow(any(), billingFlowParamsCaptor.capture()); BillingFlowParams params = billingFlowParamsCaptor.getValue(); assertEquals(params.getSku(), skuId); - assertEquals(params.getAccountId(), accountId); assertEquals(params.getOldSku(), oldSkuId); // Verify we pass the response code to result @@ -408,7 +411,6 @@ public void launchBillingFlow_ok_AccountId() { verify(mockBillingClient).launchBillingFlow(any(), billingFlowParamsCaptor.capture()); BillingFlowParams params = billingFlowParamsCaptor.getValue(); assertEquals(params.getSku(), skuId); - assertEquals(params.getAccountId(), accountId); // Verify we pass the response code to result verify(result, never()).error(any(), any(), any()); @@ -420,6 +422,7 @@ public void launchBillingFlow_ok_Proration() { // Fetch the sku details first and query the method call String skuId = "foo"; String oldSkuId = "oldFoo"; + String purchaseToken = "purchaseTokenFoo"; String accountId = "account"; int prorationMode = BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE; queryForSkus(unmodifiableList(asList(skuId, oldSkuId))); @@ -427,6 +430,7 @@ public void launchBillingFlow_ok_Proration() { arguments.put("sku", skuId); arguments.put("accountId", accountId); arguments.put("oldSku", oldSkuId); + arguments.put("purchaseToken", purchaseToken); arguments.put("prorationMode", prorationMode); MethodCall launchCall = new MethodCall(LAUNCH_BILLING_FLOW, arguments); @@ -445,8 +449,8 @@ public void launchBillingFlow_ok_Proration() { verify(mockBillingClient).launchBillingFlow(any(), billingFlowParamsCaptor.capture()); BillingFlowParams params = billingFlowParamsCaptor.getValue(); assertEquals(params.getSku(), skuId); - assertEquals(params.getAccountId(), accountId); assertEquals(params.getOldSku(), oldSkuId); + assertEquals(params.getOldSkuPurchaseToken(), purchaseToken); assertEquals(params.getReplaceSkusProrationMode(), prorationMode); // Verify we pass the response code to result @@ -668,11 +672,7 @@ public void consumeAsync() { methodChannelHandler.onMethodCall(new MethodCall(CONSUME_PURCHASE_ASYNC, arguments), result); - ConsumeParams params = - ConsumeParams.newBuilder() - .setDeveloperPayload("mockPayload") - .setPurchaseToken("mockToken") - .build(); + ConsumeParams params = ConsumeParams.newBuilder().setPurchaseToken("mockToken").build(); // Verify we pass the data to result verify(mockBillingClient).consumeAsync(refEq(params), listenerCaptor.capture()); @@ -703,10 +703,7 @@ public void acknowledgePurchase() { methodChannelHandler.onMethodCall(new MethodCall(ACKNOWLEDGE_PURCHASE, arguments), result); AcknowledgePurchaseParams params = - AcknowledgePurchaseParams.newBuilder() - .setDeveloperPayload("mockPayload") - .setPurchaseToken("mockToken") - .build(); + AcknowledgePurchaseParams.newBuilder().setPurchaseToken("mockToken").build(); // Verify we pass the data to result verify(mockBillingClient).acknowledgePurchase(refEq(params), listenerCaptor.capture()); @@ -774,6 +771,7 @@ private void queryForSkus(List skusList) { verify(mockBillingClient).querySkuDetailsAsync(any(), listenerCaptor.capture()); List skuDetailsResponse = skusList.stream().map(this::buildSkuDetails).collect(toList()); + BillingResult billingResult = BillingResult.newBuilder() .setResponseCode(100) @@ -783,8 +781,16 @@ private void queryForSkus(List skusList) { } private SkuDetails buildSkuDetails(String id) { - SkuDetails details = mock(SkuDetails.class); - when(details.getSku()).thenReturn(id); + String json = + String.format( + "{\"packageName\": \"dummyPackageName\",\"productId\":\"%s\",\"type\":\"inapp\",\"price\":\"$0.99\",\"price_amount_micros\":990000,\"price_currency_code\":\"USD\",\"title\":\"Example title\",\"description\":\"Example description.\",\"original_price\":\"$0.99\",\"original_price_micros\":990000}", + id); + SkuDetails details = null; + try { + details = new SkuDetails(json); + } catch (JSONException e) { + fail("buildSkuDetails failed with JSONException " + e.toString()); + } return details; } diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart index a0ba91556094..f14e8dbec6bd 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart @@ -155,8 +155,13 @@ class BillingClient { /// The [skuDetails] needs to have already been fetched in a [querySkuDetails] /// call. The [accountId] is an optional hashed string associated with the user /// that's unique to your app. It's used by Google to detect unusual behavior. - /// Do not pass in a cleartext [accountId], use your developer ID, or use the - /// user's Google ID for this field. + /// Do not pass in a cleartext [accountId], and do not use this field to store any Personally Identifiable Information (PII) + /// such as emails in cleartext. Attempting to store PII in this field will result in purchases being blocked. + /// Google Play recommends that you use either encryption or a one-way hash to generate an obfuscated identifier to send to Google Play. + /// + /// Specifies an optional [obfuscatedProfileId] that is uniquely associated with the user's profile in your app. + /// Some applications allow users to have multiple profiles within a single account. Use this method to send the user's profile identifier to Google. + /// Setting this field requests the user's obfuscated account id. /// /// Calling this attemps to show the Google Play purchase UI. The user is free /// to complete the transaction there. @@ -169,27 +174,33 @@ class BillingClient { /// [`BillingClient#launchBillingFlow`](https://developer.android.com/reference/com/android/billingclient/api/BillingClient#launchbillingflow). /// It constructs a /// [`BillingFlowParams`](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams) - /// instance by [setting the given - /// skuDetails](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.Builder.html#setskudetails) - /// and [the given - /// accountId](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.Builder.html#setAccountId(java.lang.String)). + /// instance by [setting the given skuDetails](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.Builder.html#setskudetails), + /// [the given accountId](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.Builder#setObfuscatedAccountId(java.lang.String)) + /// and the [obfuscatedProfileId] (https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.Builder#setobfuscatedprofileid). /// /// When this method is called to purchase a subscription, an optional `oldSku` /// can be passed in. This will tell Google Play that rather than purchasing a new subscription, /// the user needs to upgrade/downgrade the existing subscription. - /// The [oldSku](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.Builder#setoldsku) is the SKU id that the user is upgrading or downgrading from. + /// The [oldSku](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.Builder#setoldsku) and [purchaseToken] are the SKU id and purchase token that the user is upgrading or downgrading from. + /// [purchaseToken] must not be `null` if [oldSku] is not `null`. /// The [prorationMode](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.Builder#setreplaceskusprorationmode) is the mode of proration during subscription upgrade/downgrade. /// This value will only be effective if the `oldSku` is also set. Future launchBillingFlow( {required String sku, String? accountId, + String? obfuscatedProfileId, String? oldSku, + String? purchaseToken, ProrationMode? prorationMode}) async { assert(sku != null); + assert((oldSku == null) == (purchaseToken == null), + 'oldSku and purchaseToken must both be set, or both be null.'); final Map arguments = { 'sku': sku, 'accountId': accountId, + 'obfuscatedProfileId': obfuscatedProfileId, 'oldSku': oldSku, + 'purchaseToken': purchaseToken, 'prorationMode': ProrationModeConverter().toJson(prorationMode ?? ProrationMode.unknownSubscriptionUpgradeDowngradePolicy) }; @@ -250,18 +261,14 @@ class BillingClient { /// Consuming can only be done on an item that's owned, and as a result of consumption, the user will no longer own it. /// Consumption is done asynchronously. The method returns a Future containing a [BillingResultWrapper]. /// - /// The `developerPayload` is the developer data associated with the purchase to be consumed, it defaults to null. - /// /// This wraps [`BillingClient#consumeAsync(String, ConsumeResponseListener)`](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html#consumeAsync(java.lang.String,%20com.android.billingclient.api.ConsumeResponseListener)) - Future consumeAsync(String purchaseToken, - {String? developerPayload}) async { + Future consumeAsync(String purchaseToken) async { assert(purchaseToken != null); return BillingResultWrapper.fromJson((await channel .invokeMapMethod( 'BillingClient#consumeAsync(String, ConsumeResponseListener)', { 'purchaseToken': purchaseToken, - 'developerPayload': developerPayload, })) ?? {}); } @@ -282,18 +289,14 @@ class BillingClient { /// Please refer to [acknowledge](https://developer.android.com/google/play/billing/billing_library_overview#acknowledge) for more /// details. /// - /// The `developerPayload` is the developer data associated with the purchase to be consumed, it defaults to null. - /// /// This wraps [`BillingClient#acknowledgePurchase(String, AcknowledgePurchaseResponseListener)`](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html#acknowledgePurchase(com.android.billingclient.api.AcknowledgePurchaseParams,%20com.android.billingclient.api.AcknowledgePurchaseResponseListener)) - Future acknowledgePurchase(String purchaseToken, - {String? developerPayload}) async { + Future acknowledgePurchase(String purchaseToken) async { assert(purchaseToken != null); return BillingResultWrapper.fromJson((await channel.invokeMapMethod( 'BillingClient#(AcknowledgePurchaseParams params, (AcknowledgePurchaseParams, AcknowledgePurchaseResponseListener)', { 'purchaseToken': purchaseToken, - 'developerPayload': developerPayload, })) ?? {}); } diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart index 05472278968a..929b58292a2f 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart @@ -120,6 +120,8 @@ class PurchaseWrapper { /// The payload specified by the developer when the purchase was acknowledged or consumed. /// /// The value is `null` if it wasn't specified when the purchase was acknowledged or consumed. + /// The `developerPayload` is removed from [BillingClientWrapper.acknowledgePurchase], [BillingClientWrapper.consumeAsync], [InAppPurchaseConnection.completePurchase], [InAppPurchaseConnection.consumePurchase] + /// after plugin version `0.5.0`. As a result, this will be `null` for new purchases that happen after updating to `0.5.0`. final String? developerPayload; /// Whether the purchase has been acknowledged. diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart index b3872958e5b9..f93dd60284f8 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart @@ -42,7 +42,6 @@ class SkuDetailsWrapper { required this.subscriptionPeriod, required this.title, required this.type, - required this.isRewarded, required this.originalPrice, required this.originalPriceAmountMicros, }); @@ -71,9 +70,10 @@ class SkuDetailsWrapper { @JsonKey(defaultValue: '') final String introductoryPriceMicros; - /// The number of billing perios that [introductoryPrice] is valid for ("2"). - @JsonKey(defaultValue: '') - final String introductoryPriceCycles; + /// The number of subscription billing periods for which the user will be given the introductory price, such as 3. + /// Returns 0 if the SKU is not a subscription or doesn't have an introductory period. + @JsonKey(defaultValue: 0) + final int introductoryPriceCycles; /// The billing period of [introductoryPrice], in ISO 8601 format. @JsonKey(defaultValue: '') @@ -106,10 +106,6 @@ class SkuDetailsWrapper { /// The [SkuType] of the product. final SkuType type; - /// False if the product is paid. - @JsonKey(defaultValue: false) - final bool isRewarded; - /// The original price that the user purchased this product for. @JsonKey(defaultValue: '') final String originalPrice; @@ -138,7 +134,6 @@ class SkuDetailsWrapper { typedOther.subscriptionPeriod == subscriptionPeriod && typedOther.title == title && typedOther.type == type && - typedOther.isRewarded == isRewarded && typedOther.originalPrice == originalPrice && typedOther.originalPriceAmountMicros == originalPriceAmountMicros; } @@ -158,7 +153,6 @@ class SkuDetailsWrapper { subscriptionPeriod.hashCode, title.hashCode, type.hashCode, - isRewarded.hashCode, originalPrice, originalPriceAmountMicros); } diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.g.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.g.dart index 247dbd54b666..a14affdf9ed3 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.g.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.g.dart @@ -12,7 +12,7 @@ SkuDetailsWrapper _$SkuDetailsWrapperFromJson(Map json) { freeTrialPeriod: json['freeTrialPeriod'] as String? ?? '', introductoryPrice: json['introductoryPrice'] as String? ?? '', introductoryPriceMicros: json['introductoryPriceMicros'] as String? ?? '', - introductoryPriceCycles: json['introductoryPriceCycles'] as String? ?? '', + introductoryPriceCycles: json['introductoryPriceCycles'] as int? ?? 0, introductoryPricePeriod: json['introductoryPricePeriod'] as String? ?? '', price: json['price'] as String? ?? '', priceAmountMicros: json['priceAmountMicros'] as int? ?? 0, @@ -21,7 +21,6 @@ SkuDetailsWrapper _$SkuDetailsWrapperFromJson(Map json) { subscriptionPeriod: json['subscriptionPeriod'] as String? ?? '', title: json['title'] as String? ?? '', type: const SkuTypeConverter().fromJson(json['type'] as String?), - isRewarded: json['isRewarded'] as bool? ?? false, originalPrice: json['originalPrice'] as String? ?? '', originalPriceAmountMicros: json['originalPriceAmountMicros'] as int? ?? 0, ); @@ -42,7 +41,6 @@ Map _$SkuDetailsWrapperToJson(SkuDetailsWrapper instance) => 'subscriptionPeriod': instance.subscriptionPeriod, 'title': instance.title, 'type': const SkuTypeConverter().toJson(instance.type), - 'isRewarded': instance.isRewarded, 'originalPrice': instance.originalPrice, 'originalPriceAmountMicros': instance.originalPriceAmountMicros, }; diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart b/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart index d4601fd809db..79a4a61fb328 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart @@ -84,8 +84,8 @@ class AppStoreConnection implements InAppPurchaseConnection { } @override - Future completePurchase(PurchaseDetails purchase, - {String? developerPayload}) async { + Future completePurchase( + PurchaseDetails purchase) async { if (purchase.skPaymentTransaction == null) { throw ArgumentError( 'completePurchase unsuccessful. The `purchase.skPaymentTransaction` is not valid'); @@ -96,8 +96,7 @@ class AppStoreConnection implements InAppPurchaseConnection { } @override - Future consumePurchase(PurchaseDetails purchase, - {String? developerPayload}) { + Future consumePurchase(PurchaseDetails purchase) { throw UnsupportedError('consume purchase is not available on Android'); } diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart b/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart index 1a47f3ebd095..c45512ed353f 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart @@ -66,6 +66,8 @@ class GooglePlayConnection accountId: purchaseParam.applicationUserName, oldSku: purchaseParam .changeSubscriptionParam?.oldPurchaseDetails.productID, + purchaseToken: purchaseParam.changeSubscriptionParam + ?.oldPurchaseDetails.verificationData.serverVerificationData, prorationMode: purchaseParam.changeSubscriptionParam?.prorationMode); return billingResultWrapper.responseCode == BillingResponse.ok; @@ -81,8 +83,8 @@ class GooglePlayConnection } @override - Future completePurchase(PurchaseDetails purchase, - {String? developerPayload}) async { + Future completePurchase( + PurchaseDetails purchase) async { if (purchase.billingClientPurchase!.isAcknowledged) { return BillingResultWrapper(responseCode: BillingResponse.ok); } @@ -90,21 +92,18 @@ class GooglePlayConnection throw ArgumentError( 'completePurchase unsuccessful. The `purchase.verificationData` is not valid'); } - return await billingClient.acknowledgePurchase( - purchase.verificationData.serverVerificationData, - developerPayload: developerPayload); + return await billingClient + .acknowledgePurchase(purchase.verificationData.serverVerificationData); } @override - Future consumePurchase(PurchaseDetails purchase, - {String? developerPayload}) { + Future consumePurchase(PurchaseDetails purchase) { if (purchase.verificationData == null) { throw ArgumentError( 'consumePurchase unsuccessful. The `purchase.verificationData` is not valid'); } - return billingClient.consumeAsync( - purchase.verificationData.serverVerificationData, - developerPayload: developerPayload); + return billingClient + .consumeAsync(purchase.verificationData.serverVerificationData); } @override diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart b/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart index 81a0e92cc591..aac5eae93e55 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart @@ -204,10 +204,7 @@ abstract class InAppPurchaseConnection { /// /// Warning! Failure to call this method and get a successful response within 3 days of the purchase will result a refund on Android. /// The [consumePurchase] acts as an implicit [completePurchase] on Android. - /// - /// The optional parameter `developerPayload` (defaults to `null`) only works on Android. - Future completePurchase(PurchaseDetails purchase, - {String? developerPayload}); + Future completePurchase(PurchaseDetails purchase); /// (Play only) Mark that the user has consumed a product. /// @@ -215,11 +212,8 @@ abstract class InAppPurchaseConnection { /// delivered. The user won't be able to buy the same product again until the /// purchase of the product is consumed. /// - /// The `developerPayload` (defaults to `null`) can be specified to be associated with this consumption. - /// /// This throws an [UnsupportedError] on iOS. - Future consumePurchase(PurchaseDetails purchase, - {String? developerPayload}); + Future consumePurchase(PurchaseDetails purchase); /// Query all previous purchases. /// diff --git a/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart b/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart index 3aa62ddd96a1..7ba560257b39 100644 --- a/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart +++ b/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart @@ -196,15 +196,53 @@ void main() { ); final SkuDetailsWrapper skuDetails = dummySkuDetails; final String accountId = "hashedAccountId"; + final String profileId = "hashedProfileId"; expect( await billingClient.launchBillingFlow( - sku: skuDetails.sku, accountId: accountId), + sku: skuDetails.sku, + accountId: accountId, + obfuscatedProfileId: profileId), equals(expectedBillingResult)); Map arguments = stubPlatform.previousCallMatching(launchMethodName).arguments; expect(arguments['sku'], equals(skuDetails.sku)); expect(arguments['accountId'], equals(accountId)); + expect(arguments['obfuscatedProfileId'], equals(profileId)); + }); + + test( + 'Change subscription throws assertion error `oldSku` and `purchaseToken` has different nullability', + () async { + const String debugMessage = 'dummy message'; + final BillingResponse responseCode = BillingResponse.ok; + final BillingResultWrapper expectedBillingResult = BillingResultWrapper( + responseCode: responseCode, debugMessage: debugMessage); + stubPlatform.addResponse( + name: launchMethodName, + value: buildBillingResultMap(expectedBillingResult), + ); + final SkuDetailsWrapper skuDetails = dummySkuDetails; + final String accountId = 'hashedAccountId'; + final String profileId = 'hashedProfileId'; + + expect( + billingClient.launchBillingFlow( + sku: skuDetails.sku, + accountId: accountId, + obfuscatedProfileId: profileId, + oldSku: dummyOldPurchase.sku, + purchaseToken: null), + throwsAssertionError); + + expect( + billingClient.launchBillingFlow( + sku: skuDetails.sku, + accountId: accountId, + obfuscatedProfileId: profileId, + oldSku: null, + purchaseToken: dummyOldPurchase.purchaseToken), + throwsAssertionError); }); test( @@ -219,19 +257,25 @@ void main() { value: buildBillingResultMap(expectedBillingResult), ); final SkuDetailsWrapper skuDetails = dummySkuDetails; - final String accountId = "hashedAccountId"; + final String accountId = 'hashedAccountId'; + final String profileId = 'hashedProfileId'; expect( await billingClient.launchBillingFlow( sku: skuDetails.sku, accountId: accountId, - oldSku: dummyOldPurchase.sku), + obfuscatedProfileId: profileId, + oldSku: dummyOldPurchase.sku, + purchaseToken: dummyOldPurchase.purchaseToken), equals(expectedBillingResult)); Map arguments = stubPlatform.previousCallMatching(launchMethodName).arguments; expect(arguments['sku'], equals(skuDetails.sku)); expect(arguments['accountId'], equals(accountId)); expect(arguments['oldSku'], equals(dummyOldPurchase.sku)); + expect( + arguments['purchaseToken'], equals(dummyOldPurchase.purchaseToken)); + expect(arguments['obfuscatedProfileId'], equals(profileId)); }); test( @@ -246,21 +290,27 @@ void main() { value: buildBillingResultMap(expectedBillingResult), ); final SkuDetailsWrapper skuDetails = dummySkuDetails; - final String accountId = "hashedAccountId"; + final String accountId = 'hashedAccountId'; + final String profileId = 'hashedProfileId'; final prorationMode = ProrationMode.immediateAndChargeProratedPrice; expect( await billingClient.launchBillingFlow( sku: skuDetails.sku, accountId: accountId, + obfuscatedProfileId: profileId, oldSku: dummyOldPurchase.sku, - prorationMode: prorationMode), + prorationMode: prorationMode, + purchaseToken: dummyOldPurchase.purchaseToken), equals(expectedBillingResult)); Map arguments = stubPlatform.previousCallMatching(launchMethodName).arguments; expect(arguments['sku'], equals(skuDetails.sku)); expect(arguments['accountId'], equals(accountId)); expect(arguments['oldSku'], equals(dummyOldPurchase.sku)); + expect(arguments['obfuscatedProfileId'], equals(profileId)); + expect( + arguments['purchaseToken'], equals(dummyOldPurchase.purchaseToken)); expect(arguments['prorationMode'], ProrationModeConverter().toJson(prorationMode)); }); @@ -440,8 +490,8 @@ void main() { name: consumeMethodName, value: buildBillingResultMap(expectedBillingResult)); - final BillingResultWrapper billingResult = await billingClient - .consumeAsync('dummy token', developerPayload: 'dummy payload'); + final BillingResultWrapper billingResult = + await billingClient.consumeAsync('dummy token'); expect(billingResult, equals(expectedBillingResult)); }); @@ -451,8 +501,8 @@ void main() { name: consumeMethodName, value: null, ); - final BillingResultWrapper billingResult = await billingClient - .consumeAsync('dummy token', developerPayload: 'dummy payload'); + final BillingResultWrapper billingResult = + await billingClient.consumeAsync('dummy token'); expect( billingResult, @@ -475,8 +525,7 @@ void main() { value: buildBillingResultMap(expectedBillingResult)); final BillingResultWrapper billingResult = - await billingClient.acknowledgePurchase('dummy token', - developerPayload: 'dummy payload'); + await billingClient.acknowledgePurchase('dummy token'); expect(billingResult, equals(expectedBillingResult)); }); @@ -486,8 +535,7 @@ void main() { value: null, ); final BillingResultWrapper billingResult = - await billingClient.acknowledgePurchase('dummy token', - developerPayload: 'dummy payload'); + await billingClient.acknowledgePurchase('dummy token'); expect( billingResult, diff --git a/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart b/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart index 13715eeb9fc0..7a7b7fb86364 100644 --- a/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart +++ b/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart @@ -12,7 +12,7 @@ final SkuDetailsWrapper dummySkuDetails = SkuDetailsWrapper( freeTrialPeriod: 'freeTrialPeriod', introductoryPrice: 'introductoryPrice', introductoryPriceMicros: 'introductoryPriceMicros', - introductoryPriceCycles: 'introductoryPriceCycles', + introductoryPriceCycles: 1, introductoryPricePeriod: 'introductoryPricePeriod', price: 'price', priceAmountMicros: 1000, @@ -21,7 +21,6 @@ final SkuDetailsWrapper dummySkuDetails = SkuDetailsWrapper( subscriptionPeriod: 'subscriptionPeriod', title: 'title', type: SkuType.inapp, - isRewarded: true, originalPrice: 'originalPrice', originalPriceAmountMicros: 1000, ); @@ -144,7 +143,6 @@ Map buildSkuMap(SkuDetailsWrapper original) { 'subscriptionPeriod': original.subscriptionPeriod, 'title': original.title, 'type': original.type.toString().substring(8), - 'isRewarded': original.isRewarded, 'originalPrice': original.originalPrice, 'originalPriceAmountMicros': original.originalPriceAmountMicros, }; diff --git a/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart b/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart index 79c2ee436c5c..5a265b8de907 100644 --- a/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart +++ b/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart @@ -632,9 +632,8 @@ void main() { purchaseDetails.status = PurchaseStatus.purchased; if (purchaseDetails.pendingCompletePurchase) { final BillingResultWrapper billingResultWrapper = - await GooglePlayConnection.instance.completePurchase( - purchaseDetails, - developerPayload: 'dummy payload'); + await GooglePlayConnection.instance + .completePurchase(purchaseDetails); expect(billingResultWrapper, equals(expectedBillingResult)); completer.complete(billingResultWrapper); } From 96ea724a099d896f3643f98138864877210c2e42 Mon Sep 17 00:00:00 2001 From: Emmanuel Garcia Date: Mon, 1 Mar 2021 18:15:51 -0800 Subject: [PATCH 0232/1565] Move plugin tool tests over (#3606) --- .cirrus.yml | 20 +- script/tool/pubspec.yaml | 5 + script/tool/test/analyze_command_test.dart | 93 ++++ .../test/build_examples_command_test.dart | 470 ++++++++++++++++ script/tool/test/common_test.dart | 100 ++++ .../test/drive_examples_command_test.dart | 505 ++++++++++++++++++ script/tool/test/firebase_test_lab_test.dart | 256 +++++++++ .../tool/test/lint_podspecs_command_test.dart | 202 +++++++ script/tool/test/list_command_test.dart | 198 +++++++ script/tool/test/mocks.dart | 33 ++ .../test/publish_plugin_command_test.dart | 378 +++++++++++++ script/tool/test/test_command_test.dart | 154 ++++++ script/tool/test/util.dart | 291 ++++++++++ script/tool/test/version_check_test.dart | 319 +++++++++++ script/tool/test/xctest_command_test.dart | 358 +++++++++++++ 15 files changed, 3367 insertions(+), 15 deletions(-) create mode 100644 script/tool/test/analyze_command_test.dart create mode 100644 script/tool/test/build_examples_command_test.dart create mode 100644 script/tool/test/common_test.dart create mode 100644 script/tool/test/drive_examples_command_test.dart create mode 100644 script/tool/test/firebase_test_lab_test.dart create mode 100644 script/tool/test/lint_podspecs_command_test.dart create mode 100644 script/tool/test/list_command_test.dart create mode 100644 script/tool/test/mocks.dart create mode 100644 script/tool/test/publish_plugin_command_test.dart create mode 100644 script/tool/test/test_command_test.dart create mode 100644 script/tool/test/util.dart create mode 100644 script/tool/test/version_check_test.dart create mode 100644 script/tool/test/xctest_command_test.dart diff --git a/.cirrus.yml b/.cirrus.yml index 5a25b773ea33..118802b74810 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -16,10 +16,12 @@ task: - flutter channel master - flutter upgrade - git fetch origin master - submodules_script: - - git submodule init - - git submodule update matrix: + - name: plugin_tools_tests + script: + - cd script/tool + - pub get + - CIRRUS_BUILD_ID=null pub run test - name: publishable script: - flutter channel master @@ -132,9 +134,6 @@ task: - flutter channel master - flutter upgrade - git fetch origin master - submodules_script: - - git submodule init - - git submodule update matrix: - name: build-linux+drive-examples install_script: @@ -161,9 +160,6 @@ task: - flutter channel master - flutter upgrade - git fetch origin master - submodules_script: - - git submodule init - - git submodule update create_simulator_script: - xcrun simctl list - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-11 com.apple.CoreSimulator.SimRuntime.iOS-14-3 | xargs xcrun simctl boot @@ -222,9 +218,6 @@ task: - flutter channel master - flutter upgrade - git fetch origin master - submodules_script: - - git submodule init - - git submodule update create_simulator_script: - xcrun simctl list - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-X com.apple.CoreSimulator.SimRuntime.iOS-13-3 | xargs xcrun simctl boot @@ -254,9 +247,6 @@ task: - flutter channel master - flutter upgrade - git fetch origin master - submodules_script: - - git submodule init - - git submodule update matrix: - name: build_all_plugins_app script: diff --git a/script/tool/pubspec.yaml b/script/tool/pubspec.yaml index d9fce4ad26a7..e47123959005 100644 --- a/script/tool/pubspec.yaml +++ b/script/tool/pubspec.yaml @@ -21,5 +21,10 @@ dependencies: http_multi_server: ^2.2.0 collection: 1.14.13 +dev_dependencies: + matcher: ^0.12.6 + mockito: ^4.1.1 + pedantic: 1.8.0 + environment: sdk: ">=2.3.0 <3.0.0" diff --git a/script/tool/test/analyze_command_test.dart b/script/tool/test/analyze_command_test.dart new file mode 100644 index 000000000000..9e7a42bbb680 --- /dev/null +++ b/script/tool/test/analyze_command_test.dart @@ -0,0 +1,93 @@ +import 'package:args/command_runner.dart'; +import 'package:file/file.dart'; +import 'package:flutter_plugin_tools/src/analyze_command.dart'; +import 'package:flutter_plugin_tools/src/common.dart'; +import 'package:test/test.dart'; + +import 'mocks.dart'; +import 'util.dart'; + +void main() { + RecordingProcessRunner processRunner; + CommandRunner runner; + + setUp(() { + initializeFakePackages(); + processRunner = RecordingProcessRunner(); + final AnalyzeCommand analyzeCommand = AnalyzeCommand( + mockPackagesDir, mockFileSystem, + processRunner: processRunner); + + runner = CommandRunner('analyze_command', 'Test for analyze_command'); + runner.addCommand(analyzeCommand); + }); + + tearDown(() { + mockPackagesDir.deleteSync(recursive: true); + }); + + test('analyzes all packages', () async { + final Directory plugin1Dir = await createFakePlugin('a'); + final Directory plugin2Dir = await createFakePlugin('b'); + + final MockProcess mockProcess = MockProcess(); + mockProcess.exitCodeCompleter.complete(0); + processRunner.processToReturn = mockProcess; + await runner.run(['analyze']); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall('pub', ['global', 'activate', 'tuneup'], + mockPackagesDir.path), + ProcessCall('flutter', ['packages', 'get'], plugin1Dir.path), + ProcessCall('flutter', ['packages', 'get'], plugin2Dir.path), + ProcessCall('pub', ['global', 'run', 'tuneup', 'check'], + plugin1Dir.path), + ProcessCall('pub', ['global', 'run', 'tuneup', 'check'], + plugin2Dir.path), + ])); + }); + + group('verifies analysis settings', () { + test('fails analysis_options.yaml', () async { + await createFakePlugin('foo', withExtraFiles: >[ + ['analysis_options.yaml'] + ]); + + await expectLater(() => runner.run(['analyze']), + throwsA(const TypeMatcher())); + }); + + test('fails .analysis_options', () async { + await createFakePlugin('foo', withExtraFiles: >[ + ['.analysis_options'] + ]); + + await expectLater(() => runner.run(['analyze']), + throwsA(const TypeMatcher())); + }); + + test('takes an allow list', () async { + final Directory pluginDir = + await createFakePlugin('foo', withExtraFiles: >[ + ['analysis_options.yaml'] + ]); + + final MockProcess mockProcess = MockProcess(); + mockProcess.exitCodeCompleter.complete(0); + processRunner.processToReturn = mockProcess; + await runner.run(['analyze', '--custom-analysis', 'foo']); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall('pub', ['global', 'activate', 'tuneup'], + mockPackagesDir.path), + ProcessCall('flutter', ['packages', 'get'], pluginDir.path), + ProcessCall('pub', ['global', 'run', 'tuneup', 'check'], + pluginDir.path), + ])); + }); + }); +} diff --git a/script/tool/test/build_examples_command_test.dart b/script/tool/test/build_examples_command_test.dart new file mode 100644 index 000000000000..eaf5049dcc02 --- /dev/null +++ b/script/tool/test/build_examples_command_test.dart @@ -0,0 +1,470 @@ +import 'package:args/command_runner.dart'; +import 'package:file/file.dart'; +import 'package:flutter_plugin_tools/src/build_examples_command.dart'; +import 'package:path/path.dart' as p; +import 'package:platform/platform.dart'; +import 'package:test/test.dart'; + +import 'util.dart'; + +void main() { + group('test build_example_command', () { + CommandRunner runner; + RecordingProcessRunner processRunner; + final String flutterCommand = + LocalPlatform().isWindows ? 'flutter.bat' : 'flutter'; + + setUp(() { + initializeFakePackages(); + processRunner = RecordingProcessRunner(); + final BuildExamplesCommand command = BuildExamplesCommand( + mockPackagesDir, mockFileSystem, + processRunner: processRunner); + + runner = CommandRunner( + 'build_examples_command', 'Test for build_example_command'); + runner.addCommand(command); + cleanupPackages(); + }); + + test('building for iOS when plugin is not set up for iOS results in no-op', + () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test'], + ], + isLinuxPlugin: false); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint( + runner, ['build-examples', '--ipa', '--no-macos']); + final String packageName = + p.relative(pluginExampleDirectory.path, from: mockPackagesDir.path); + + expect( + output, + orderedEquals([ + '\nBUILDING IPA for $packageName', + 'iOS is not supported by this plugin', + '\n\n', + 'All builds successful!', + ]), + ); + + print(processRunner.recordedCalls); + // Output should be empty since running build-examples --macos with no macos + // implementation is a no-op. + expect(processRunner.recordedCalls, orderedEquals([])); + cleanupPackages(); + }); + + test('building for ios', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test'], + ], + isIosPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint(runner, [ + 'build-examples', + '--ipa', + '--no-macos', + '--enable-experiment=exp1' + ]); + final String packageName = + p.relative(pluginExampleDirectory.path, from: mockPackagesDir.path); + + expect( + output, + orderedEquals([ + '\nBUILDING IPA for $packageName', + '\n\n', + 'All builds successful!', + ]), + ); + + print(processRunner.recordedCalls); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + flutterCommand, + [ + 'build', + 'ios', + '--no-codesign', + '--enable-experiment=exp1' + ], + pluginExampleDirectory.path), + ])); + cleanupPackages(); + }); + + test( + 'building for Linux when plugin is not set up for Linux results in no-op', + () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test'], + ], + isLinuxPlugin: false); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint( + runner, ['build-examples', '--no-ipa', '--linux']); + final String packageName = + p.relative(pluginExampleDirectory.path, from: mockPackagesDir.path); + + expect( + output, + orderedEquals([ + '\nBUILDING Linux for $packageName', + 'Linux is not supported by this plugin', + '\n\n', + 'All builds successful!', + ]), + ); + + print(processRunner.recordedCalls); + // Output should be empty since running build-examples --linux with no + // Linux implementation is a no-op. + expect(processRunner.recordedCalls, orderedEquals([])); + cleanupPackages(); + }); + + test('building for Linux', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test'], + ], + isLinuxPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint( + runner, ['build-examples', '--no-ipa', '--linux']); + final String packageName = + p.relative(pluginExampleDirectory.path, from: mockPackagesDir.path); + + expect( + output, + orderedEquals([ + '\nBUILDING Linux for $packageName', + '\n\n', + 'All builds successful!', + ]), + ); + + print(processRunner.recordedCalls); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall(flutterCommand, ['build', 'linux'], + pluginExampleDirectory.path), + ])); + cleanupPackages(); + }); + + test('building for macos with no implementation results in no-op', + () async { + createFakePlugin('plugin', withExtraFiles: >[ + ['example', 'test'], + ]); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint( + runner, ['build-examples', '--no-ipa', '--macos']); + final String packageName = + p.relative(pluginExampleDirectory.path, from: mockPackagesDir.path); + + expect( + output, + orderedEquals([ + '\nBUILDING macOS for $packageName', + '\macOS is not supported by this plugin', + '\n\n', + 'All builds successful!', + ]), + ); + + print(processRunner.recordedCalls); + // Output should be empty since running build-examples --macos with no macos + // implementation is a no-op. + expect(processRunner.recordedCalls, orderedEquals([])); + cleanupPackages(); + }); + test('building for macos', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test'], + ['example', 'macos', 'macos.swift'], + ], + isMacOsPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint( + runner, ['build-examples', '--no-ipa', '--macos']); + final String packageName = + p.relative(pluginExampleDirectory.path, from: mockPackagesDir.path); + + expect( + output, + orderedEquals([ + '\nBUILDING macOS for $packageName', + '\n\n', + 'All builds successful!', + ]), + ); + + print(processRunner.recordedCalls); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall(flutterCommand, ['pub', 'get'], + pluginExampleDirectory.path), + ProcessCall(flutterCommand, ['build', 'macos'], + pluginExampleDirectory.path), + ])); + cleanupPackages(); + }); + + test( + 'building for Windows when plugin is not set up for Windows results in no-op', + () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test'], + ], + isWindowsPlugin: false); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint( + runner, ['build-examples', '--no-ipa', '--windows']); + final String packageName = + p.relative(pluginExampleDirectory.path, from: mockPackagesDir.path); + + expect( + output, + orderedEquals([ + '\nBUILDING Windows for $packageName', + 'Windows is not supported by this plugin', + '\n\n', + 'All builds successful!', + ]), + ); + + print(processRunner.recordedCalls); + // Output should be empty since running build-examples --macos with no macos + // implementation is a no-op. + expect(processRunner.recordedCalls, orderedEquals([])); + cleanupPackages(); + }); + + test('building for windows', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test'], + ], + isWindowsPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint( + runner, ['build-examples', '--no-ipa', '--windows']); + final String packageName = + p.relative(pluginExampleDirectory.path, from: mockPackagesDir.path); + + expect( + output, + orderedEquals([ + '\nBUILDING Windows for $packageName', + '\n\n', + 'All builds successful!', + ]), + ); + + print(processRunner.recordedCalls); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall(flutterCommand, ['build', 'windows'], + pluginExampleDirectory.path), + ])); + cleanupPackages(); + }); + + test( + 'building for Android when plugin is not set up for Android results in no-op', + () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test'], + ], + isLinuxPlugin: false); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint( + runner, ['build-examples', '--apk', '--no-ipa']); + final String packageName = + p.relative(pluginExampleDirectory.path, from: mockPackagesDir.path); + + expect( + output, + orderedEquals([ + '\nBUILDING APK for $packageName', + 'Android is not supported by this plugin', + '\n\n', + 'All builds successful!', + ]), + ); + + print(processRunner.recordedCalls); + // Output should be empty since running build-examples --macos with no macos + // implementation is a no-op. + expect(processRunner.recordedCalls, orderedEquals([])); + cleanupPackages(); + }); + + test('building for android', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test'], + ], + isAndroidPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint(runner, [ + 'build-examples', + '--apk', + '--no-ipa', + '--no-macos', + ]); + final String packageName = + p.relative(pluginExampleDirectory.path, from: mockPackagesDir.path); + + expect( + output, + orderedEquals([ + '\nBUILDING APK for $packageName', + '\n\n', + 'All builds successful!', + ]), + ); + + print(processRunner.recordedCalls); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall(flutterCommand, ['build', 'apk'], + pluginExampleDirectory.path), + ])); + cleanupPackages(); + }); + + test('enable-experiment flag for Android', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test'], + ], + isAndroidPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + await runCapturingPrint(runner, [ + 'build-examples', + '--apk', + '--no-ipa', + '--no-macos', + '--enable-experiment=exp1' + ]); + + print(processRunner.recordedCalls); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + flutterCommand, + ['build', 'apk', '--enable-experiment=exp1'], + pluginExampleDirectory.path), + ])); + cleanupPackages(); + }); + + test('enable-experiment flag for ios', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test'], + ], + isIosPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + await runCapturingPrint(runner, [ + 'build-examples', + '--ipa', + '--no-macos', + '--enable-experiment=exp1' + ]); + print(processRunner.recordedCalls); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + flutterCommand, + [ + 'build', + 'ios', + '--no-codesign', + '--enable-experiment=exp1' + ], + pluginExampleDirectory.path), + ])); + cleanupPackages(); + }); + }); +} diff --git a/script/tool/test/common_test.dart b/script/tool/test/common_test.dart new file mode 100644 index 000000000000..b3504c2358d9 --- /dev/null +++ b/script/tool/test/common_test.dart @@ -0,0 +1,100 @@ +import 'package:args/command_runner.dart'; +import 'package:file/file.dart'; +import 'package:flutter_plugin_tools/src/common.dart'; +import 'package:test/test.dart'; + +import 'util.dart'; + +void main() { + RecordingProcessRunner processRunner; + CommandRunner runner; + List plugins; + + setUp(() { + initializeFakePackages(); + processRunner = RecordingProcessRunner(); + plugins = []; + final SamplePluginCommand samplePluginCommand = SamplePluginCommand( + plugins, + mockPackagesDir, + mockFileSystem, + processRunner: processRunner, + ); + runner = + CommandRunner('common_command', 'Test for common functionality'); + runner.addCommand(samplePluginCommand); + }); + + tearDown(() { + mockPackagesDir.deleteSync(recursive: true); + }); + + test('all plugins from file system', () async { + final Directory plugin1 = createFakePlugin('plugin1'); + final Directory plugin2 = createFakePlugin('plugin2'); + await runner.run(['sample']); + expect(plugins, unorderedEquals([plugin1.path, plugin2.path])); + }); + + test('exclude plugins when plugins flag is specified', () async { + createFakePlugin('plugin1'); + final Directory plugin2 = createFakePlugin('plugin2'); + await runner.run( + ['sample', '--plugins=plugin1,plugin2', '--exclude=plugin1']); + expect(plugins, unorderedEquals([plugin2.path])); + }); + + test('exclude plugins when plugins flag isn\'t specified', () async { + createFakePlugin('plugin1'); + createFakePlugin('plugin2'); + await runner.run(['sample', '--exclude=plugin1,plugin2']); + expect(plugins, unorderedEquals([])); + }); + + test('exclude federated plugins when plugins flag is specified', () async { + createFakePlugin('plugin1', parentDirectoryName: 'federated'); + final Directory plugin2 = createFakePlugin('plugin2'); + await runner.run([ + 'sample', + '--plugins=federated/plugin1,plugin2', + '--exclude=federated/plugin1' + ]); + expect(plugins, unorderedEquals([plugin2.path])); + }); + + test('exclude entire federated plugins when plugins flag is specified', + () async { + createFakePlugin('plugin1', parentDirectoryName: 'federated'); + final Directory plugin2 = createFakePlugin('plugin2'); + await runner.run([ + 'sample', + '--plugins=federated/plugin1,plugin2', + '--exclude=federated' + ]); + expect(plugins, unorderedEquals([plugin2.path])); + }); +} + +class SamplePluginCommand extends PluginCommand { + SamplePluginCommand( + this.plugins_, + Directory packagesDir, + FileSystem fileSystem, { + ProcessRunner processRunner = const ProcessRunner(), + }) : super(packagesDir, fileSystem, processRunner: processRunner); + + List plugins_; + + @override + final String name = 'sample'; + + @override + final String description = 'sample command'; + + @override + Future run() async { + await for (Directory package in getPlugins()) { + this.plugins_.add(package.path); + } + } +} diff --git a/script/tool/test/drive_examples_command_test.dart b/script/tool/test/drive_examples_command_test.dart new file mode 100644 index 000000000000..f4bdd95c1664 --- /dev/null +++ b/script/tool/test/drive_examples_command_test.dart @@ -0,0 +1,505 @@ +import 'package:args/command_runner.dart'; +import 'package:file/file.dart'; +import 'package:flutter_plugin_tools/src/common.dart'; +import 'package:flutter_plugin_tools/src/drive_examples_command.dart'; +import 'package:path/path.dart' as p; +import 'package:platform/platform.dart'; +import 'package:test/test.dart'; + +import 'util.dart'; + +void main() { + group('test drive_example_command', () { + CommandRunner runner; + RecordingProcessRunner processRunner; + final String flutterCommand = + LocalPlatform().isWindows ? 'flutter.bat' : 'flutter'; + setUp(() { + initializeFakePackages(); + processRunner = RecordingProcessRunner(); + final DriveExamplesCommand command = DriveExamplesCommand( + mockPackagesDir, mockFileSystem, + processRunner: processRunner); + + runner = CommandRunner( + 'drive_examples_command', 'Test for drive_example_command'); + runner.addCommand(command); + }); + + tearDown(() { + cleanupPackages(); + }); + + test('driving under folder "test"', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test_driver', 'plugin_test.dart'], + ['example', 'test', 'plugin.dart'], + ], + isIosPlugin: true, + isAndroidPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint(runner, [ + 'drive-examples', + ]); + + expect( + output, + orderedEquals([ + '\n\n', + 'All driver tests successful!', + ]), + ); + + String deviceTestPath = p.join('test', 'plugin.dart'); + String driverTestPath = p.join('test_driver', 'plugin_test.dart'); + print(processRunner.recordedCalls); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + flutterCommand, + [ + 'drive', + '--driver', + driverTestPath, + '--target', + deviceTestPath + ], + pluginExampleDirectory.path), + ])); + }); + + test('driving under folder "test_driver"', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test_driver', 'plugin_test.dart'], + ['example', 'test_driver', 'plugin.dart'], + ], + isAndroidPlugin: true, + isIosPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint(runner, [ + 'drive-examples', + ]); + + expect( + output, + orderedEquals([ + '\n\n', + 'All driver tests successful!', + ]), + ); + + String deviceTestPath = p.join('test_driver', 'plugin.dart'); + String driverTestPath = p.join('test_driver', 'plugin_test.dart'); + print(processRunner.recordedCalls); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + flutterCommand, + [ + 'drive', + '--driver', + driverTestPath, + '--target', + deviceTestPath + ], + pluginExampleDirectory.path), + ])); + }); + + test('driving under folder "test_driver" when test files are missing"', + () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test_driver', 'plugin_test.dart'], + ], + isAndroidPlugin: true, + isIosPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + await expectLater( + () => runCapturingPrint(runner, ['drive-examples']), + throwsA(const TypeMatcher())); + }); + + test( + 'driving under folder "test_driver" when targets are under "integration_test"', + () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test_driver', 'integration_test.dart'], + ['example', 'integration_test', 'bar_test.dart'], + ['example', 'integration_test', 'foo_test.dart'], + ['example', 'integration_test', 'ignore_me.dart'], + ], + isAndroidPlugin: true, + isIosPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint(runner, [ + 'drive-examples', + ]); + + expect( + output, + orderedEquals([ + '\n\n', + 'All driver tests successful!', + ]), + ); + + String driverTestPath = p.join('test_driver', 'integration_test.dart'); + print(processRunner.recordedCalls); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + flutterCommand, + [ + 'drive', + '--driver', + driverTestPath, + '--target', + p.join('integration_test', 'bar_test.dart'), + ], + pluginExampleDirectory.path), + ProcessCall( + flutterCommand, + [ + 'drive', + '--driver', + driverTestPath, + '--target', + p.join('integration_test', 'foo_test.dart'), + ], + pluginExampleDirectory.path), + ])); + }); + + test('driving when plugin does not support Linux is a no-op', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test_driver', 'plugin_test.dart'], + ['example', 'test_driver', 'plugin.dart'], + ], + isMacOsPlugin: false); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint(runner, [ + 'drive-examples', + '--linux', + ]); + + expect( + output, + orderedEquals([ + '\n\n', + 'All driver tests successful!', + ]), + ); + + print(processRunner.recordedCalls); + // Output should be empty since running drive-examples --linux on a non-Linux + // plugin is a no-op. + expect(processRunner.recordedCalls, []); + }); + + test('driving on a Linux plugin', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test_driver', 'plugin_test.dart'], + ['example', 'test_driver', 'plugin.dart'], + ], + isLinuxPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint(runner, [ + 'drive-examples', + '--linux', + ]); + + expect( + output, + orderedEquals([ + '\n\n', + 'All driver tests successful!', + ]), + ); + + String deviceTestPath = p.join('test_driver', 'plugin.dart'); + String driverTestPath = p.join('test_driver', 'plugin_test.dart'); + print(processRunner.recordedCalls); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + flutterCommand, + [ + 'drive', + '-d', + 'linux', + '--driver', + driverTestPath, + '--target', + deviceTestPath + ], + pluginExampleDirectory.path), + ])); + }); + + test('driving when plugin does not suppport macOS is a no-op', () async { + createFakePlugin('plugin', withExtraFiles: >[ + ['example', 'test_driver', 'plugin_test.dart'], + ['example', 'test_driver', 'plugin.dart'], + ]); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint(runner, [ + 'drive-examples', + '--macos', + ]); + + expect( + output, + orderedEquals([ + '\n\n', + 'All driver tests successful!', + ]), + ); + + print(processRunner.recordedCalls); + // Output should be empty since running drive-examples --macos with no macos + // implementation is a no-op. + expect(processRunner.recordedCalls, []); + }); + test('driving on a macOS plugin', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test_driver', 'plugin_test.dart'], + ['example', 'test_driver', 'plugin.dart'], + ['example', 'macos', 'macos.swift'], + ], + isMacOsPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint(runner, [ + 'drive-examples', + '--macos', + ]); + + expect( + output, + orderedEquals([ + '\n\n', + 'All driver tests successful!', + ]), + ); + + String deviceTestPath = p.join('test_driver', 'plugin.dart'); + String driverTestPath = p.join('test_driver', 'plugin_test.dart'); + print(processRunner.recordedCalls); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + flutterCommand, + [ + 'drive', + '-d', + 'macos', + '--driver', + driverTestPath, + '--target', + deviceTestPath + ], + pluginExampleDirectory.path), + ])); + }); + + test('driving when plugin does not suppport windows is a no-op', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test_driver', 'plugin_test.dart'], + ['example', 'test_driver', 'plugin.dart'], + ], + isMacOsPlugin: false); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint(runner, [ + 'drive-examples', + '--windows', + ]); + + expect( + output, + orderedEquals([ + '\n\n', + 'All driver tests successful!', + ]), + ); + + print(processRunner.recordedCalls); + // Output should be empty since running drive-examples --windows on a non-windows + // plugin is a no-op. + expect(processRunner.recordedCalls, []); + }); + + test('driving on a Windows plugin', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test_driver', 'plugin_test.dart'], + ['example', 'test_driver', 'plugin.dart'], + ], + isWindowsPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint(runner, [ + 'drive-examples', + '--windows', + ]); + + expect( + output, + orderedEquals([ + '\n\n', + 'All driver tests successful!', + ]), + ); + + String deviceTestPath = p.join('test_driver', 'plugin.dart'); + String driverTestPath = p.join('test_driver', 'plugin_test.dart'); + print(processRunner.recordedCalls); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + flutterCommand, + [ + 'drive', + '-d', + 'windows', + '--driver', + driverTestPath, + '--target', + deviceTestPath + ], + pluginExampleDirectory.path), + ])); + }); + + test('driving when plugin does not support mobile is no-op', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test_driver', 'plugin_test.dart'], + ['example', 'test_driver', 'plugin.dart'], + ], + isMacOsPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint(runner, [ + 'drive-examples', + ]); + + expect( + output, + orderedEquals([ + '\n\n', + 'All driver tests successful!', + ]), + ); + + print(processRunner.recordedCalls); + // Output should be empty since running drive-examples --macos with no macos + // implementation is a no-op. + expect(processRunner.recordedCalls, []); + }); + + test('enable-experiment flag', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test_driver', 'plugin_test.dart'], + ['example', 'test', 'plugin.dart'], + ], + isIosPlugin: true, + isAndroidPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + await runCapturingPrint(runner, [ + 'drive-examples', + '--enable-experiment=exp1', + ]); + + String deviceTestPath = p.join('test', 'plugin.dart'); + String driverTestPath = p.join('test_driver', 'plugin_test.dart'); + print(processRunner.recordedCalls); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + flutterCommand, + [ + 'drive', + '--enable-experiment=exp1', + '--driver', + driverTestPath, + '--target', + deviceTestPath + ], + pluginExampleDirectory.path), + ])); + }); + }); +} diff --git a/script/tool/test/firebase_test_lab_test.dart b/script/tool/test/firebase_test_lab_test.dart new file mode 100644 index 000000000000..97b977619d57 --- /dev/null +++ b/script/tool/test/firebase_test_lab_test.dart @@ -0,0 +1,256 @@ +import 'dart:io'; + +import 'package:args/command_runner.dart'; +import 'package:flutter_plugin_tools/src/common.dart'; +import 'package:flutter_plugin_tools/src/firebase_test_lab_command.dart'; +import 'package:test/test.dart'; + +import 'mocks.dart'; +import 'util.dart'; + +void main() { + group('$FirebaseTestLabCommand', () { + final List printedMessages = []; + CommandRunner runner; + RecordingProcessRunner processRunner; + + setUp(() { + initializeFakePackages(); + processRunner = RecordingProcessRunner(); + final FirebaseTestLabCommand command = FirebaseTestLabCommand( + mockPackagesDir, mockFileSystem, + processRunner: processRunner, + print: (Object message) => printedMessages.add(message.toString())); + + runner = CommandRunner( + 'firebase_test_lab_command', 'Test for $FirebaseTestLabCommand'); + runner.addCommand(command); + }); + + tearDown(() { + printedMessages.clear(); + }); + + test('retries gcloud set', () async { + final MockProcess mockProcess = MockProcess(); + mockProcess.exitCodeCompleter.complete(1); + processRunner.processToReturn = mockProcess; + createFakePlugin('plugin', withExtraFiles: >[ + ['lib/test/should_not_run_e2e.dart'], + ['example', 'test_driver', 'plugin_e2e.dart'], + ['example', 'test_driver', 'plugin_e2e_test.dart'], + ['example', 'android', 'gradlew'], + ['example', 'should_not_run_e2e.dart'], + [ + 'example', + 'android', + 'app', + 'src', + 'androidTest', + 'MainActivityTest.java' + ], + ]); + await expectLater( + () => runCapturingPrint(runner, ['firebase-test-lab']), + throwsA(const TypeMatcher())); + expect( + printedMessages, + contains( + "\nWarning: gcloud config set returned a non-zero exit code. Continuing anyway.")); + }); + + test('runs e2e tests', () async { + createFakePlugin('plugin', withExtraFiles: >[ + ['test', 'plugin_test.dart'], + ['test', 'plugin_e2e.dart'], + ['should_not_run_e2e.dart'], + ['lib/test/should_not_run_e2e.dart'], + ['example', 'test', 'plugin_e2e.dart'], + ['example', 'test_driver', 'plugin_e2e.dart'], + ['example', 'test_driver', 'plugin_e2e_test.dart'], + ['example', 'integration_test', 'foo_test.dart'], + ['example', 'integration_test', 'should_not_run.dart'], + ['example', 'android', 'gradlew'], + ['example', 'should_not_run_e2e.dart'], + [ + 'example', + 'android', + 'app', + 'src', + 'androidTest', + 'MainActivityTest.java' + ], + ]); + + final List output = await runCapturingPrint(runner, [ + 'firebase-test-lab', + '--device', + 'model=flame,version=29', + '--device', + 'model=seoul,version=26', + '--test-run-id', + 'testRunId', + ]); + + expect( + printedMessages, + orderedEquals([ + '\nRUNNING FIREBASE TEST LAB TESTS for plugin', + '\nFirebase project configured.', + '\n\n', + 'All Firebase Test Lab tests successful!', + ]), + ); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + 'gcloud', + 'auth activate-service-account --key-file=${Platform.environment['HOME']}/gcloud-service-key.json' + .split(' '), + null), + ProcessCall( + 'gcloud', 'config set project flutter-infra'.split(' '), null), + ProcessCall( + '/packages/plugin/example/android/gradlew', + 'app:assembleAndroidTest -Pverbose=true'.split(' '), + '/packages/plugin/example/android'), + ProcessCall( + '/packages/plugin/example/android/gradlew', + 'app:assembleDebug -Pverbose=true -Ptarget=/packages/plugin/test/plugin_e2e.dart' + .split(' '), + '/packages/plugin/example/android'), + ProcessCall( + 'gcloud', + 'firebase test android run --type instrumentation --app build/app/outputs/apk/debug/app-debug.apk --test build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk --timeout 5m --results-bucket=gs://flutter_firebase_testlab --results-dir=plugins_android_test/plugin/null/testRunId/0/ --device model=flame,version=29 --device model=seoul,version=26' + .split(' '), + '/packages/plugin/example'), + ProcessCall( + '/packages/plugin/example/android/gradlew', + 'app:assembleDebug -Pverbose=true -Ptarget=/packages/plugin/example/test_driver/plugin_e2e.dart' + .split(' '), + '/packages/plugin/example/android'), + ProcessCall( + 'gcloud', + 'firebase test android run --type instrumentation --app build/app/outputs/apk/debug/app-debug.apk --test build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk --timeout 5m --results-bucket=gs://flutter_firebase_testlab --results-dir=plugins_android_test/plugin/null/testRunId/1/ --device model=flame,version=29 --device model=seoul,version=26' + .split(' '), + '/packages/plugin/example'), + ProcessCall( + '/packages/plugin/example/android/gradlew', + 'app:assembleDebug -Pverbose=true -Ptarget=/packages/plugin/example/test/plugin_e2e.dart' + .split(' '), + '/packages/plugin/example/android'), + ProcessCall( + 'gcloud', + 'firebase test android run --type instrumentation --app build/app/outputs/apk/debug/app-debug.apk --test build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk --timeout 5m --results-bucket=gs://flutter_firebase_testlab --results-dir=plugins_android_test/plugin/null/testRunId/2/ --device model=flame,version=29 --device model=seoul,version=26' + .split(' '), + '/packages/plugin/example'), + ProcessCall( + '/packages/plugin/example/android/gradlew', + 'app:assembleDebug -Pverbose=true -Ptarget=/packages/plugin/example/integration_test/foo_test.dart' + .split(' '), + '/packages/plugin/example/android'), + ProcessCall( + 'gcloud', + 'firebase test android run --type instrumentation --app build/app/outputs/apk/debug/app-debug.apk --test build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk --timeout 5m --results-bucket=gs://flutter_firebase_testlab --results-dir=plugins_android_test/plugin/null/testRunId/3/ --device model=flame,version=29 --device model=seoul,version=26' + .split(' '), + '/packages/plugin/example'), + ]), + ); + }); + + test('experimental flag', () async { + createFakePlugin('plugin', withExtraFiles: >[ + ['test', 'plugin_test.dart'], + ['test', 'plugin_e2e.dart'], + ['should_not_run_e2e.dart'], + ['lib/test/should_not_run_e2e.dart'], + ['example', 'test', 'plugin_e2e.dart'], + ['example', 'test_driver', 'plugin_e2e.dart'], + ['example', 'test_driver', 'plugin_e2e_test.dart'], + ['example', 'integration_test', 'foo_test.dart'], + ['example', 'integration_test', 'should_not_run.dart'], + ['example', 'android', 'gradlew'], + ['example', 'should_not_run_e2e.dart'], + [ + 'example', + 'android', + 'app', + 'src', + 'androidTest', + 'MainActivityTest.java' + ], + ]); + + await runCapturingPrint(runner, [ + 'firebase-test-lab', + '--device', + 'model=flame,version=29', + '--test-run-id', + 'testRunId', + '--enable-experiment=exp1', + ]); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + 'gcloud', + 'auth activate-service-account --key-file=${Platform.environment['HOME']}/gcloud-service-key.json' + .split(' '), + null), + ProcessCall( + 'gcloud', 'config set project flutter-infra'.split(' '), null), + ProcessCall( + '/packages/plugin/example/android/gradlew', + 'app:assembleAndroidTest -Pverbose=true -Pextra-front-end-options=--enable-experiment%3Dexp1 -Pextra-gen-snapshot-options=--enable-experiment%3Dexp1' + .split(' '), + '/packages/plugin/example/android'), + ProcessCall( + '/packages/plugin/example/android/gradlew', + 'app:assembleDebug -Pverbose=true -Ptarget=/packages/plugin/test/plugin_e2e.dart -Pextra-front-end-options=--enable-experiment%3Dexp1 -Pextra-gen-snapshot-options=--enable-experiment%3Dexp1' + .split(' '), + '/packages/plugin/example/android'), + ProcessCall( + 'gcloud', + 'firebase test android run --type instrumentation --app build/app/outputs/apk/debug/app-debug.apk --test build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk --timeout 5m --results-bucket=gs://flutter_firebase_testlab --results-dir=plugins_android_test/plugin/null/testRunId/0/ --device model=flame,version=29' + .split(' '), + '/packages/plugin/example'), + ProcessCall( + '/packages/plugin/example/android/gradlew', + 'app:assembleDebug -Pverbose=true -Ptarget=/packages/plugin/example/test_driver/plugin_e2e.dart -Pextra-front-end-options=--enable-experiment%3Dexp1 -Pextra-gen-snapshot-options=--enable-experiment%3Dexp1' + .split(' '), + '/packages/plugin/example/android'), + ProcessCall( + 'gcloud', + 'firebase test android run --type instrumentation --app build/app/outputs/apk/debug/app-debug.apk --test build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk --timeout 5m --results-bucket=gs://flutter_firebase_testlab --results-dir=plugins_android_test/plugin/null/testRunId/1/ --device model=flame,version=29' + .split(' '), + '/packages/plugin/example'), + ProcessCall( + '/packages/plugin/example/android/gradlew', + 'app:assembleDebug -Pverbose=true -Ptarget=/packages/plugin/example/test/plugin_e2e.dart -Pextra-front-end-options=--enable-experiment%3Dexp1 -Pextra-gen-snapshot-options=--enable-experiment%3Dexp1' + .split(' '), + '/packages/plugin/example/android'), + ProcessCall( + 'gcloud', + 'firebase test android run --type instrumentation --app build/app/outputs/apk/debug/app-debug.apk --test build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk --timeout 5m --results-bucket=gs://flutter_firebase_testlab --results-dir=plugins_android_test/plugin/null/testRunId/2/ --device model=flame,version=29' + .split(' '), + '/packages/plugin/example'), + ProcessCall( + '/packages/plugin/example/android/gradlew', + 'app:assembleDebug -Pverbose=true -Ptarget=/packages/plugin/example/integration_test/foo_test.dart -Pextra-front-end-options=--enable-experiment%3Dexp1 -Pextra-gen-snapshot-options=--enable-experiment%3Dexp1' + .split(' '), + '/packages/plugin/example/android'), + ProcessCall( + 'gcloud', + 'firebase test android run --type instrumentation --app build/app/outputs/apk/debug/app-debug.apk --test build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk --timeout 5m --results-bucket=gs://flutter_firebase_testlab --results-dir=plugins_android_test/plugin/null/testRunId/3/ --device model=flame,version=29' + .split(' '), + '/packages/plugin/example'), + ]), + ); + + cleanupPackages(); + }); + }); +} diff --git a/script/tool/test/lint_podspecs_command_test.dart b/script/tool/test/lint_podspecs_command_test.dart new file mode 100644 index 000000000000..49d6ad4d8e20 --- /dev/null +++ b/script/tool/test/lint_podspecs_command_test.dart @@ -0,0 +1,202 @@ +import 'dart:io'; + +import 'package:args/command_runner.dart'; +import 'package:file/file.dart'; +import 'package:flutter_plugin_tools/src/lint_podspecs_command.dart'; +import 'package:mockito/mockito.dart'; +import 'package:path/path.dart' as p; +import 'package:platform/platform.dart'; +import 'package:test/test.dart'; + +import 'mocks.dart'; +import 'util.dart'; + +void main() { + group('$LintPodspecsCommand', () { + CommandRunner runner; + MockPlatform mockPlatform; + final RecordingProcessRunner processRunner = RecordingProcessRunner(); + List printedMessages; + + setUp(() { + initializeFakePackages(); + + printedMessages = []; + mockPlatform = MockPlatform(); + when(mockPlatform.isMacOS).thenReturn(true); + final LintPodspecsCommand command = LintPodspecsCommand( + mockPackagesDir, + mockFileSystem, + processRunner: processRunner, + platform: mockPlatform, + print: (Object message) => printedMessages.add(message.toString()), + ); + + runner = + CommandRunner('podspec_test', 'Test for $LintPodspecsCommand'); + runner.addCommand(command); + final MockProcess mockLintProcess = MockProcess(); + mockLintProcess.exitCodeCompleter.complete(0); + processRunner.processToReturn = mockLintProcess; + processRunner.recordedCalls.clear(); + }); + + tearDown(() { + cleanupPackages(); + }); + + test('only runs on macOS', () async { + createFakePlugin('plugin1', withExtraFiles: >[ + ['plugin1.podspec'], + ]); + + when(mockPlatform.isMacOS).thenReturn(false); + await runner.run(['podspecs']); + + expect( + processRunner.recordedCalls, + equals([]), + ); + }); + + test('runs pod lib lint on a podspec', () async { + Directory plugin1Dir = + createFakePlugin('plugin1', withExtraFiles: >[ + ['ios', 'plugin1.podspec'], + ['bogus.dart'], // Ignore non-podspecs. + ]); + + processRunner.resultStdout = 'Foo'; + processRunner.resultStderr = 'Bar'; + + await runner.run(['podspecs']); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall('which', ['pod'], mockPackagesDir.path), + ProcessCall( + 'pod', + [ + 'lib', + 'lint', + p.join(plugin1Dir.path, 'ios', 'plugin1.podspec'), + '--analyze', + '--use-libraries' + ], + mockPackagesDir.path), + ProcessCall( + 'pod', + [ + 'lib', + 'lint', + p.join(plugin1Dir.path, 'ios', 'plugin1.podspec'), + '--analyze', + ], + mockPackagesDir.path), + ]), + ); + + expect( + printedMessages, contains('Linting and analyzing plugin1.podspec')); + expect(printedMessages, contains('Foo')); + expect(printedMessages, contains('Bar')); + }); + + test('skips podspecs with known issues', () async { + createFakePlugin('plugin1', withExtraFiles: >[ + ['plugin1.podspec'] + ]); + createFakePlugin('plugin2', withExtraFiles: >[ + ['plugin2.podspec'] + ]); + + await runner + .run(['podspecs', '--skip=plugin1', '--skip=plugin2']); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall('which', ['pod'], mockPackagesDir.path), + ]), + ); + }); + + test('skips analyzer for podspecs with known warnings', () async { + Directory plugin1Dir = + createFakePlugin('plugin1', withExtraFiles: >[ + ['plugin1.podspec'], + ]); + + await runner.run(['podspecs', '--no-analyze=plugin1']); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall('which', ['pod'], mockPackagesDir.path), + ProcessCall( + 'pod', + [ + 'lib', + 'lint', + p.join(plugin1Dir.path, 'plugin1.podspec'), + '--use-libraries' + ], + mockPackagesDir.path), + ProcessCall( + 'pod', + [ + 'lib', + 'lint', + p.join(plugin1Dir.path, 'plugin1.podspec'), + ], + mockPackagesDir.path), + ]), + ); + + expect(printedMessages, contains('Linting plugin1.podspec')); + }); + + test('allow warnings for podspecs with known warnings', () async { + Directory plugin1Dir = + createFakePlugin('plugin1', withExtraFiles: >[ + ['plugin1.podspec'], + ]); + + await runner.run(['podspecs', '--ignore-warnings=plugin1']); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall('which', ['pod'], mockPackagesDir.path), + ProcessCall( + 'pod', + [ + 'lib', + 'lint', + p.join(plugin1Dir.path, 'plugin1.podspec'), + '--allow-warnings', + '--analyze', + '--use-libraries' + ], + mockPackagesDir.path), + ProcessCall( + 'pod', + [ + 'lib', + 'lint', + p.join(plugin1Dir.path, 'plugin1.podspec'), + '--allow-warnings', + '--analyze', + ], + mockPackagesDir.path), + ]), + ); + + expect( + printedMessages, contains('Linting and analyzing plugin1.podspec')); + }); + }); +} + +class MockPlatform extends Mock implements Platform {} diff --git a/script/tool/test/list_command_test.dart b/script/tool/test/list_command_test.dart new file mode 100644 index 000000000000..478625283dd0 --- /dev/null +++ b/script/tool/test/list_command_test.dart @@ -0,0 +1,198 @@ +import 'package:args/command_runner.dart'; +import 'package:file/file.dart'; +import 'package:flutter_plugin_tools/src/list_command.dart'; +import 'package:test/test.dart'; + +import 'util.dart'; + +void main() { + group('$ListCommand', () { + CommandRunner runner; + + setUp(() { + initializeFakePackages(); + final ListCommand command = ListCommand(mockPackagesDir, mockFileSystem); + + runner = CommandRunner('list_test', 'Test for $ListCommand'); + runner.addCommand(command); + }); + + test('lists plugins', () async { + createFakePlugin('plugin1'); + createFakePlugin('plugin2'); + + final List plugins = + await runCapturingPrint(runner, ['list', '--type=plugin']); + + expect( + plugins, + orderedEquals([ + '/packages/plugin1', + '/packages/plugin2', + ]), + ); + + cleanupPackages(); + }); + + test('lists examples', () async { + createFakePlugin('plugin1', withSingleExample: true); + createFakePlugin('plugin2', + withExamples: ['example1', 'example2']); + createFakePlugin('plugin3'); + + final List examples = + await runCapturingPrint(runner, ['list', '--type=example']); + + expect( + examples, + orderedEquals([ + '/packages/plugin1/example', + '/packages/plugin2/example/example1', + '/packages/plugin2/example/example2', + ]), + ); + + cleanupPackages(); + }); + + test('lists packages', () async { + createFakePlugin('plugin1', withSingleExample: true); + createFakePlugin('plugin2', + withExamples: ['example1', 'example2']); + createFakePlugin('plugin3'); + + final List packages = + await runCapturingPrint(runner, ['list', '--type=package']); + + expect( + packages, + unorderedEquals([ + '/packages/plugin1', + '/packages/plugin1/example', + '/packages/plugin2', + '/packages/plugin2/example/example1', + '/packages/plugin2/example/example2', + '/packages/plugin3', + ]), + ); + + cleanupPackages(); + }); + + test('lists files', () async { + createFakePlugin('plugin1', withSingleExample: true); + createFakePlugin('plugin2', + withExamples: ['example1', 'example2']); + createFakePlugin('plugin3'); + + final List examples = + await runCapturingPrint(runner, ['list', '--type=file']); + + expect( + examples, + unorderedEquals([ + '/packages/plugin1/pubspec.yaml', + '/packages/plugin1/example/pubspec.yaml', + '/packages/plugin2/pubspec.yaml', + '/packages/plugin2/example/example1/pubspec.yaml', + '/packages/plugin2/example/example2/pubspec.yaml', + '/packages/plugin3/pubspec.yaml', + ]), + ); + + cleanupPackages(); + }); + + test('lists plugins using federated plugin layout', () async { + createFakePlugin('plugin1'); + + // Create a federated plugin by creating a directory under the packages + // directory with several packages underneath. + final Directory federatedPlugin = + mockPackagesDir.childDirectory('my_plugin')..createSync(); + final Directory clientLibrary = + federatedPlugin.childDirectory('my_plugin')..createSync(); + createFakePubspec(clientLibrary); + final Directory webLibrary = + federatedPlugin.childDirectory('my_plugin_web')..createSync(); + createFakePubspec(webLibrary); + final Directory macLibrary = + federatedPlugin.childDirectory('my_plugin_macos')..createSync(); + createFakePubspec(macLibrary); + + // Test without specifying `--type`. + final List plugins = + await runCapturingPrint(runner, ['list']); + + expect( + plugins, + unorderedEquals([ + '/packages/plugin1', + '/packages/my_plugin/my_plugin', + '/packages/my_plugin/my_plugin_web', + '/packages/my_plugin/my_plugin_macos', + ]), + ); + + cleanupPackages(); + }); + + test('can filter plugins with the --plugins argument', () async { + createFakePlugin('plugin1'); + + // Create a federated plugin by creating a directory under the packages + // directory with several packages underneath. + final Directory federatedPlugin = + mockPackagesDir.childDirectory('my_plugin')..createSync(); + final Directory clientLibrary = + federatedPlugin.childDirectory('my_plugin')..createSync(); + createFakePubspec(clientLibrary); + final Directory webLibrary = + federatedPlugin.childDirectory('my_plugin_web')..createSync(); + createFakePubspec(webLibrary); + final Directory macLibrary = + federatedPlugin.childDirectory('my_plugin_macos')..createSync(); + createFakePubspec(macLibrary); + + List plugins = await runCapturingPrint( + runner, ['list', '--plugins=plugin1']); + expect( + plugins, + unorderedEquals([ + '/packages/plugin1', + ]), + ); + + plugins = await runCapturingPrint( + runner, ['list', '--plugins=my_plugin']); + expect( + plugins, + unorderedEquals([ + '/packages/my_plugin/my_plugin', + '/packages/my_plugin/my_plugin_web', + '/packages/my_plugin/my_plugin_macos', + ]), + ); + + plugins = await runCapturingPrint( + runner, ['list', '--plugins=my_plugin/my_plugin_web']); + expect( + plugins, + unorderedEquals([ + '/packages/my_plugin/my_plugin_web', + ]), + ); + + plugins = await runCapturingPrint(runner, + ['list', '--plugins=my_plugin/my_plugin_web,plugin1']); + expect( + plugins, + unorderedEquals([ + '/packages/plugin1', + '/packages/my_plugin/my_plugin_web', + ]), + ); + }); + }); +} diff --git a/script/tool/test/mocks.dart b/script/tool/test/mocks.dart new file mode 100644 index 000000000000..3e17ff8efd32 --- /dev/null +++ b/script/tool/test/mocks.dart @@ -0,0 +1,33 @@ +import 'dart:async'; +import 'dart:io' as io; + +import 'package:file/file.dart'; +import 'package:mockito/mockito.dart'; + +class MockProcess extends Mock implements io.Process { + final Completer exitCodeCompleter = Completer(); + final StreamController> stdoutController = + StreamController>(); + final StreamController> stderrController = + StreamController>(); + final MockIOSink stdinMock = MockIOSink(); + + @override + Future get exitCode => exitCodeCompleter.future; + + @override + Stream> get stdout => stdoutController.stream; + + @override + Stream> get stderr => stderrController.stream; + + @override + IOSink get stdin => stdinMock; +} + +class MockIOSink extends Mock implements IOSink { + List lines = []; + + @override + void writeln([Object obj = ""]) => lines.add(obj); +} diff --git a/script/tool/test/publish_plugin_command_test.dart b/script/tool/test/publish_plugin_command_test.dart new file mode 100644 index 000000000000..ada4bf08fd72 --- /dev/null +++ b/script/tool/test/publish_plugin_command_test.dart @@ -0,0 +1,378 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:io' as io; + +import 'package:args/command_runner.dart'; +import 'package:file/file.dart'; +import 'package:file/local.dart'; +import 'package:flutter_plugin_tools/src/publish_plugin_command.dart'; +import 'package:flutter_plugin_tools/src/common.dart'; +import 'package:git/git.dart'; +import 'package:matcher/matcher.dart'; +import 'package:mockito/mockito.dart'; +import 'package:test/test.dart'; + +import 'mocks.dart'; +import 'util.dart'; + +void main() { + const String testPluginName = 'foo'; + final List printedMessages = []; + + Directory parentDir; + Directory pluginDir; + GitDir gitDir; + TestProcessRunner processRunner; + CommandRunner commandRunner; + MockStdin mockStdin; + + setUp(() async { + // This test uses a local file system instead of an in memory one throughout + // so that git actually works. In setup we initialize a mono repo of plugins + // with one package and commit everything to Git. + parentDir = const LocalFileSystem() + .systemTempDirectory + .createTempSync('publish_plugin_command_test-'); + initializeFakePackages(parentDir: parentDir); + pluginDir = createFakePlugin(testPluginName, withSingleExample: false); + assert(pluginDir != null && pluginDir.existsSync()); + createFakePubspec(pluginDir, includeVersion: true); + io.Process.runSync('git', ['init'], + workingDirectory: mockPackagesDir.path); + gitDir = await GitDir.fromExisting(mockPackagesDir.path); + await gitDir.runCommand(['add', '-A']); + await gitDir.runCommand(['commit', '-m', 'Initial commit']); + processRunner = TestProcessRunner(); + mockStdin = MockStdin(); + commandRunner = CommandRunner('tester', '') + ..addCommand(PublishPluginCommand( + mockPackagesDir, const LocalFileSystem(), + processRunner: processRunner, + print: (Object message) => printedMessages.add(message.toString()), + stdinput: mockStdin)); + }); + + tearDown(() { + parentDir.deleteSync(recursive: true); + printedMessages.clear(); + }); + + group('Initial validation', () { + test('requires a package flag', () async { + await expectLater(() => commandRunner.run(['publish-plugin']), + throwsA(const TypeMatcher())); + + expect( + printedMessages.last, contains("Must specify a package to publish.")); + }); + + test('requires an existing flag', () async { + await expectLater( + () => commandRunner + .run(['publish-plugin', '--package', 'iamerror']), + throwsA(const TypeMatcher())); + + expect(printedMessages.last, contains('iamerror does not exist')); + }); + + test('refuses to proceed with dirty files', () async { + pluginDir.childFile('tmp').createSync(); + + await expectLater( + () => commandRunner + .run(['publish-plugin', '--package', testPluginName]), + throwsA(const TypeMatcher())); + + expect( + printedMessages.last, + contains( + "There are files in the package directory that haven't been saved in git.")); + }); + + test('fails immediately if the remote doesn\'t exist', () async { + await expectLater( + () => commandRunner + .run(['publish-plugin', '--package', testPluginName]), + throwsA(const TypeMatcher())); + + expect(processRunner.results.last.stderr, contains("No such remote")); + }); + + test("doesn't validate the remote if it's not pushing tags", () async { + // Immediately return 0 when running `pub publish`. + processRunner.mockPublishProcess.exitCodeCompleter.complete(0); + + await commandRunner.run([ + 'publish-plugin', + '--package', + testPluginName, + '--no-push-tags', + '--no-tag-release' + ]); + + expect(printedMessages.last, 'Done!'); + }); + + test('can publish non-flutter package', () async { + createFakePubspec(pluginDir, includeVersion: true, isFlutter: false); + io.Process.runSync('git', ['init'], + workingDirectory: mockPackagesDir.path); + gitDir = await GitDir.fromExisting(mockPackagesDir.path); + await gitDir.runCommand(['add', '-A']); + await gitDir.runCommand(['commit', '-m', 'Initial commit']); + // Immediately return 0 when running `pub publish`. + processRunner.mockPublishProcess.exitCodeCompleter.complete(0); + await commandRunner.run([ + 'publish-plugin', + '--package', + testPluginName, + '--no-push-tags', + '--no-tag-release' + ]); + expect(printedMessages.last, 'Done!'); + }); + }); + + group('Publishes package', () { + test('while showing all output from pub publish to the user', () async { + final Future publishCommand = commandRunner.run([ + 'publish-plugin', + '--package', + testPluginName, + '--no-push-tags', + '--no-tag-release' + ]); + processRunner.mockPublishProcess.stdoutController.add(utf8.encode('Foo')); + processRunner.mockPublishProcess.stderrController.add(utf8.encode('Bar')); + processRunner.mockPublishProcess.exitCodeCompleter.complete(0); + + await publishCommand; + + expect(printedMessages, contains('Foo')); + expect(printedMessages, contains('Bar')); + }); + + test('forwards input from the user to `pub publish`', () async { + final Future publishCommand = commandRunner.run([ + 'publish-plugin', + '--package', + testPluginName, + '--no-push-tags', + '--no-tag-release' + ]); + mockStdin.controller.add(utf8.encode('user input')); + processRunner.mockPublishProcess.exitCodeCompleter.complete(0); + + await publishCommand; + + expect(processRunner.mockPublishProcess.stdinMock.lines, + contains('user input')); + }); + + test('forwards --pub-publish-flags to pub publish', () async { + processRunner.mockPublishProcess.exitCodeCompleter.complete(0); + await commandRunner.run([ + 'publish-plugin', + '--package', + testPluginName, + '--no-push-tags', + '--no-tag-release', + '--pub-publish-flags', + '--dry-run,--server=foo' + ]); + + expect(processRunner.mockPublishArgs.length, 4); + expect(processRunner.mockPublishArgs[0], 'pub'); + expect(processRunner.mockPublishArgs[1], 'publish'); + expect(processRunner.mockPublishArgs[2], '--dry-run'); + expect(processRunner.mockPublishArgs[3], '--server=foo'); + }); + + test('throws if pub publish fails', () async { + processRunner.mockPublishProcess.exitCodeCompleter.complete(128); + await expectLater( + () => commandRunner.run([ + 'publish-plugin', + '--package', + testPluginName, + '--no-push-tags', + '--no-tag-release', + ]), + throwsA(const TypeMatcher())); + + expect(printedMessages, contains("Publish failed. Exiting.")); + }); + }); + + group('Tags release', () { + test('with the version and name from the pubspec.yaml', () async { + processRunner.mockPublishProcess.exitCodeCompleter.complete(0); + await commandRunner.run([ + 'publish-plugin', + '--package', + testPluginName, + '--no-push-tags', + ]); + + final String tag = + (await gitDir.runCommand(['show-ref', 'fake_package-v0.0.1'])) + .stdout; + expect(tag, isNotEmpty); + }); + + test('only if publishing succeeded', () async { + processRunner.mockPublishProcess.exitCodeCompleter.complete(128); + await expectLater( + () => commandRunner.run([ + 'publish-plugin', + '--package', + testPluginName, + '--no-push-tags', + ]), + throwsA(const TypeMatcher())); + + expect(printedMessages, contains("Publish failed. Exiting.")); + final String tag = (await gitDir.runCommand( + ['show-ref', 'fake_package-v0.0.1'], + throwOnError: false)) + .stdout; + expect(tag, isEmpty); + }); + }); + + group('Pushes tags', () { + setUp(() async { + await gitDir.runCommand( + ['remote', 'add', 'upstream', 'http://localhost:8000']); + }); + + test('requires user confirmation', () async { + processRunner.mockPublishProcess.exitCodeCompleter.complete(0); + mockStdin.readLineOutput = 'help'; + await expectLater( + () => commandRunner.run([ + 'publish-plugin', + '--package', + testPluginName, + ]), + throwsA(const TypeMatcher())); + + expect(printedMessages, contains('Tag push canceled.')); + }); + + test('to upstream by default', () async { + await gitDir.runCommand(['tag', 'garbage']); + processRunner.mockPublishProcess.exitCodeCompleter.complete(0); + mockStdin.readLineOutput = 'y'; + await commandRunner.run([ + 'publish-plugin', + '--package', + testPluginName, + ]); + + expect(processRunner.pushTagsArgs.isNotEmpty, isTrue); + expect(processRunner.pushTagsArgs[1], 'upstream'); + expect(processRunner.pushTagsArgs[2], 'fake_package-v0.0.1'); + expect(printedMessages.last, 'Done!'); + }); + + test('to different remotes based on a flag', () async { + await gitDir.runCommand( + ['remote', 'add', 'origin', 'http://localhost:8001']); + processRunner.mockPublishProcess.exitCodeCompleter.complete(0); + mockStdin.readLineOutput = 'y'; + await commandRunner.run([ + 'publish-plugin', + '--package', + testPluginName, + '--remote', + 'origin', + ]); + + expect(processRunner.pushTagsArgs.isNotEmpty, isTrue); + expect(processRunner.pushTagsArgs[1], 'origin'); + expect(processRunner.pushTagsArgs[2], 'fake_package-v0.0.1'); + expect(printedMessages.last, 'Done!'); + }); + + test('only if tagging and pushing to remotes are both enabled', () async { + processRunner.mockPublishProcess.exitCodeCompleter.complete(0); + await commandRunner.run([ + 'publish-plugin', + '--package', + testPluginName, + '--no-tag-release', + ]); + + expect(processRunner.pushTagsArgs.isEmpty, isTrue); + expect(printedMessages.last, 'Done!'); + }); + }); +} + +class TestProcessRunner extends ProcessRunner { + final List results = []; + final MockProcess mockPublishProcess = MockProcess(); + final List mockPublishArgs = []; + final MockProcessResult mockPushTagsResult = MockProcessResult(); + final List pushTagsArgs = []; + + @override + Future runAndExitOnError( + String executable, + List args, { + Directory workingDir, + }) async { + // Don't ever really push tags. + if (executable == 'git' && args.isNotEmpty && args[0] == 'push') { + pushTagsArgs.addAll(args); + return mockPushTagsResult; + } + + final io.ProcessResult result = io.Process.runSync(executable, args, + workingDirectory: workingDir?.path); + results.add(result); + if (result.exitCode != 0) { + throw ToolExit(result.exitCode); + } + return result; + } + + @override + Future start(String executable, List args, + {Directory workingDirectory}) async { + /// Never actually publish anything. Start is always and only used for this + /// since it returns something we can route stdin through. + assert(executable == 'flutter' && + args.isNotEmpty && + args[0] == 'pub' && + args[1] == 'publish'); + mockPublishArgs.addAll(args); + return mockPublishProcess; + } +} + +class MockStdin extends Mock implements io.Stdin { + final StreamController> controller = StreamController>(); + String readLineOutput; + + @override + Stream transform(StreamTransformer streamTransformer) { + return controller.stream.transform(streamTransformer); + } + + @override + StreamSubscription> listen(void onData(List event), + {Function onError, void onDone(), bool cancelOnError}) { + return controller.stream.listen(onData, + onError: onError, onDone: onDone, cancelOnError: cancelOnError); + } + + @override + String readLineSync( + {Encoding encoding = io.systemEncoding, + bool retainNewlines = false}) => + readLineOutput; +} + +class MockProcessResult extends Mock implements io.ProcessResult {} diff --git a/script/tool/test/test_command_test.dart b/script/tool/test/test_command_test.dart new file mode 100644 index 000000000000..514e4c27190a --- /dev/null +++ b/script/tool/test/test_command_test.dart @@ -0,0 +1,154 @@ +import 'package:args/command_runner.dart'; +import 'package:file/file.dart'; +import 'package:flutter_plugin_tools/src/test_command.dart'; +import 'package:test/test.dart'; + +import 'util.dart'; + +void main() { + group('$TestCommand', () { + CommandRunner runner; + final RecordingProcessRunner processRunner = RecordingProcessRunner(); + + setUp(() { + initializeFakePackages(); + final TestCommand command = TestCommand(mockPackagesDir, mockFileSystem, + processRunner: processRunner); + + runner = CommandRunner('test_test', 'Test for $TestCommand'); + runner.addCommand(command); + }); + + tearDown(() { + cleanupPackages(); + processRunner.recordedCalls.clear(); + }); + + test('runs flutter test on each plugin', () async { + final Directory plugin1Dir = + createFakePlugin('plugin1', withExtraFiles: >[ + ['test', 'empty_test.dart'], + ]); + final Directory plugin2Dir = + createFakePlugin('plugin2', withExtraFiles: >[ + ['test', 'empty_test.dart'], + ]); + + await runner.run(['test']); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall('flutter', ['test', '--color'], plugin1Dir.path), + ProcessCall('flutter', ['test', '--color'], plugin2Dir.path), + ]), + ); + + cleanupPackages(); + }); + + test('skips testing plugins without test directory', () async { + createFakePlugin('plugin1'); + final Directory plugin2Dir = + createFakePlugin('plugin2', withExtraFiles: >[ + ['test', 'empty_test.dart'], + ]); + + await runner.run(['test']); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall('flutter', ['test', '--color'], plugin2Dir.path), + ]), + ); + + cleanupPackages(); + }); + + test('runs pub run test on non-Flutter packages', () async { + final Directory plugin1Dir = createFakePlugin('plugin1', + isFlutter: true, + withExtraFiles: >[ + ['test', 'empty_test.dart'], + ]); + final Directory plugin2Dir = createFakePlugin('plugin2', + isFlutter: false, + withExtraFiles: >[ + ['test', 'empty_test.dart'], + ]); + + await runner.run(['test', '--enable-experiment=exp1']); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + 'flutter', + ['test', '--color', '--enable-experiment=exp1'], + plugin1Dir.path), + ProcessCall('pub', ['get'], plugin2Dir.path), + ProcessCall( + 'pub', + ['run', '--enable-experiment=exp1', 'test'], + plugin2Dir.path), + ]), + ); + + cleanupPackages(); + }); + + test('runs on Chrome for web plugins', () async { + final Directory pluginDir = createFakePlugin( + 'plugin', + withExtraFiles: >[ + ['test', 'empty_test.dart'], + ], + isFlutter: true, + isWebPlugin: true, + ); + + await runner.run(['test']); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall('flutter', + ['test', '--color', '--platform=chrome'], pluginDir.path), + ]), + ); + }); + + test('enable-experiment flag', () async { + final Directory plugin1Dir = createFakePlugin('plugin1', + isFlutter: true, + withExtraFiles: >[ + ['test', 'empty_test.dart'], + ]); + final Directory plugin2Dir = createFakePlugin('plugin2', + isFlutter: false, + withExtraFiles: >[ + ['test', 'empty_test.dart'], + ]); + + await runner.run(['test', '--enable-experiment=exp1']); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + 'flutter', + ['test', '--color', '--enable-experiment=exp1'], + plugin1Dir.path), + ProcessCall('pub', ['get'], plugin2Dir.path), + ProcessCall( + 'pub', + ['run', '--enable-experiment=exp1', 'test'], + plugin2Dir.path), + ]), + ); + + cleanupPackages(); + }); + }); +} diff --git a/script/tool/test/util.dart b/script/tool/test/util.dart new file mode 100644 index 000000000000..ec0000d13f34 --- /dev/null +++ b/script/tool/test/util.dart @@ -0,0 +1,291 @@ +import 'dart:async'; +import 'dart:io' as io; + +import 'package:args/command_runner.dart'; +import 'package:file/file.dart'; +import 'package:file/memory.dart'; +import 'package:platform/platform.dart'; +import 'package:flutter_plugin_tools/src/common.dart'; +import 'package:quiver/collection.dart'; + +FileSystem mockFileSystem = MemoryFileSystem( + style: LocalPlatform().isWindows + ? FileSystemStyle.windows + : FileSystemStyle.posix); +Directory mockPackagesDir; + +/// Creates a mock packages directory in the mock file system. +/// +/// If [parentDir] is set the mock packages dir will be creates as a child of +/// it. If not [mockFileSystem] will be used instead. +void initializeFakePackages({Directory parentDir}) { + mockPackagesDir = + (parentDir ?? mockFileSystem.currentDirectory).childDirectory('packages'); + mockPackagesDir.createSync(); +} + +/// Creates a plugin package with the given [name] in [mockPackagesDir]. +Directory createFakePlugin( + String name, { + bool withSingleExample = false, + List withExamples = const [], + List> withExtraFiles = const >[], + bool isFlutter = true, + bool isAndroidPlugin = false, + bool isIosPlugin = false, + bool isWebPlugin = false, + bool isLinuxPlugin = false, + bool isMacOsPlugin = false, + bool isWindowsPlugin = false, + String parentDirectoryName = '', +}) { + assert(!(withSingleExample && withExamples.isNotEmpty), + 'cannot pass withSingleExample and withExamples simultaneously'); + + final Directory pluginDirectory = (parentDirectoryName != '') + ? mockPackagesDir.childDirectory(parentDirectoryName).childDirectory(name) + : mockPackagesDir.childDirectory(name); + pluginDirectory.createSync(recursive: true); + + createFakePubspec( + pluginDirectory, + name: name, + isFlutter: isFlutter, + isAndroidPlugin: isAndroidPlugin, + isIosPlugin: isIosPlugin, + isWebPlugin: isWebPlugin, + isLinuxPlugin: isLinuxPlugin, + isMacOsPlugin: isMacOsPlugin, + isWindowsPlugin: isWindowsPlugin, + ); + + if (withSingleExample) { + final Directory exampleDir = pluginDirectory.childDirectory('example') + ..createSync(); + createFakePubspec(exampleDir, + name: "${name}_example", isFlutter: isFlutter); + } else if (withExamples.isNotEmpty) { + final Directory exampleDir = pluginDirectory.childDirectory('example') + ..createSync(); + for (String example in withExamples) { + final Directory currentExample = exampleDir.childDirectory(example) + ..createSync(); + createFakePubspec(currentExample, name: example, isFlutter: isFlutter); + } + } + + for (List file in withExtraFiles) { + final List newFilePath = [pluginDirectory.path] + ..addAll(file); + final File newFile = + mockFileSystem.file(mockFileSystem.path.joinAll(newFilePath)); + newFile.createSync(recursive: true); + } + + return pluginDirectory; +} + +/// Creates a `pubspec.yaml` file with a flutter dependency. +void createFakePubspec( + Directory parent, { + String name = 'fake_package', + bool isFlutter = true, + bool includeVersion = false, + bool isAndroidPlugin = false, + bool isIosPlugin = false, + bool isWebPlugin = false, + bool isLinuxPlugin = false, + bool isMacOsPlugin = false, + bool isWindowsPlugin = false, +}) { + parent.childFile('pubspec.yaml').createSync(); + String yaml = ''' +name: $name +flutter: + plugin: + platforms: +'''; + if (isAndroidPlugin) { + yaml += ''' + android: + package: io.flutter.plugins.fake + pluginClass: FakePlugin +'''; + } + if (isIosPlugin) { + yaml += ''' + ios: + pluginClass: FLTFakePlugin +'''; + } + if (isWebPlugin) { + yaml += ''' + web: + pluginClass: FakePlugin + fileName: ${name}_web.dart +'''; + } + if (isLinuxPlugin) { + yaml += ''' + linux: + pluginClass: FakePlugin +'''; + } + if (isMacOsPlugin) { + yaml += ''' + macos: + pluginClass: FakePlugin +'''; + } + if (isWindowsPlugin) { + yaml += ''' + windows: + pluginClass: FakePlugin +'''; + } + if (isFlutter) { + yaml += ''' +dependencies: + flutter: + sdk: flutter +'''; + } + if (includeVersion) { + yaml += ''' +version: 0.0.1 +publish_to: none # Hardcoded safeguard to prevent this from somehow being published by a broken test. +'''; + } + parent.childFile('pubspec.yaml').writeAsStringSync(yaml); +} + +/// Cleans up the mock packages directory, making it an empty directory again. +void cleanupPackages() { + mockPackagesDir.listSync().forEach((FileSystemEntity entity) { + entity.deleteSync(recursive: true); + }); +} + +/// Run the command [runner] with the given [args] and return +/// what was printed. +Future> runCapturingPrint( + CommandRunner runner, List args) async { + final List prints = []; + final ZoneSpecification spec = ZoneSpecification( + print: (_, __, ___, String message) { + prints.add(message); + }, + ); + await Zone.current + .fork(specification: spec) + .run>(() => runner.run(args)); + + return prints; +} + +/// A mock [ProcessRunner] which records process calls. +class RecordingProcessRunner extends ProcessRunner { + io.Process processToReturn; + final List recordedCalls = []; + + /// Populate for [io.ProcessResult] to use a String [stdout] instead of a [List] of [int]. + String resultStdout; + + /// Populate for [io.ProcessResult] to use a String [stderr] instead of a [List] of [int]. + String resultStderr; + + @override + Future runAndStream( + String executable, + List args, { + Directory workingDir, + bool exitOnError = false, + }) async { + recordedCalls.add(ProcessCall(executable, args, workingDir?.path)); + return Future.value( + processToReturn == null ? 0 : await processToReturn.exitCode); + } + + /// Returns [io.ProcessResult] created from [processToReturn], [resultStdout], and [resultStderr]. + @override + Future run(String executable, List args, + {Directory workingDir, + bool exitOnError = false, + stdoutEncoding = io.systemEncoding, + stderrEncoding = io.systemEncoding}) async { + recordedCalls.add(ProcessCall(executable, args, workingDir?.path)); + io.ProcessResult result; + + if (processToReturn != null) { + result = io.ProcessResult( + processToReturn.pid, + await processToReturn.exitCode, + resultStdout ?? processToReturn.stdout, + resultStderr ?? processToReturn.stderr); + } + return Future.value(result); + } + + @override + Future runAndExitOnError( + String executable, + List args, { + Directory workingDir, + }) async { + recordedCalls.add(ProcessCall(executable, args, workingDir?.path)); + io.ProcessResult result; + if (processToReturn != null) { + result = io.ProcessResult( + processToReturn.pid, + await processToReturn.exitCode, + resultStdout ?? processToReturn.stdout, + resultStderr ?? processToReturn.stderr); + } + return Future.value(result); + } + + @override + Future start(String executable, List args, + {Directory workingDirectory}) async { + recordedCalls.add(ProcessCall(executable, args, workingDirectory?.path)); + return Future.value(processToReturn); + } +} + +/// A recorded process call. +class ProcessCall { + const ProcessCall(this.executable, this.args, this.workingDir); + + /// The executable that was called. + final String executable; + + /// The arguments passed to [executable] in the call. + final List args; + + /// The working directory this process was called from. + final String workingDir; + + @override + bool operator ==(dynamic other) { + if (other is! ProcessCall) { + return false; + } + final ProcessCall otherCall = other; + return executable == otherCall.executable && + listsEqual(args, otherCall.args) && + workingDir == otherCall.workingDir; + } + + @override + int get hashCode => + executable?.hashCode ?? + 0 ^ args?.hashCode ?? + 0 ^ workingDir?.hashCode ?? + 0; + + @override + String toString() { + final List command = [executable]..addAll(args); + return '"${command.join(' ')}" in $workingDir'; + } +} diff --git a/script/tool/test/version_check_test.dart b/script/tool/test/version_check_test.dart new file mode 100644 index 000000000000..b9ace3811bff --- /dev/null +++ b/script/tool/test/version_check_test.dart @@ -0,0 +1,319 @@ +import 'dart:async'; +import 'dart:io'; + +import 'package:args/command_runner.dart'; +import 'package:git/git.dart'; +import 'package:mockito/mockito.dart'; +import "package:test/test.dart"; +import "package:flutter_plugin_tools/src/version_check_command.dart"; +import 'package:pub_semver/pub_semver.dart'; +import 'util.dart'; + +void testAllowedVersion( + String masterVersion, + String headVersion, { + bool allowed = true, + NextVersionType nextVersionType, +}) { + final Version master = Version.parse(masterVersion); + final Version head = Version.parse(headVersion); + final Map allowedVersions = + getAllowedNextVersions(master, head); + if (allowed) { + expect(allowedVersions, contains(head)); + if (nextVersionType != null) { + expect(allowedVersions[head], equals(nextVersionType)); + } + } else { + expect(allowedVersions, isNot(contains(head))); + } +} + +class MockGitDir extends Mock implements GitDir {} + +class MockProcessResult extends Mock implements ProcessResult {} + +void main() { + group('$VersionCheckCommand', () { + CommandRunner runner; + RecordingProcessRunner processRunner; + List> gitDirCommands; + String gitDiffResponse; + Map gitShowResponses; + + setUp(() { + gitDirCommands = >[]; + gitDiffResponse = ''; + gitShowResponses = {}; + final MockGitDir gitDir = MockGitDir(); + when(gitDir.runCommand(any)).thenAnswer((Invocation invocation) { + gitDirCommands.add(invocation.positionalArguments[0]); + final MockProcessResult mockProcessResult = MockProcessResult(); + if (invocation.positionalArguments[0][0] == 'diff') { + when(mockProcessResult.stdout).thenReturn(gitDiffResponse); + } else if (invocation.positionalArguments[0][0] == 'show') { + final String response = + gitShowResponses[invocation.positionalArguments[0][1]]; + when(mockProcessResult.stdout).thenReturn(response); + } + return Future.value(mockProcessResult); + }); + initializeFakePackages(); + processRunner = RecordingProcessRunner(); + final VersionCheckCommand command = VersionCheckCommand( + mockPackagesDir, mockFileSystem, + processRunner: processRunner, gitDir: gitDir); + + runner = CommandRunner( + 'version_check_command', 'Test for $VersionCheckCommand'); + runner.addCommand(command); + }); + + tearDown(() { + cleanupPackages(); + }); + + test('allows valid version', () async { + createFakePlugin('plugin'); + gitDiffResponse = "packages/plugin/pubspec.yaml"; + gitShowResponses = { + 'master:packages/plugin/pubspec.yaml': 'version: 1.0.0', + 'HEAD:packages/plugin/pubspec.yaml': 'version: 2.0.0', + }; + final List output = await runCapturingPrint( + runner, ['version-check', '--base_sha=master']); + + expect( + output, + orderedEquals([ + 'No version check errors found!', + ]), + ); + expect(gitDirCommands.length, equals(3)); + expect( + gitDirCommands[0].join(' '), equals('diff --name-only master HEAD')); + expect(gitDirCommands[1].join(' '), + equals('show master:packages/plugin/pubspec.yaml')); + expect(gitDirCommands[2].join(' '), + equals('show HEAD:packages/plugin/pubspec.yaml')); + }); + + test('denies invalid version', () async { + createFakePlugin('plugin'); + gitDiffResponse = "packages/plugin/pubspec.yaml"; + gitShowResponses = { + 'master:packages/plugin/pubspec.yaml': 'version: 0.0.1', + 'HEAD:packages/plugin/pubspec.yaml': 'version: 0.2.0', + }; + final Future> result = runCapturingPrint( + runner, ['version-check', '--base_sha=master']); + + await expectLater( + result, + throwsA(const TypeMatcher()), + ); + expect(gitDirCommands.length, equals(3)); + expect( + gitDirCommands[0].join(' '), equals('diff --name-only master HEAD')); + expect(gitDirCommands[1].join(' '), + equals('show master:packages/plugin/pubspec.yaml')); + expect(gitDirCommands[2].join(' '), + equals('show HEAD:packages/plugin/pubspec.yaml')); + }); + + test('gracefully handles missing pubspec.yaml', () async { + createFakePlugin('plugin'); + gitDiffResponse = "packages/plugin/pubspec.yaml"; + mockFileSystem.currentDirectory + .childDirectory('packages') + .childDirectory('plugin') + .childFile('pubspec.yaml') + .deleteSync(); + final List output = await runCapturingPrint( + runner, ['version-check', '--base_sha=master']); + + expect( + output, + orderedEquals([ + 'No version check errors found!', + ]), + ); + expect(gitDirCommands.length, equals(1)); + expect(gitDirCommands.first.join(' '), + equals('diff --name-only master HEAD')); + }); + + test('allows minor changes to platform interfaces', () async { + createFakePlugin('plugin_platform_interface'); + gitDiffResponse = "packages/plugin_platform_interface/pubspec.yaml"; + gitShowResponses = { + 'master:packages/plugin_platform_interface/pubspec.yaml': + 'version: 1.0.0', + 'HEAD:packages/plugin_platform_interface/pubspec.yaml': + 'version: 1.1.0', + }; + final List output = await runCapturingPrint( + runner, ['version-check', '--base_sha=master']); + expect( + output, + orderedEquals([ + 'No version check errors found!', + ]), + ); + expect(gitDirCommands.length, equals(3)); + expect( + gitDirCommands[0].join(' '), equals('diff --name-only master HEAD')); + expect( + gitDirCommands[1].join(' '), + equals( + 'show master:packages/plugin_platform_interface/pubspec.yaml')); + expect(gitDirCommands[2].join(' '), + equals('show HEAD:packages/plugin_platform_interface/pubspec.yaml')); + }); + + test('disallows breaking changes to platform interfaces', () async { + createFakePlugin('plugin_platform_interface'); + gitDiffResponse = "packages/plugin_platform_interface/pubspec.yaml"; + gitShowResponses = { + 'master:packages/plugin_platform_interface/pubspec.yaml': + 'version: 1.0.0', + 'HEAD:packages/plugin_platform_interface/pubspec.yaml': + 'version: 2.0.0', + }; + final Future> output = runCapturingPrint( + runner, ['version-check', '--base_sha=master']); + await expectLater( + output, + throwsA(const TypeMatcher()), + ); + expect(gitDirCommands.length, equals(3)); + expect( + gitDirCommands[0].join(' '), equals('diff --name-only master HEAD')); + expect( + gitDirCommands[1].join(' '), + equals( + 'show master:packages/plugin_platform_interface/pubspec.yaml')); + expect(gitDirCommands[2].join(' '), + equals('show HEAD:packages/plugin_platform_interface/pubspec.yaml')); + }); + }); + + group("Pre 1.0", () { + test("nextVersion allows patch version", () { + testAllowedVersion("0.12.0", "0.12.0+1", + nextVersionType: NextVersionType.PATCH); + testAllowedVersion("0.12.0+4", "0.12.0+5", + nextVersionType: NextVersionType.PATCH); + }); + + test("nextVersion does not allow jumping patch", () { + testAllowedVersion("0.12.0", "0.12.0+2", allowed: false); + testAllowedVersion("0.12.0+2", "0.12.0+4", allowed: false); + }); + + test("nextVersion does not allow going back", () { + testAllowedVersion("0.12.0", "0.11.0", allowed: false); + testAllowedVersion("0.12.0+2", "0.12.0+1", allowed: false); + testAllowedVersion("0.12.0+1", "0.12.0", allowed: false); + }); + + test("nextVersion allows minor version", () { + testAllowedVersion("0.12.0", "0.12.1", + nextVersionType: NextVersionType.MINOR); + testAllowedVersion("0.12.0+4", "0.12.1", + nextVersionType: NextVersionType.MINOR); + }); + + test("nextVersion does not allow jumping minor", () { + testAllowedVersion("0.12.0", "0.12.2", allowed: false); + testAllowedVersion("0.12.0+2", "0.12.3", allowed: false); + }); + }); + + group("Releasing 1.0", () { + test("nextVersion allows releasing 1.0", () { + testAllowedVersion("0.12.0", "1.0.0", + nextVersionType: NextVersionType.BREAKING_MAJOR); + testAllowedVersion("0.12.0+4", "1.0.0", + nextVersionType: NextVersionType.BREAKING_MAJOR); + }); + + test("nextVersion does not allow jumping major", () { + testAllowedVersion("0.12.0", "2.0.0", allowed: false); + testAllowedVersion("0.12.0+4", "2.0.0", allowed: false); + }); + + test("nextVersion does not allow un-releasing", () { + testAllowedVersion("1.0.0", "0.12.0+4", allowed: false); + testAllowedVersion("1.0.0", "0.12.0", allowed: false); + }); + }); + + group("Post 1.0", () { + test("nextVersion allows patch jumps", () { + testAllowedVersion("1.0.1", "1.0.2", + nextVersionType: NextVersionType.PATCH); + testAllowedVersion("1.0.0", "1.0.1", + nextVersionType: NextVersionType.PATCH); + }); + + test("nextVersion does not allow build jumps", () { + testAllowedVersion("1.0.1", "1.0.1+1", allowed: false); + testAllowedVersion("1.0.0+5", "1.0.0+6", allowed: false); + }); + + test("nextVersion does not allow skipping patches", () { + testAllowedVersion("1.0.1", "1.0.3", allowed: false); + testAllowedVersion("1.0.0", "1.0.6", allowed: false); + }); + + test("nextVersion allows minor version jumps", () { + testAllowedVersion("1.0.1", "1.1.0", + nextVersionType: NextVersionType.MINOR); + testAllowedVersion("1.0.0", "1.1.0", + nextVersionType: NextVersionType.MINOR); + }); + + test("nextVersion does not allow skipping minor versions", () { + testAllowedVersion("1.0.1", "1.2.0", allowed: false); + testAllowedVersion("1.1.0", "1.3.0", allowed: false); + }); + + test("nextVersion allows breaking changes", () { + testAllowedVersion("1.0.1", "2.0.0", + nextVersionType: NextVersionType.BREAKING_MAJOR); + testAllowedVersion("1.0.0", "2.0.0", + nextVersionType: NextVersionType.BREAKING_MAJOR); + }); + + test("nextVersion allows null safety pre prelease", () { + testAllowedVersion("1.0.1", "2.0.0-nullsafety", + nextVersionType: NextVersionType.MAJOR_NULLSAFETY_PRE_RELEASE); + testAllowedVersion("1.0.0", "2.0.0-nullsafety", + nextVersionType: NextVersionType.MAJOR_NULLSAFETY_PRE_RELEASE); + testAllowedVersion("1.0.0-nullsafety", "1.0.0-nullsafety.1", + nextVersionType: NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE); + testAllowedVersion("1.0.0-nullsafety.1", "1.0.0-nullsafety.2", + nextVersionType: NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE); + testAllowedVersion("0.1.0", "0.2.0-nullsafety", + nextVersionType: NextVersionType.MAJOR_NULLSAFETY_PRE_RELEASE); + testAllowedVersion("0.1.0-nullsafety", "0.1.0-nullsafety.1", + nextVersionType: NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE); + testAllowedVersion("0.1.0-nullsafety.1", "0.1.0-nullsafety.2", + nextVersionType: NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE); + testAllowedVersion("1.0.0", "1.1.0-nullsafety", + nextVersionType: NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE); + testAllowedVersion("1.1.0-nullsafety", "1.1.0-nullsafety.1", + nextVersionType: NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE); + testAllowedVersion("0.1.0", "0.1.1-nullsafety", + nextVersionType: NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE); + testAllowedVersion("0.1.1-nullsafety", "0.1.1-nullsafety.1", + nextVersionType: NextVersionType.MINOR_NULLSAFETY_PRE_RELEASE); + }); + + test("nextVersion does not allow skipping major versions", () { + testAllowedVersion("1.0.1", "3.0.0", allowed: false); + testAllowedVersion("1.1.0", "2.3.0", allowed: false); + }); + }); +} diff --git a/script/tool/test/xctest_command_test.dart b/script/tool/test/xctest_command_test.dart new file mode 100644 index 000000000000..007c2e12188c --- /dev/null +++ b/script/tool/test/xctest_command_test.dart @@ -0,0 +1,358 @@ +// 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. + +import 'dart:convert'; + +import 'package:args/command_runner.dart'; +import 'package:file/file.dart'; +import 'package:flutter_plugin_tools/src/xctest_command.dart'; +import 'package:test/test.dart'; +import 'package:flutter_plugin_tools/src/common.dart'; + +import 'mocks.dart'; +import 'util.dart'; + +final _kDeviceListMap = { + "runtimes": [ + { + "bundlePath": + "/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.0.simruntime", + "buildversion": "17A577", + "runtimeRoot": + "/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.0.simruntime/Contents/Resources/RuntimeRoot", + "identifier": "com.apple.CoreSimulator.SimRuntime.iOS-13-0", + "version": "13.0", + "isAvailable": true, + "name": "iOS 13.0" + }, + { + "bundlePath": + "/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.4.simruntime", + "buildversion": "17L255", + "runtimeRoot": + "/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.4.simruntime/Contents/Resources/RuntimeRoot", + "identifier": "com.apple.CoreSimulator.SimRuntime.iOS-13-4", + "version": "13.4", + "isAvailable": true, + "name": "iOS 13.4" + }, + { + "bundlePath": + "/Applications/Xcode_11_7.app/Contents/Developer/Platforms/WatchOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/watchOS.simruntime", + "buildversion": "17T531", + "runtimeRoot": + "/Applications/Xcode_11_7.app/Contents/Developer/Platforms/WatchOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/watchOS.simruntime/Contents/Resources/RuntimeRoot", + "identifier": "com.apple.CoreSimulator.SimRuntime.watchOS-6-2", + "version": "6.2.1", + "isAvailable": true, + "name": "watchOS 6.2" + } + ], + "devices": { + "com.apple.CoreSimulator.SimRuntime.iOS-13-4": [ + { + "dataPath": + "/Users/xxx/Library/Developer/CoreSimulator/Devices/2706BBEB-1E01-403E-A8E9-70E8E5A24774/data", + "logPath": + "/Users/xxx/Library/Logs/CoreSimulator/2706BBEB-1E01-403E-A8E9-70E8E5A24774", + "udid": "2706BBEB-1E01-403E-A8E9-70E8E5A24774", + "isAvailable": true, + "deviceTypeIdentifier": + "com.apple.CoreSimulator.SimDeviceType.iPhone-8", + "state": "Shutdown", + "name": "iPhone 8" + }, + { + "dataPath": + "/Users/xxx/Library/Developer/CoreSimulator/Devices/1E76A0FD-38AC-4537-A989-EA639D7D012A/data", + "logPath": + "/Users/xxx/Library/Logs/CoreSimulator/1E76A0FD-38AC-4537-A989-EA639D7D012A", + "udid": "1E76A0FD-38AC-4537-A989-EA639D7D012A", + "isAvailable": true, + "deviceTypeIdentifier": + "com.apple.CoreSimulator.SimDeviceType.iPhone-8-Plus", + "state": "Shutdown", + "name": "iPhone 8 Plus" + } + ] + } +}; + +void main() { + const String _kDestination = '--ios-destination'; + const String _kTarget = '--target'; + const String _kSkip = '--skip'; + + group('test xctest_command', () { + CommandRunner runner; + RecordingProcessRunner processRunner; + + setUp(() { + initializeFakePackages(); + processRunner = RecordingProcessRunner(); + final XCTestCommand command = XCTestCommand( + mockPackagesDir, mockFileSystem, + processRunner: processRunner); + + runner = CommandRunner('xctest_command', 'Test for xctest_command'); + runner.addCommand(command); + cleanupPackages(); + }); + + test('Not specifying --target throws', () async { + await expectLater( + () => runner.run(['xctest', _kDestination, 'a_destination']), + throwsA(const TypeMatcher())); + }); + + test('skip if ios is not supported', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test'], + ], + isIosPlugin: false); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final MockProcess mockProcess = MockProcess(); + mockProcess.exitCodeCompleter.complete(0); + processRunner.processToReturn = mockProcess; + final List output = await runCapturingPrint(runner, [ + 'xctest', + _kTarget, + 'foo_scheme', + _kDestination, + 'foo_destination' + ]); + expect(output, contains('iOS is not supported by this plugin.')); + expect(processRunner.recordedCalls, orderedEquals([])); + + cleanupPackages(); + }); + + test('running with correct scheme and destination, did not find scheme', + () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test'], + ], + isIosPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final MockProcess mockProcess = MockProcess(); + mockProcess.exitCodeCompleter.complete(0); + processRunner.processToReturn = mockProcess; + processRunner.resultStdout = '{"project":{"targets":["bar_scheme"]}}'; + + await expectLater(() async { + final List output = await runCapturingPrint(runner, [ + 'xctest', + _kTarget, + 'foo_scheme', + _kDestination, + 'foo_destination' + ]); + expect(output, + contains('foo_scheme not configured for plugin, test failed.')); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall('xcrun', ['simctl', 'list', '--json'], null), + ProcessCall( + 'xcodebuild', + [ + '-project', + 'ios/Runner.xcodeproj', + '-list', + '-json' + ], + pluginExampleDirectory.path), + ])); + }, throwsA(const TypeMatcher())); + cleanupPackages(); + }); + + test('running with correct scheme and destination, found scheme', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test'], + ], + isIosPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final MockProcess mockProcess = MockProcess(); + mockProcess.exitCodeCompleter.complete(0); + processRunner.processToReturn = mockProcess; + processRunner.resultStdout = + '{"project":{"targets":["bar_scheme", "foo_scheme"]}}'; + List output = await runCapturingPrint(runner, [ + 'xctest', + _kTarget, + 'foo_scheme', + _kDestination, + 'foo_destination' + ]); + + expect(output, contains('Successfully ran xctest for plugin')); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + 'xcodebuild', + ['-project', 'ios/Runner.xcodeproj', '-list', '-json'], + pluginExampleDirectory.path), + ProcessCall( + 'xcodebuild', + [ + 'test', + '-workspace', + 'ios/Runner.xcworkspace', + '-scheme', + 'foo_scheme', + '-destination', + 'foo_destination', + 'CODE_SIGN_IDENTITY=""', + 'CODE_SIGNING_REQUIRED=NO' + ], + pluginExampleDirectory.path), + ])); + + cleanupPackages(); + }); + + test('running with correct scheme and destination, skip 1 plugin', + () async { + createFakePlugin('plugin1', + withExtraFiles: >[ + ['example', 'test'], + ], + isIosPlugin: true); + createFakePlugin('plugin2', + withExtraFiles: >[ + ['example', 'test'], + ], + isIosPlugin: true); + + final Directory pluginExampleDirectory1 = + mockPackagesDir.childDirectory('plugin1').childDirectory('example'); + createFakePubspec(pluginExampleDirectory1, isFlutter: true); + final Directory pluginExampleDirectory2 = + mockPackagesDir.childDirectory('plugin2').childDirectory('example'); + createFakePubspec(pluginExampleDirectory2, isFlutter: true); + + final MockProcess mockProcess = MockProcess(); + mockProcess.exitCodeCompleter.complete(0); + processRunner.processToReturn = mockProcess; + processRunner.resultStdout = + '{"project":{"targets":["bar_scheme", "foo_scheme"]}}'; + List output = await runCapturingPrint(runner, [ + 'xctest', + _kTarget, + 'foo_scheme', + _kDestination, + 'foo_destination', + _kSkip, + 'plugin1' + ]); + + expect(output, contains('plugin1 was skipped with the --skip flag.')); + expect(output, contains('Successfully ran xctest for plugin2')); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + 'xcodebuild', + ['-project', 'ios/Runner.xcodeproj', '-list', '-json'], + pluginExampleDirectory2.path), + ProcessCall( + 'xcodebuild', + [ + 'test', + '-workspace', + 'ios/Runner.xcworkspace', + '-scheme', + 'foo_scheme', + '-destination', + 'foo_destination', + 'CODE_SIGN_IDENTITY=""', + 'CODE_SIGNING_REQUIRED=NO' + ], + pluginExampleDirectory2.path), + ])); + + cleanupPackages(); + }); + + test('Not specifying --ios-destination assigns an available simulator', + () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test'], + ], + isIosPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final MockProcess mockProcess = MockProcess(); + mockProcess.exitCodeCompleter.complete(0); + processRunner.processToReturn = mockProcess; + final Map schemeCommandResult = { + "project": { + "targets": ["bar_scheme", "foo_scheme"] + } + }; + // For simplicity of the test, we combine all the mock results into a single mock result, each internal command + // will get this result and they should still be able to parse them correctly. + processRunner.resultStdout = + jsonEncode(schemeCommandResult..addAll(_kDeviceListMap)); + await runner.run([ + 'xctest', + _kTarget, + 'foo_scheme', + ]); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall('xcrun', ['simctl', 'list', '--json'], null), + ProcessCall( + 'xcodebuild', + ['-project', 'ios/Runner.xcodeproj', '-list', '-json'], + pluginExampleDirectory.path), + ProcessCall( + 'xcodebuild', + [ + 'test', + '-workspace', + 'ios/Runner.xcworkspace', + '-scheme', + 'foo_scheme', + '-destination', + 'id=1E76A0FD-38AC-4537-A989-EA639D7D012A', + 'CODE_SIGN_IDENTITY=""', + 'CODE_SIGNING_REQUIRED=NO' + ], + pluginExampleDirectory.path), + ])); + + cleanupPackages(); + }); + }); +} From 976a7fbc3de77b8fd16e7bffbb3c6f2c13ba8b95 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 1 Mar 2021 19:24:10 -0800 Subject: [PATCH 0233/1565] [in_app_purchase] fix plugin version (#3654) --- packages/in_app_purchase/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/in_app_purchase/pubspec.yaml b/packages/in_app_purchase/pubspec.yaml index 6175e8cbf1dc..3d121fd51e5e 100644 --- a/packages/in_app_purchase/pubspec.yaml +++ b/packages/in_app_purchase/pubspec.yaml @@ -1,7 +1,7 @@ name: in_app_purchase description: A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases through the App Store and Google Play. homepage: https://github.com/flutter/plugins/tree/master/packages/in_app_purchase -version: 0.4.1 +version: 0.5.0 dependencies: flutter: From a6cbf671e3463953b7ade113537cbe043dec4a0e Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Tue, 2 Mar 2021 15:11:31 +0100 Subject: [PATCH 0234/1565] [camera] Stable release for null safety. (#3641) Stable NNBD release for the camera package. With this PR I also migrated the example App to sound null safe. --- packages/camera/camera/CHANGELOG.md | 15 +- .../example/integration_test/camera_test.dart | 7 + packages/camera/camera/example/lib/main.dart | 282 +++++++++++------- packages/camera/camera/example/pubspec.yaml | 14 +- .../example/test_driver/integration_test.dart | 7 + packages/camera/camera/pubspec.yaml | 19 +- 6 files changed, 212 insertions(+), 132 deletions(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 079aa1685bd5..f1d771496dde 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,18 +1,9 @@ -## 0.8.0-nullsafety.3 - -* Updates the example code listed in the [README.md](README.md), so it runs without errors when you simply copy/ paste it into a Flutter App. - -## 0.8.0-nullsafety.2 +## 0.8.0 +* Stable null safety release. * Solved delay when using the zoom feature on iOS. - -## 0.8.0-nullsafety.1 - * Added a timeout to the pre-capture sequence on Android to prevent crashes when the camera cannot get a focus. - -## 0.8.0-nullsafety - -* Migrated to null safety. +* Updates the example code listed in the [README.md](README.md), so it runs without errors when you simply copy/ paste it into a Flutter App. ## 0.7.0+4 diff --git a/packages/camera/camera/example/integration_test/camera_test.dart b/packages/camera/camera/example/integration_test/camera_test.dart index c2e73e0f1563..4ff624c7d989 100644 --- a/packages/camera/camera/example/integration_test/camera_test.dart +++ b/packages/camera/camera/example/integration_test/camera_test.dart @@ -1,3 +1,10 @@ +// 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. + +// TODO(mvanbeusekom): Remove this once flutter_driver supports null safety. +// https://github.com/flutter/flutter/issues/71379 +// @dart = 2.9 import 'dart:async'; import 'dart:io'; import 'dart:ui'; diff --git a/packages/camera/camera/example/lib/main.dart b/packages/camera/camera/example/lib/main.dart index 6244aa5a8e37..5eebc9a379ca 100644 --- a/packages/camera/camera/example/lib/main.dart +++ b/packages/camera/camera/example/lib/main.dart @@ -27,32 +27,38 @@ IconData getCameraLensIcon(CameraLensDirection direction) { return Icons.camera_front; case CameraLensDirection.external: return Icons.camera; + default: + throw ArgumentError('Unknown lens direction'); } - throw ArgumentError('Unknown lens direction'); } -void logError(String code, String message) => +void logError(String code, String? message) { + if (message != null) { print('Error: $code\nError Message: $message'); + } else { + print('Error: $code'); + } +} class _CameraExampleHomeState extends State with WidgetsBindingObserver, TickerProviderStateMixin { - CameraController controller; - XFile imageFile; - XFile videoFile; - VideoPlayerController videoController; - VoidCallback videoPlayerListener; + CameraController? controller; + XFile? imageFile; + XFile? videoFile; + VideoPlayerController? videoController; + VoidCallback? videoPlayerListener; bool enableAudio = true; double _minAvailableExposureOffset = 0.0; double _maxAvailableExposureOffset = 0.0; double _currentExposureOffset = 0.0; - AnimationController _flashModeControlRowAnimationController; - Animation _flashModeControlRowAnimation; - AnimationController _exposureModeControlRowAnimationController; - Animation _exposureModeControlRowAnimation; - AnimationController _focusModeControlRowAnimationController; - Animation _focusModeControlRowAnimation; - double _minAvailableZoom; - double _maxAvailableZoom; + late AnimationController _flashModeControlRowAnimationController; + late Animation _flashModeControlRowAnimation; + late AnimationController _exposureModeControlRowAnimationController; + late Animation _exposureModeControlRowAnimation; + late AnimationController _focusModeControlRowAnimationController; + late Animation _focusModeControlRowAnimation; + double _minAvailableZoom = 1.0; + double _maxAvailableZoom = 1.0; double _currentScale = 1.0; double _baseScale = 1.0; @@ -62,7 +68,8 @@ class _CameraExampleHomeState extends State @override void initState() { super.initState(); - WidgetsBinding.instance.addObserver(this); + WidgetsBinding.instance?.addObserver(this); + _flashModeControlRowAnimationController = AnimationController( duration: const Duration(milliseconds: 300), vsync: this, @@ -91,7 +98,7 @@ class _CameraExampleHomeState extends State @override void dispose() { - WidgetsBinding.instance.removeObserver(this); + WidgetsBinding.instance?.removeObserver(this); _flashModeControlRowAnimationController.dispose(); _exposureModeControlRowAnimationController.dispose(); super.dispose(); @@ -99,16 +106,17 @@ class _CameraExampleHomeState extends State @override void didChangeAppLifecycleState(AppLifecycleState state) { + final CameraController? cameraController = controller; + // App state changed before we got the chance to initialize. - if (controller == null || !controller.value.isInitialized) { + if (cameraController == null || !cameraController.value.isInitialized) { return; } + if (state == AppLifecycleState.inactive) { - controller?.dispose(); + cameraController.dispose(); } else if (state == AppLifecycleState.resumed) { - if (controller != null) { - onNewCameraSelected(controller.description); - } + onNewCameraSelected(cameraController.description); } } @@ -134,9 +142,10 @@ class _CameraExampleHomeState extends State decoration: BoxDecoration( color: Colors.black, border: Border.all( - color: controller != null && controller.value.isRecordingVideo - ? Colors.redAccent - : Colors.grey, + color: + controller != null && controller!.value.isRecordingVideo + ? Colors.redAccent + : Colors.grey, width: 3.0, ), ), @@ -161,7 +170,9 @@ class _CameraExampleHomeState extends State /// Display the preview from the camera (or a message if the preview is not available). Widget _cameraPreviewWidget() { - if (controller == null || !controller.value.isInitialized) { + final CameraController? cameraController = controller; + + if (cameraController == null || !cameraController.value.isInitialized) { return const Text( 'Tap a camera', style: TextStyle( @@ -175,7 +186,7 @@ class _CameraExampleHomeState extends State onPointerDown: (_) => _pointers++, onPointerUp: (_) => _pointers--, child: CameraPreview( - controller, + controller!, child: LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { return GestureDetector( @@ -196,37 +207,40 @@ class _CameraExampleHomeState extends State Future _handleScaleUpdate(ScaleUpdateDetails details) async { // When there are not exactly two fingers on screen don't scale - if (_pointers != 2) { + if (controller == null || _pointers != 2) { return; } _currentScale = (_baseScale * details.scale) .clamp(_minAvailableZoom, _maxAvailableZoom); - await controller.setZoomLevel(_currentScale); + await controller!.setZoomLevel(_currentScale); } /// Display the thumbnail of the captured image or video. Widget _thumbnailWidget() { + final VideoPlayerController? localVideoController = videoController; + return Expanded( child: Align( alignment: Alignment.centerRight, child: Row( mainAxisSize: MainAxisSize.min, children: [ - videoController == null && imageFile == null + localVideoController == null && imageFile == null ? Container() : SizedBox( - child: (videoController == null) - ? Image.file(File(imageFile.path)) + child: (localVideoController == null) + ? Image.file(File(imageFile!.path)) : Container( child: Center( child: AspectRatio( aspectRatio: - videoController.value.size != null - ? videoController.value.aspectRatio + localVideoController.value.size != null + ? localVideoController + .value.aspectRatio : 1.0, - child: VideoPlayer(videoController)), + child: VideoPlayer(localVideoController)), ), decoration: BoxDecoration( border: Border.all(color: Colors.pink)), @@ -270,7 +284,7 @@ class _CameraExampleHomeState extends State onPressed: controller != null ? onAudioModeButtonPressed : null, ), IconButton( - icon: Icon(controller?.value?.isCaptureOrientationLocked ?? false + icon: Icon(controller?.value.isCaptureOrientationLocked ?? false ? Icons.screen_lock_rotation : Icons.screen_rotation), color: Colors.blue, @@ -297,7 +311,7 @@ class _CameraExampleHomeState extends State children: [ IconButton( icon: Icon(Icons.flash_off), - color: controller?.value?.flashMode == FlashMode.off + color: controller?.value.flashMode == FlashMode.off ? Colors.orange : Colors.blue, onPressed: controller != null @@ -306,7 +320,7 @@ class _CameraExampleHomeState extends State ), IconButton( icon: Icon(Icons.flash_auto), - color: controller?.value?.flashMode == FlashMode.auto + color: controller?.value.flashMode == FlashMode.auto ? Colors.orange : Colors.blue, onPressed: controller != null @@ -315,7 +329,7 @@ class _CameraExampleHomeState extends State ), IconButton( icon: Icon(Icons.flash_on), - color: controller?.value?.flashMode == FlashMode.always + color: controller?.value.flashMode == FlashMode.always ? Colors.orange : Colors.blue, onPressed: controller != null @@ -324,7 +338,7 @@ class _CameraExampleHomeState extends State ), IconButton( icon: Icon(Icons.highlight), - color: controller?.value?.flashMode == FlashMode.torch + color: controller?.value.flashMode == FlashMode.torch ? Colors.orange : Colors.blue, onPressed: controller != null @@ -339,12 +353,12 @@ class _CameraExampleHomeState extends State Widget _exposureModeControlRowWidget() { final ButtonStyle styleAuto = TextButton.styleFrom( - primary: controller?.value?.exposureMode == ExposureMode.auto + primary: controller?.value.exposureMode == ExposureMode.auto ? Colors.orange : Colors.blue, ); final ButtonStyle styleLocked = TextButton.styleFrom( - primary: controller?.value?.exposureMode == ExposureMode.locked + primary: controller?.value.exposureMode == ExposureMode.locked ? Colors.orange : Colors.blue, ); @@ -371,8 +385,10 @@ class _CameraExampleHomeState extends State onSetExposureModeButtonPressed(ExposureMode.auto) : null, onLongPress: () { - if (controller != null) controller.setExposurePoint(null); - showInSnackBar('Resetting exposure point'); + if (controller != null) { + controller!.setExposurePoint(null); + showInSnackBar('Resetting exposure point'); + } }, ), TextButton( @@ -415,12 +431,12 @@ class _CameraExampleHomeState extends State Widget _focusModeControlRowWidget() { final ButtonStyle styleAuto = TextButton.styleFrom( - primary: controller?.value?.focusMode == FocusMode.auto + primary: controller?.value.focusMode == FocusMode.auto ? Colors.orange : Colors.blue, ); final ButtonStyle styleLocked = TextButton.styleFrom( - primary: controller?.value?.focusMode == FocusMode.locked + primary: controller?.value.focusMode == FocusMode.locked ? Colors.orange : Colors.blue, ); @@ -446,7 +462,7 @@ class _CameraExampleHomeState extends State ? () => onSetFocusModeButtonPressed(FocusMode.auto) : null, onLongPress: () { - if (controller != null) controller.setFocusPoint(null); + if (controller != null) controller!.setFocusPoint(null); showInSnackBar('Resetting focus point'); }, ), @@ -468,6 +484,8 @@ class _CameraExampleHomeState extends State /// Display the control bar with buttons to take pictures and record videos. Widget _captureControlRowWidget() { + final CameraController? cameraController = controller; + return Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisSize: MainAxisSize.max, @@ -475,40 +493,41 @@ class _CameraExampleHomeState extends State IconButton( icon: const Icon(Icons.camera_alt), color: Colors.blue, - onPressed: controller != null && - controller.value.isInitialized && - !controller.value.isRecordingVideo + onPressed: cameraController != null && + cameraController.value.isInitialized && + !cameraController.value.isRecordingVideo ? onTakePictureButtonPressed : null, ), IconButton( icon: const Icon(Icons.videocam), color: Colors.blue, - onPressed: controller != null && - controller.value.isInitialized && - !controller.value.isRecordingVideo + onPressed: cameraController != null && + cameraController.value.isInitialized && + !cameraController.value.isRecordingVideo ? onVideoRecordButtonPressed : null, ), IconButton( - icon: controller != null && controller.value.isRecordingPaused + icon: cameraController != null && + cameraController.value.isRecordingPaused ? Icon(Icons.play_arrow) : Icon(Icons.pause), color: Colors.blue, - onPressed: controller != null && - controller.value.isInitialized && - controller.value.isRecordingVideo - ? (controller != null && controller.value.isRecordingPaused + onPressed: cameraController != null && + cameraController.value.isInitialized && + cameraController.value.isRecordingVideo + ? (cameraController.value.isRecordingPaused) ? onResumeButtonPressed - : onPauseButtonPressed) + : onPauseButtonPressed : null, ), IconButton( icon: const Icon(Icons.stop), color: Colors.red, - onPressed: controller != null && - controller.value.isInitialized && - controller.value.isRecordingVideo + onPressed: cameraController != null && + cameraController.value.isInitialized && + cameraController.value.isRecordingVideo ? onStopButtonPressed : null, ) @@ -520,6 +539,14 @@ class _CameraExampleHomeState extends State Widget _cameraTogglesRowWidget() { final List toggles = []; + final onChanged = (CameraDescription? description) { + if (description == null) { + return; + } + + onNewCameraSelected(description); + }; + if (cameras.isEmpty) { return const Text('No camera found'); } else { @@ -531,9 +558,10 @@ class _CameraExampleHomeState extends State title: Icon(getCameraLensIcon(cameraDescription.lensDirection)), groupValue: controller?.description, value: cameraDescription, - onChanged: controller != null && controller.value.isRecordingVideo - ? null - : onNewCameraSelected, + onChanged: + controller != null && controller!.value.isRecordingVideo + ? null + : onChanged, ), ), ); @@ -547,48 +575,60 @@ class _CameraExampleHomeState extends State void showInSnackBar(String message) { // ignore: deprecated_member_use - _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text(message))); + _scaffoldKey.currentState?.showSnackBar(SnackBar(content: Text(message))); } void onViewFinderTap(TapDownDetails details, BoxConstraints constraints) { + if (controller == null) { + return; + } + + final CameraController cameraController = controller!; + final offset = Offset( details.localPosition.dx / constraints.maxWidth, details.localPosition.dy / constraints.maxHeight, ); - controller.setExposurePoint(offset); - controller.setFocusPoint(offset); + cameraController.setExposurePoint(offset); + cameraController.setFocusPoint(offset); } void onNewCameraSelected(CameraDescription cameraDescription) async { if (controller != null) { - await controller.dispose(); + await controller!.dispose(); } - controller = CameraController( + final CameraController cameraController = CameraController( cameraDescription, ResolutionPreset.medium, enableAudio: enableAudio, imageFormatGroup: ImageFormatGroup.jpeg, ); + controller = cameraController; // If the controller is updated then update the UI. - controller.addListener(() { + cameraController.addListener(() { if (mounted) setState(() {}); - if (controller.value.hasError) { - showInSnackBar('Camera error ${controller.value.errorDescription}'); + if (cameraController.value.hasError) { + showInSnackBar( + 'Camera error ${cameraController.value.errorDescription}'); } }); try { - await controller.initialize(); + await cameraController.initialize(); await Future.wait([ - controller + cameraController .getMinExposureOffset() .then((value) => _minAvailableExposureOffset = value), - controller + cameraController .getMaxExposureOffset() .then((value) => _maxAvailableExposureOffset = value), - controller.getMaxZoomLevel().then((value) => _maxAvailableZoom = value), - controller.getMinZoomLevel().then((value) => _minAvailableZoom = value), + cameraController + .getMaxZoomLevel() + .then((value) => _maxAvailableZoom = value), + cameraController + .getMinZoomLevel() + .then((value) => _minAvailableZoom = value), ]); } on CameraException catch (e) { _showCameraException(e); @@ -600,7 +640,7 @@ class _CameraExampleHomeState extends State } void onTakePictureButtonPressed() { - takePicture().then((XFile file) { + takePicture().then((XFile? file) { if (mounted) { setState(() { imageFile = file; @@ -645,19 +685,20 @@ class _CameraExampleHomeState extends State void onAudioModeButtonPressed() { enableAudio = !enableAudio; if (controller != null) { - onNewCameraSelected(controller.description); + onNewCameraSelected(controller!.description); } } void onCaptureOrientationLockButtonPressed() async { if (controller != null) { - if (controller.value.isCaptureOrientationLocked) { - await controller.unlockCaptureOrientation(); + final CameraController cameraController = controller!; + if (cameraController.value.isCaptureOrientationLocked) { + await cameraController.unlockCaptureOrientation(); showInSnackBar('Capture orientation unlocked'); } else { - await controller.lockCaptureOrientation(); + await cameraController.lockCaptureOrientation(); showInSnackBar( - 'Capture orientation locked to ${controller.value.lockedCaptureOrientation.toString().split('.').last}'); + 'Capture orientation locked to ${cameraController.value.lockedCaptureOrientation.toString().split('.').last}'); } } } @@ -715,31 +756,35 @@ class _CameraExampleHomeState extends State } Future startVideoRecording() async { - if (!controller.value.isInitialized) { + final CameraController? cameraController = controller; + + if (cameraController == null || !cameraController.value.isInitialized) { showInSnackBar('Error: select a camera first.'); return; } - if (controller.value.isRecordingVideo) { + if (cameraController.value.isRecordingVideo) { // A recording is already started, do nothing. return; } try { - await controller.startVideoRecording(); + await cameraController.startVideoRecording(); } on CameraException catch (e) { _showCameraException(e); return; } } - Future stopVideoRecording() async { - if (!controller.value.isRecordingVideo) { + Future stopVideoRecording() async { + final CameraController? cameraController = controller; + + if (cameraController == null || !cameraController.value.isRecordingVideo) { return null; } try { - return controller.stopVideoRecording(); + return cameraController.stopVideoRecording(); } on CameraException catch (e) { _showCameraException(e); return null; @@ -747,12 +792,14 @@ class _CameraExampleHomeState extends State } Future pauseVideoRecording() async { - if (!controller.value.isRecordingVideo) { + final CameraController? cameraController = controller; + + if (cameraController == null || !cameraController.value.isRecordingVideo) { return null; } try { - await controller.pauseVideoRecording(); + await cameraController.pauseVideoRecording(); } on CameraException catch (e) { _showCameraException(e); rethrow; @@ -760,12 +807,14 @@ class _CameraExampleHomeState extends State } Future resumeVideoRecording() async { - if (!controller.value.isRecordingVideo) { + final CameraController? cameraController = controller; + + if (cameraController == null || !cameraController.value.isRecordingVideo) { return null; } try { - await controller.resumeVideoRecording(); + await cameraController.resumeVideoRecording(); } on CameraException catch (e) { _showCameraException(e); rethrow; @@ -773,8 +822,12 @@ class _CameraExampleHomeState extends State } Future setFlashMode(FlashMode mode) async { + if (controller == null) { + return; + } + try { - await controller.setFlashMode(mode); + await controller!.setFlashMode(mode); } on CameraException catch (e) { _showCameraException(e); rethrow; @@ -782,8 +835,12 @@ class _CameraExampleHomeState extends State } Future setExposureMode(ExposureMode mode) async { + if (controller == null) { + return; + } + try { - await controller.setExposureMode(mode); + await controller!.setExposureMode(mode); } on CameraException catch (e) { _showCameraException(e); rethrow; @@ -791,11 +848,15 @@ class _CameraExampleHomeState extends State } Future setExposureOffset(double offset) async { + if (controller == null) { + return; + } + setState(() { _currentExposureOffset = offset; }); try { - offset = await controller.setExposureOffset(offset); + offset = await controller!.setExposureOffset(offset); } on CameraException catch (e) { _showCameraException(e); rethrow; @@ -803,8 +864,12 @@ class _CameraExampleHomeState extends State } Future setFocusMode(FocusMode mode) async { + if (controller == null) { + return; + } + try { - await controller.setFocusMode(mode); + await controller!.setFocusMode(mode); } on CameraException catch (e) { _showCameraException(e); rethrow; @@ -812,16 +877,20 @@ class _CameraExampleHomeState extends State } Future _startVideoPlayer() async { + if (videoFile == null) { + return; + } + final VideoPlayerController vController = - VideoPlayerController.file(File(videoFile.path)); + VideoPlayerController.file(File(videoFile!.path)); videoPlayerListener = () { - if (videoController != null && videoController.value.size != null) { + if (videoController != null && videoController!.value.size != null) { // Refreshing the state to update video player with the correct ratio. if (mounted) setState(() {}); - videoController.removeListener(videoPlayerListener); + videoController!.removeListener(videoPlayerListener!); } }; - vController.addListener(videoPlayerListener); + vController.addListener(videoPlayerListener!); await vController.setLooping(true); await vController.initialize(); await videoController?.dispose(); @@ -834,19 +903,20 @@ class _CameraExampleHomeState extends State await vController.play(); } - Future takePicture() async { - if (!controller.value.isInitialized) { + Future takePicture() async { + final CameraController? cameraController = controller; + if (cameraController == null || !cameraController.value.isInitialized) { showInSnackBar('Error: select a camera first.'); return null; } - if (controller.value.isTakingPicture) { + if (cameraController.value.isTakingPicture) { // A capture is already pending, do nothing. return null; } try { - XFile file = await controller.takePicture(); + XFile file = await cameraController.takePicture(); return file; } on CameraException catch (e) { _showCameraException(e); diff --git a/packages/camera/camera/example/pubspec.yaml b/packages/camera/camera/example/pubspec.yaml index 2a45fd69194c..b3ef8e497dc1 100644 --- a/packages/camera/camera/example/pubspec.yaml +++ b/packages/camera/camera/example/pubspec.yaml @@ -9,23 +9,23 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - path_provider: ^0.5.0 + path_provider: ^2.0.0 flutter: sdk: flutter - video_player: ^0.10.0 - integration_test: - path: ../../../integration_test + video_player: ^2.0.0 dev_dependencies: flutter_test: sdk: flutter flutter_driver: sdk: flutter - pedantic: ^1.8.0 + integration_test: + path: ../../../integration_test + pedantic: ^1.10.0 flutter: uses-material-design: true environment: - sdk: ">=2.7.0 <3.0.0" - flutter: ">=1.9.1+hotfix.4" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.22.0" diff --git a/packages/camera/camera/example/test_driver/integration_test.dart b/packages/camera/camera/example/test_driver/integration_test.dart index 1e6e3ba7941f..160b48f8f72f 100644 --- a/packages/camera/camera/example/test_driver/integration_test.dart +++ b/packages/camera/camera/example/test_driver/integration_test.dart @@ -1,3 +1,10 @@ +// 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. + +// TODO(mvanbeusekom): Remove this once flutter_driver supports null safety. +// https://github.com/flutter/flutter/issues/71379 +// @dart = 2.9 import 'dart:async'; import 'dart:convert'; import 'dart:io'; diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 2d620505def2..53f9b3b40ad1 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,26 +2,31 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.8.0-nullsafety.3 +version: 0.8.0 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: flutter: sdk: flutter - camera_platform_interface: ^2.0.0-nullsafety + camera_platform_interface: ^2.0.0 pedantic: ^1.10.0 - quiver: ^3.0.0-nullsafety.3 + quiver: ^3.0.0 dev_dependencies: - video_player: ^2.0.0-nullsafety.7 + video_player: ^2.0.0 flutter_test: sdk: flutter flutter_driver: sdk: flutter - mockito: ^5.0.0-nullsafety.5 - plugin_platform_interface: ^1.1.0-nullsafety.2 + + # TODO(mvanbeusekom): Update to stable 5.0.0 release when dependency conflict + # with flutter_driver has been resolved: + # Because mockito >=5.0.0 depends on analyzer ^1.0.0 which depends on crypto ^3.0.0 + # every version of flutter_driver from sdk depends on crypto 2.1.5. + mockito: ^5.0.0-nullsafety.7 + plugin_platform_interface: ^2.0.0 flutter: plugin: @@ -33,5 +38,5 @@ flutter: pluginClass: CameraPlugin environment: - sdk: '>=2.12.0-0 <3.0.0' + sdk: ">=2.12.0-259.9.beta <3.0.0" flutter: ">=1.22.0" From 72feefd6df283ac4ff97421218ccc1e694f9fbb8 Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Tue, 2 Mar 2021 11:14:04 -0800 Subject: [PATCH 0235/1565] [connectivity_for_web] Migration to null-safety. (#3652) --- .../connectivity_for_web/CHANGELOG.md | 5 ++ .../connectivity_for_web/example/README.md | 21 +++++++ .../network_information_test.dart} | 56 ++++++++++--------- .../src/connectivity_mocks.dart | 56 +++++++++++++++++++ .../example/lib/main.dart | 25 +++++++++ .../connectivity_for_web/example/pubspec.yaml | 21 +++++++ .../connectivity_for_web/example/run_test.sh | 18 ++++++ .../test_driver/integration_driver.dart | 7 +++ .../{test => example}/web/index.html | 0 .../src/dart_html_connectivity_plugin.dart | 12 ++-- ...k_information_api_connectivity_plugin.dart | 16 +++--- .../lib/src/utils/connectivity_result.dart | 6 +- .../connectivity_for_web/pubspec.yaml | 13 ++--- .../connectivity_for_web/test/.gitignore | 8 --- .../connectivity_for_web/test/README.md | 5 ++ .../test/lib/src/connectivity_mocks.dart | 25 --------- .../connectivity_for_web/test/pubspec.yaml | 25 --------- .../test/tests_exist_elsewhere_test.dart | 10 ++++ 18 files changed, 219 insertions(+), 110 deletions(-) create mode 100644 packages/connectivity/connectivity_for_web/example/README.md rename packages/connectivity/connectivity_for_web/{test/lib/main.dart => example/integration_test/network_information_test.dart} (57%) create mode 100644 packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart create mode 100644 packages/connectivity/connectivity_for_web/example/lib/main.dart create mode 100644 packages/connectivity/connectivity_for_web/example/pubspec.yaml create mode 100755 packages/connectivity/connectivity_for_web/example/run_test.sh create mode 100644 packages/connectivity/connectivity_for_web/example/test_driver/integration_driver.dart rename packages/connectivity/connectivity_for_web/{test => example}/web/index.html (100%) delete mode 100644 packages/connectivity/connectivity_for_web/test/.gitignore create mode 100644 packages/connectivity/connectivity_for_web/test/README.md delete mode 100644 packages/connectivity/connectivity_for_web/test/lib/src/connectivity_mocks.dart delete mode 100644 packages/connectivity/connectivity_for_web/test/pubspec.yaml create mode 100644 packages/connectivity/connectivity_for_web/test/tests_exist_elsewhere_test.dart diff --git a/packages/connectivity/connectivity_for_web/CHANGELOG.md b/packages/connectivity/connectivity_for_web/CHANGELOG.md index f6d83dd3e0cc..ccd689760b84 100644 --- a/packages/connectivity/connectivity_for_web/CHANGELOG.md +++ b/packages/connectivity/connectivity_for_web/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.4.0 + +* Migrate to null-safety +* Run tests using flutter driver + ## 0.3.1+4 * Remove unused `test` dependency. diff --git a/packages/connectivity/connectivity_for_web/example/README.md b/packages/connectivity/connectivity_for_web/example/README.md new file mode 100644 index 000000000000..0ec01e025570 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/example/README.md @@ -0,0 +1,21 @@ +# Testing + +This package utilizes the `integration_test` package to run its tests in a web browser. + +See [flutter.dev > Integration testing](https://flutter.dev/docs/testing/integration-tests) for more info. + +## Running the tests + +Make sure you have updated to the latest Flutter master. + +1. Check what version of Chrome is running on the machine you're running tests on. + +2. Download and install driver for that version from here: + * + +3. Start the driver using `chromedriver --port=4444` + +4. Run tests: `flutter drive -d web-server --browser-name=chrome --driver=test_driver/integration_driver.dart --target=integration_test/TEST_NAME.dart`, or (in Linux): + + * Single: `./run_test.sh integration_test/TEST_NAME.dart` + * All: `./run_test.sh` diff --git a/packages/connectivity/connectivity_for_web/test/lib/main.dart b/packages/connectivity/connectivity_for_web/example/integration_test/network_information_test.dart similarity index 57% rename from packages/connectivity/connectivity_for_web/test/lib/main.dart rename to packages/connectivity/connectivity_for_web/example/integration_test/network_information_test.dart index e3473532553e..f8e8059e7dba 100644 --- a/packages/connectivity/connectivity_for_web/test/lib/main.dart +++ b/packages/connectivity/connectivity_for_web/example/integration_test/network_information_test.dart @@ -1,9 +1,7 @@ -import 'package:integration_test/integration_test.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; import 'package:connectivity_for_web/src/network_information_api_connectivity_plugin.dart'; - -import 'package:mockito/mockito.dart'; +import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; import 'src/connectivity_mocks.dart'; @@ -12,66 +10,70 @@ void main() { group('checkConnectivity', () { void testCheckConnectivity({ - String type, - String effectiveType, - num downlink = 10, - num rtt = 50, - ConnectivityResult expected, + String? type, + String? effectiveType, + num? downlink = 10, + int? rtt = 50, + required ConnectivityResult expected, }) { - final connection = MockNetworkInformation(); - when(connection.type).thenReturn(type); - when(connection.effectiveType).thenReturn(effectiveType); - when(connection.downlink).thenReturn(downlink); - when(connection.rtt).thenReturn(downlink); + final connection = FakeNetworkInformation( + type: type, + effectiveType: effectiveType, + downlink: downlink, + rtt: rtt, + ); NetworkInformationApiConnectivityPlugin plugin = NetworkInformationApiConnectivityPlugin.withConnection(connection); expect(plugin.checkConnectivity(), completion(equals(expected))); } - test('0 downlink and rtt -> none', () { + testWidgets('0 downlink and rtt -> none', (WidgetTester tester) async { testCheckConnectivity( effectiveType: '4g', downlink: 0, rtt: 0, expected: ConnectivityResult.none); }); - test('slow-2g -> mobile', () { + testWidgets('slow-2g -> mobile', (WidgetTester tester) async { testCheckConnectivity( effectiveType: 'slow-2g', expected: ConnectivityResult.mobile); }); - test('2g -> mobile', () { + testWidgets('2g -> mobile', (WidgetTester tester) async { testCheckConnectivity( effectiveType: '2g', expected: ConnectivityResult.mobile); }); - test('3g -> mobile', () { + testWidgets('3g -> mobile', (WidgetTester tester) async { testCheckConnectivity( effectiveType: '3g', expected: ConnectivityResult.mobile); }); - test('4g -> wifi', () { + testWidgets('4g -> wifi', (WidgetTester tester) async { testCheckConnectivity( effectiveType: '4g', expected: ConnectivityResult.wifi); }); }); group('get onConnectivityChanged', () { - test('puts change events in a Stream', () async { - final connection = MockNetworkInformation(); + testWidgets('puts change events in a Stream', (WidgetTester tester) async { + final connection = FakeNetworkInformation(); NetworkInformationApiConnectivityPlugin plugin = NetworkInformationApiConnectivityPlugin.withConnection(connection); - Stream results = plugin.onConnectivityChanged; + // The onConnectivityChanged stream is infinite, so we only .take(2) so the test completes. + // We need to do .toList() now, because otherwise the Stream won't be actually listened to, + // and we'll miss the calls to mockChangeValue below. + final results = plugin.onConnectivityChanged.take(2).toList(); // Fake a disconnect-reconnect await connection.mockChangeValue(downlink: 0, rtt: 0); await connection.mockChangeValue( downlink: 10, rtt: 50, effectiveType: '4g'); - // The stream of results is infinite, so we need to .take(2) for this test to complete. + // Expect to see the disconnect-reconnect in the resulting stream. expect( - results.take(2).toList(), - completion( - equals([ConnectivityResult.none, ConnectivityResult.wifi]))); + results, + completion([ConnectivityResult.none, ConnectivityResult.wifi]), + ); }); }); } diff --git a/packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart b/packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart new file mode 100644 index 000000000000..fc795595e3f3 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart @@ -0,0 +1,56 @@ +import 'dart:async'; +import 'dart:html'; +import 'dart:js_util' show getProperty; + +import 'package:flutter_test/flutter_test.dart'; + +/// A Fake implementation of the NetworkInformation API that allows +/// for external modification of its values. +/// +/// Note that the DOM API works by internally mutating and broadcasting +/// 'change' events. +class FakeNetworkInformation extends Fake implements NetworkInformation { + String? _type; + String? _effectiveType; + num? _downlink; + int? _rtt; + + @override + String? get type => _type; + + @override + String? get effectiveType => _effectiveType; + + @override + num? get downlink => _downlink; + + @override + int? get rtt => _rtt; + + FakeNetworkInformation({ + String? type, + String? effectiveType, + num? downlink, + int? rtt, + }) : this._type = type, + this._effectiveType = effectiveType, + this._downlink = downlink, + this._rtt = rtt; + + /// Changes the desired values, and triggers the change event listener. + Future mockChangeValue({ + String? type, + String? effectiveType, + num? downlink, + int? rtt, + }) async { + this._type = type; + this._effectiveType = effectiveType; + this._downlink = downlink; + this._rtt = rtt; + + // This is set by the onConnectivityChanged getter... + final Function onchange = getProperty(this, 'onchange') as Function; + onchange(Event('change')); + } +} diff --git a/packages/connectivity/connectivity_for_web/example/lib/main.dart b/packages/connectivity/connectivity_for_web/example/lib/main.dart new file mode 100644 index 000000000000..e1a38dcdcd46 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/example/lib/main.dart @@ -0,0 +1,25 @@ +// Copyright 2013 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/material.dart'; + +void main() { + runApp(MyApp()); +} + +/// App for testing +class MyApp extends StatefulWidget { + @override + _MyAppState createState() => _MyAppState(); +} + +class _MyAppState extends State { + @override + Widget build(BuildContext context) { + return Directionality( + textDirection: TextDirection.ltr, + child: Text('Testing... Look at the console output for results!'), + ); + } +} diff --git a/packages/connectivity/connectivity_for_web/example/pubspec.yaml b/packages/connectivity/connectivity_for_web/example/pubspec.yaml new file mode 100644 index 000000000000..54289bc648ec --- /dev/null +++ b/packages/connectivity/connectivity_for_web/example/pubspec.yaml @@ -0,0 +1,21 @@ +name: connectivity_for_web_integration_tests +publish_to: none + +dependencies: + connectivity_for_web: + path: ../ + flutter: + sdk: flutter + +dev_dependencies: + js: ^0.6.3 + flutter_test: + sdk: flutter + flutter_driver: + sdk: flutter + integration_test: + sdk: flutter + +environment: + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.27.0-0" # For integration_test from sdk diff --git a/packages/connectivity/connectivity_for_web/example/run_test.sh b/packages/connectivity/connectivity_for_web/example/run_test.sh new file mode 100755 index 000000000000..8e6f149358c9 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/example/run_test.sh @@ -0,0 +1,18 @@ +#!/usr/bin/bash +if pgrep -lf chromedriver > /dev/null; then + echo "chromedriver is running." + + if [ $# -eq 0 ]; then + echo "No target specified, running all tests..." + find integration_test/ -iname *_test.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_driver.dart --target='{}' + else + echo "Running test target: $1..." + set -x + flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_driver.dart --target=$1 + fi + + else + echo "chromedriver is not running." + echo "Please, check the README.md for instructions on how to use run_test.sh" +fi + diff --git a/packages/connectivity/connectivity_for_web/example/test_driver/integration_driver.dart b/packages/connectivity/connectivity_for_web/example/test_driver/integration_driver.dart new file mode 100644 index 000000000000..64e2248a4f9b --- /dev/null +++ b/packages/connectivity/connectivity_for_web/example/test_driver/integration_driver.dart @@ -0,0 +1,7 @@ +// Copyright 2019 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. + +import 'package:integration_test/integration_test_driver.dart'; + +Future main() async => integrationDriver(); diff --git a/packages/connectivity/connectivity_for_web/test/web/index.html b/packages/connectivity/connectivity_for_web/example/web/index.html similarity index 100% rename from packages/connectivity/connectivity_for_web/test/web/index.html rename to packages/connectivity/connectivity_for_web/example/web/index.html diff --git a/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart b/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart index 5caa5679d6ad..950d26804371 100644 --- a/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart +++ b/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart @@ -9,26 +9,26 @@ class DartHtmlConnectivityPlugin extends ConnectivityPlugin { /// Checks the connection status of the device. @override Future checkConnectivity() async { - return html.window.navigator.onLine + return html.window.navigator.onLine ?? false ? ConnectivityResult.wifi : ConnectivityResult.none; } - StreamController _connectivityResult; + StreamController? _connectivityResult; /// Returns a Stream of ConnectivityResults changes. @override Stream get onConnectivityChanged { if (_connectivityResult == null) { - _connectivityResult = StreamController(); + _connectivityResult = StreamController.broadcast(); // Fallback to dart:html window.onOnline / window.onOffline html.window.onOnline.listen((event) { - _connectivityResult.add(ConnectivityResult.wifi); + _connectivityResult!.add(ConnectivityResult.wifi); }); html.window.onOffline.listen((event) { - _connectivityResult.add(ConnectivityResult.none); + _connectivityResult!.add(ConnectivityResult.none); }); } - return _connectivityResult.stream; + return _connectivityResult!.stream; } } diff --git a/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart b/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart index 99bac2ab8d30..800be2ef238f 100644 --- a/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart +++ b/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'dart:html' as html show window, NetworkInformation; -import 'dart:js'; -import 'dart:js_util'; +import 'dart:js' show allowInterop; +import 'dart:js_util' show setProperty; import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; import 'package:connectivity_for_web/connectivity_for_web.dart'; @@ -18,7 +18,7 @@ class NetworkInformationApiConnectivityPlugin extends ConnectivityPlugin { /// The constructor of the plugin. NetworkInformationApiConnectivityPlugin() - : this.withConnection(html.window.navigator.connection); + : this.withConnection(html.window.navigator.connection!); /// Creates the plugin, with an override of the NetworkInformation object. @visibleForTesting @@ -32,8 +32,8 @@ class NetworkInformationApiConnectivityPlugin extends ConnectivityPlugin { return networkInformationToConnectivityResult(_networkInformation); } - StreamController _connectivityResultStreamController; - Stream _connectivityResultStream; + StreamController? _connectivityResultStreamController; + late Stream _connectivityResultStream; /// Returns a Stream of ConnectivityResults changes. @override @@ -41,8 +41,10 @@ class NetworkInformationApiConnectivityPlugin extends ConnectivityPlugin { if (_connectivityResultStreamController == null) { _connectivityResultStreamController = StreamController(); + + // Directly write the 'onchange' function on the networkInformation object. setProperty(_networkInformation, 'onchange', allowInterop((_) { - _connectivityResultStreamController + _connectivityResultStreamController! .add(networkInformationToConnectivityResult(_networkInformation)); })); // TODO: Implement the above with _networkInformation.onChange: @@ -54,7 +56,7 @@ class NetworkInformationApiConnectivityPlugin extends ConnectivityPlugin { // onChange Stream upon hot restart. // https://github.com/dart-lang/sdk/issues/42679 _connectivityResultStream = - _connectivityResultStreamController.stream.asBroadcastStream(); + _connectivityResultStreamController!.stream.asBroadcastStream(); } return _connectivityResultStream; } diff --git a/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart b/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart index efefd8d52440..e7eb8969231a 100644 --- a/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart +++ b/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart @@ -3,7 +3,7 @@ import 'package:connectivity_platform_interface/connectivity_platform_interface. /// Converts an incoming NetworkInformation object into the correct ConnectivityResult. ConnectivityResult networkInformationToConnectivityResult( - html.NetworkInformation info, + html.NetworkInformation? info, ) { if (info == null) { return ConnectivityResult.none; @@ -12,10 +12,10 @@ ConnectivityResult networkInformationToConnectivityResult( return ConnectivityResult.none; } if (info.effectiveType != null) { - return _effectiveTypeToConnectivityResult(info.effectiveType); + return _effectiveTypeToConnectivityResult(info.effectiveType!); } if (info.type != null) { - return _typeToConnectivityResult(info.type); + return _typeToConnectivityResult(info.type!); } return ConnectivityResult.none; } diff --git a/packages/connectivity/connectivity_for_web/pubspec.yaml b/packages/connectivity/connectivity_for_web/pubspec.yaml index 3622b15709b6..5c673e83b44a 100644 --- a/packages/connectivity/connectivity_for_web/pubspec.yaml +++ b/packages/connectivity/connectivity_for_web/pubspec.yaml @@ -1,7 +1,7 @@ name: connectivity_for_web description: An implementation for the web platform of the Flutter `connectivity` plugin. This uses the NetworkInformation Web API, with a fallback to Navigator.onLine. -version: 0.3.1+4 repository: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_for_web +version: 0.4.0 flutter: plugin: @@ -11,21 +11,16 @@ flutter: fileName: connectivity_for_web.dart dependencies: - connectivity_platform_interface: ^1.0.3 + connectivity_platform_interface: ^2.0.0 flutter_web_plugins: sdk: flutter flutter: sdk: flutter dev_dependencies: - flutter_driver: - sdk: flutter flutter_test: sdk: flutter - integration_test: - path: ../../integration_test - mockito: ^4.1.1 environment: - sdk: ">=2.6.0 <3.0.0" - flutter: ">=1.12.13+hotfix.4" + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.20.0" diff --git a/packages/connectivity/connectivity_for_web/test/.gitignore b/packages/connectivity/connectivity_for_web/test/.gitignore deleted file mode 100644 index d7dee828a6b9..000000000000 --- a/packages/connectivity/connectivity_for_web/test/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -.DS_Store -.dart_tool/ - -.packages -.pub/ - -build/ -lib/generated_plugin_registrant.dart diff --git a/packages/connectivity/connectivity_for_web/test/README.md b/packages/connectivity/connectivity_for_web/test/README.md new file mode 100644 index 000000000000..7c5b4ad682ba --- /dev/null +++ b/packages/connectivity/connectivity_for_web/test/README.md @@ -0,0 +1,5 @@ +## test + +This package uses integration tests for testing. + +See `example/README.md` for more info. diff --git a/packages/connectivity/connectivity_for_web/test/lib/src/connectivity_mocks.dart b/packages/connectivity/connectivity_for_web/test/lib/src/connectivity_mocks.dart deleted file mode 100644 index 7b82b512065b..000000000000 --- a/packages/connectivity/connectivity_for_web/test/lib/src/connectivity_mocks.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'dart:html'; - -import 'package:mockito/mockito.dart'; - -/// A Mock implementation of the NetworkInformation API that allows -/// for external modification of its values. -class MockNetworkInformation extends Mock implements NetworkInformation { - /// The callback that will fire after the network information values change. - Function onchange; - - /// Changes the desired values, and triggers the change event listener. - void mockChangeValue({ - String type, - String effectiveType, - num downlink, - num rtt, - }) async { - when(this.type).thenAnswer((_) => type); - when(this.effectiveType).thenAnswer((_) => effectiveType); - when(this.downlink).thenAnswer((_) => downlink); - when(this.rtt).thenAnswer((_) => rtt); - - onchange(Event('change')); - } -} diff --git a/packages/connectivity/connectivity_for_web/test/pubspec.yaml b/packages/connectivity/connectivity_for_web/test/pubspec.yaml deleted file mode 100644 index 512b7df8c26e..000000000000 --- a/packages/connectivity/connectivity_for_web/test/pubspec.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: connectivity_web_example -description: Example web app for the connectivity plugin -homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_web - -dependencies: - connectivity_for_web: - path: ../ - js: ^0.6.1+1 - flutter_web_plugins: - sdk: flutter - flutter: - sdk: flutter - -dev_dependencies: - flutter_test: - sdk: flutter - flutter_driver: - sdk: flutter - integration_test: - path: ../../../integration_test - mockito: ^4.1.1 - -environment: - sdk: ">=2.6.0 <3.0.0" - flutter: ">=1.12.13+hotfix.4" diff --git a/packages/connectivity/connectivity_for_web/test/tests_exist_elsewhere_test.dart b/packages/connectivity/connectivity_for_web/test/tests_exist_elsewhere_test.dart new file mode 100644 index 000000000000..334f52186d9d --- /dev/null +++ b/packages/connectivity/connectivity_for_web/test/tests_exist_elsewhere_test.dart @@ -0,0 +1,10 @@ +import 'package:flutter_test/flutter_test.dart'; + +void main() { + test('Tell the user where to find the real tests', () { + print('---'); + print('This package uses integration_test for its tests.'); + print('See `example/README.md` for more info.'); + print('---'); + }); +} From 84648904cb3a2e1040ede68ebbd71525574da626 Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Tue, 2 Mar 2021 13:09:04 -0800 Subject: [PATCH 0236/1565] [share] Migrate unit tests to null-safety. (#3660) --- packages/share/CHANGELOG.md | 4 ++ packages/share/pubspec.yaml | 4 +- packages/share/test/share_test.dart | 89 ++++++++++++++++++----------- 3 files changed, 61 insertions(+), 36 deletions(-) diff --git a/packages/share/CHANGELOG.md b/packages/share/CHANGELOG.md index 20afdea9f054..87e941c7afd7 100644 --- a/packages/share/CHANGELOG.md +++ b/packages/share/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +* Migrate unit tests to sound null safety. + ## 2.0.0 * Migrate to null safety. diff --git a/packages/share/pubspec.yaml b/packages/share/pubspec.yaml index e8a116799433..dd82fb4926bf 100644 --- a/packages/share/pubspec.yaml +++ b/packages/share/pubspec.yaml @@ -2,7 +2,7 @@ name: share description: Flutter plugin for sharing content via the platform share UI, using the ACTION_SEND intent on Android and UIActivityViewController on iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/share -version: 2.0.0 +version: 2.0.1 flutter: plugin: @@ -20,8 +20,6 @@ dependencies: sdk: flutter dev_dependencies: - test: ^1.16.3 - mockito: ^5.0.0-nullsafety.7 flutter_test: sdk: flutter integration_test: diff --git a/packages/share/test/share_test.dart b/packages/share/test/share_test.dart index d00867b19452..7e72fc4dc012 100644 --- a/packages/share/test/share_test.dart +++ b/packages/share/test/share_test.dart @@ -2,38 +2,33 @@ // 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'; -import 'package:flutter_test/flutter_test.dart' show TestWidgetsFlutterBinding; -import 'package:mockito/mockito.dart'; -import 'package:share/share.dart'; -import 'package:test/test.dart'; - import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:share/share.dart'; void main() { - TestWidgetsFlutterBinding.ensureInitialized(); + TestWidgetsFlutterBinding.ensureInitialized(); // Required for MethodChannels - MockMethodChannel mockChannel; + late FakeMethodChannel fakeChannel; setUp(() { - mockChannel = MockMethodChannel(); - // Re-pipe to mockito for easier verifies. + fakeChannel = FakeMethodChannel(); + // Re-pipe to our fake to verify invocations. Share.channel.setMockMethodCallHandler((MethodCall call) async { // The explicit type can be void as the only method call has a return type of void. - await mockChannel.invokeMethod(call.method, call.arguments); + await fakeChannel.invokeMethod(call.method, call.arguments); }); }); test('sharing empty fails', () { expect( () => Share.share(''), - throwsA(const TypeMatcher()), + throwsA(isA()), ); - verifyZeroInteractions(mockChannel); + expect(fakeChannel.invocation, isNull); }); test('sharing origin sets the right params', () async { @@ -42,22 +37,28 @@ void main() { subject: 'some subject to share', sharePositionOrigin: const Rect.fromLTWH(1.0, 2.0, 3.0, 4.0), ); - verify(mockChannel.invokeMethod('share', { - 'text': 'some text to share', - 'subject': 'some subject to share', - 'originX': 1.0, - 'originY': 2.0, - 'originWidth': 3.0, - 'originHeight': 4.0, - })); + + expect( + fakeChannel.invocation, + equals({ + 'share': { + 'text': 'some text to share', + 'subject': 'some subject to share', + 'originX': 1.0, + 'originY': 2.0, + 'originWidth': 3.0, + 'originHeight': 4.0, + } + }), + ); }); test('sharing empty file fails', () { expect( () => Share.shareFiles(['']), - throwsA(const TypeMatcher()), + throwsA(isA()), ); - verifyZeroInteractions(mockChannel); + expect(fakeChannel.invocation, isNull); }); test('sharing file sets correct mimeType', () async { @@ -65,11 +66,18 @@ void main() { final File file = File(path); try { file.createSync(); + await Share.shareFiles([path]); - verify(mockChannel.invokeMethod('shareFiles', { - 'paths': [path], - 'mimeTypes': ['image/png'], - })); + + expect( + fakeChannel.invocation, + equals({ + 'shareFiles': { + 'paths': [path], + 'mimeTypes': ['image/png'], + } + }), + ); } finally { file.deleteSync(); } @@ -80,15 +88,30 @@ void main() { final File file = File(path); try { file.createSync(); + await Share.shareFiles([path], mimeTypes: ['*/*']); - verify(mockChannel.invokeMethod('shareFiles', { - 'paths': [file.path], - 'mimeTypes': ['*/*'], - })); + + expect( + fakeChannel.invocation, + equals({ + 'shareFiles': { + 'paths': [file.path], + 'mimeTypes': ['*/*'], + } + }), + ); } finally { file.deleteSync(); } }); } -class MockMethodChannel extends Mock implements MethodChannel {} +class FakeMethodChannel extends Fake implements MethodChannel { + Map? invocation; + + @override + Future invokeMethod(String method, [dynamic arguments]) async { + this.invocation = {method: arguments}; + return null; + } +} From b90e42b9a4c373b7f86beec6606ded7fac9874cb Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Tue, 2 Mar 2021 14:00:43 -0800 Subject: [PATCH 0237/1565] [url_launcher] Migrate unit tests to NNBD (#3657) Replaces the problematic Mockito mock with a manual mock that handles null and non-null types correctly. Removes the unit test of the example app, since it's not adding any actual coverage. --- .../test/url_launcher_example_test.dart | 52 --- .../url_launcher/url_launcher/pubspec.yaml | 2 +- .../url_launcher/test/link_test.dart | 108 +++--- .../test/mock_url_launcher_platform.dart | 93 ++++++ .../url_launcher/test/url_launcher_test.dart | 309 ++++++++++-------- 5 files changed, 314 insertions(+), 250 deletions(-) delete mode 100644 packages/url_launcher/url_launcher/example/test/url_launcher_example_test.dart create mode 100644 packages/url_launcher/url_launcher/test/mock_url_launcher_platform.dart diff --git a/packages/url_launcher/url_launcher/example/test/url_launcher_example_test.dart b/packages/url_launcher/url_launcher/example/test/url_launcher_example_test.dart deleted file mode 100644 index a890be7f65f1..000000000000 --- a/packages/url_launcher/url_launcher/example/test/url_launcher_example_test.dart +++ /dev/null @@ -1,52 +0,0 @@ -// 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. - -// TODO(egarciad): Remove once mockito is migrated to null safety. -// @dart = 2.9 - -import 'package:flutter_test/flutter_test.dart'; -import 'package:flutter/material.dart'; -import 'package:mockito/mockito.dart'; -import 'package:plugin_platform_interface/plugin_platform_interface.dart'; -import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; -import 'package:url_launcher_example/main.dart'; - -void main() { - final MockUrlLauncher mock = MockUrlLauncher(); - UrlLauncherPlatform.instance = mock; - - testWidgets('Can open URLs', (WidgetTester tester) async { - await tester.pumpWidget(MyApp()); - const String defaultUrl = 'https://www.cylog.org/headers/'; - when(mock.canLaunch(defaultUrl)).thenAnswer((_) => Future.value(true)); - const Map defaultHeaders = { - 'my_header_key': 'my_header_value' - }; - verifyNever(mock.launch(defaultUrl, - useSafariVC: false, - useWebView: false, - enableDomStorage: false, - enableJavaScript: false, - universalLinksOnly: false, - headers: defaultHeaders)); - - Finder browserlaunchBtn = - find.widgetWithText(ElevatedButton, 'Launch in browser'); - expect(browserlaunchBtn, findsOneWidget); - await tester.tap(browserlaunchBtn); - - verify(mock.launch(defaultUrl, - useSafariVC: false, - useWebView: false, - enableDomStorage: false, - enableJavaScript: false, - universalLinksOnly: false, - headers: defaultHeaders)) - .called(1); - }); -} - -class MockUrlLauncher extends Mock - with MockPlatformInterfaceMixin - implements UrlLauncherPlatform {} diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index f337c8bed525..7a4d1820fb1f 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -39,7 +39,7 @@ dev_dependencies: flutter_test: sdk: flutter test: ^1.16.3 - mockito: ^5.0.0-nullsafety.7 + mockito: ^5.0.0 plugin_platform_interface: ^2.0.0 pedantic: ^1.10.0 diff --git a/packages/url_launcher/url_launcher/test/link_test.dart b/packages/url_launcher/url_launcher/test/link_test.dart index 46903aadaede..8da5111f5733 100644 --- a/packages/url_launcher/url_launcher/test/link_test.dart +++ b/packages/url_launcher/url_launcher/test/link_test.dart @@ -2,26 +2,26 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(egarciad): Remove once Mockito has been migrated to null safety. -// @dart = 2.9 - import 'dart:ui'; + import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:flutter/services.dart'; -import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'package:url_launcher/link.dart'; import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; +import 'mock_url_launcher_platform.dart'; + final MethodCodec _codec = const JSONMethodCodec(); void main() { - final MockUrlLauncher mock = MockUrlLauncher(); - UrlLauncherPlatform.instance = mock; + late MockUrlLauncher mock; - PlatformMessageCallback realOnPlatformMessage; + PlatformMessageCallback? realOnPlatformMessage; setUp(() { + mock = MockUrlLauncher(); + UrlLauncherPlatform.instance = mock; realOnPlatformMessage = window.onPlatformMessage; }); tearDown(() { @@ -31,11 +31,11 @@ void main() { group('$Link', () { testWidgets('handles null uri correctly', (WidgetTester tester) async { bool isBuilt = false; - FollowLink followLink; + FollowLink? followLink; final Link link = Link( uri: null, - builder: (BuildContext context, FollowLink followLink2) { + builder: (BuildContext context, FollowLink? followLink2) { isBuilt = true; followLink = followLink2; return Container(); @@ -50,66 +50,62 @@ void main() { testWidgets('calls url_launcher for external URLs with blank target', (WidgetTester tester) async { - FollowLink followLink; + FollowLink? followLink; await tester.pumpWidget(Link( uri: Uri.parse('http://example.com/foobar'), target: LinkTarget.blank, - builder: (BuildContext context, FollowLink followLink2) { + builder: (BuildContext context, FollowLink? followLink2) { followLink = followLink2; return Container(); }, )); - when(mock.canLaunch('http://example.com/foobar')) - .thenAnswer((realInvocation) => Future.value(true)); - clearInteractions(mock); - await followLink(); - - verifyInOrder([ - mock.canLaunch('http://example.com/foobar'), - mock.launch( - 'http://example.com/foobar', + mock + ..setLaunchExpectations( + url: 'http://example.com/foobar', useSafariVC: false, useWebView: false, universalLinksOnly: false, enableJavaScript: false, enableDomStorage: false, headers: {}, + webOnlyWindowName: null, ) - ]); + ..setResponse(true); + await followLink!(); + expect(mock.canLaunchCalled, isTrue); + expect(mock.launchCalled, isTrue); }); testWidgets('calls url_launcher for external URLs with self target', (WidgetTester tester) async { - FollowLink followLink; + FollowLink? followLink; await tester.pumpWidget(Link( uri: Uri.parse('http://example.com/foobar'), target: LinkTarget.self, - builder: (BuildContext context, FollowLink followLink2) { + builder: (BuildContext context, FollowLink? followLink2) { followLink = followLink2; return Container(); }, )); - when(mock.canLaunch('http://example.com/foobar')) - .thenAnswer((realInvocation) => Future.value(true)); - clearInteractions(mock); - await followLink(); - - verifyInOrder([ - mock.canLaunch('http://example.com/foobar'), - mock.launch( - 'http://example.com/foobar', + mock + ..setLaunchExpectations( + url: 'http://example.com/foobar', useSafariVC: true, useWebView: true, universalLinksOnly: false, enableJavaScript: false, enableDomStorage: false, headers: {}, + webOnlyWindowName: null, ) - ]); + ..setResponse(true); + await followLink!(); + expect(mock.canLaunchCalled, isTrue); + expect(mock.launchCalled, isTrue); }); testWidgets('sends navigation platform messages for internal route names', @@ -125,21 +121,21 @@ void main() { final List frameworkCalls = []; window.onPlatformMessage = ( String name, - ByteData data, - PlatformMessageResponseCallback callback, + ByteData? data, + PlatformMessageResponseCallback? callback, ) { frameworkCalls.add(_codec.decodeMethodCall(data)); - realOnPlatformMessage(name, data, callback); + realOnPlatformMessage!(name, data, callback); }; final Uri uri = Uri.parse('/foo/bar'); - FollowLink followLink; + FollowLink? followLink; await tester.pumpWidget(MaterialApp( routes: { '/': (BuildContext context) => Link( uri: uri, - builder: (BuildContext context, FollowLink followLink2) { + builder: (BuildContext context, FollowLink? followLink2) { followLink = followLink2; return Container(); }, @@ -150,11 +146,11 @@ void main() { engineCalls.clear(); frameworkCalls.clear(); - clearInteractions(mock); - await followLink(); + await followLink!(); // Shouldn't use url_launcher when uri is an internal route name. - verifyZeroInteractions(mock); + expect(mock.canLaunchCalled, isFalse); + expect(mock.launchCalled, isFalse); // A message should've been sent to the engine (by the Navigator, not by // the Link widget). @@ -191,19 +187,19 @@ void main() { final List frameworkCalls = []; window.onPlatformMessage = ( String name, - ByteData data, - PlatformMessageResponseCallback callback, + ByteData? data, + PlatformMessageResponseCallback? callback, ) { frameworkCalls.add(_codec.decodeMethodCall(data)); - realOnPlatformMessage(name, data, callback); + realOnPlatformMessage!(name, data, callback); }; final Uri uri = Uri.parse('/foo/bar'); - FollowLink followLink; + FollowLink? followLink; final Link link = Link( uri: uri, - builder: (BuildContext context, FollowLink followLink2) { + builder: (BuildContext context, FollowLink? followLink2) { followLink = followLink2; return Container(); }, @@ -217,11 +213,11 @@ void main() { engineCalls.clear(); frameworkCalls.clear(); - clearInteractions(mock); - await followLink(); + await followLink!(); // Shouldn't use url_launcher when uri is an internal route name. - verifyZeroInteractions(mock); + expect(mock.canLaunchCalled, isFalse); + expect(mock.launchCalled, isFalse); // Sends route information update to the engine. expect(engineCalls, hasLength(1)); @@ -249,10 +245,6 @@ void main() { }); } -class MockUrlLauncher extends Mock - with MockPlatformInterfaceMixin - implements UrlLauncherPlatform {} - class MockRouteInformationParser extends Mock implements RouteInformationParser { @override @@ -261,8 +253,8 @@ class MockRouteInformationParser extends Mock } } -class MockRouterDelegate extends Mock implements RouterDelegate { - MockRouterDelegate({@required this.builder}); +class MockRouterDelegate extends Mock implements RouterDelegate { + MockRouterDelegate({required this.builder}); final WidgetBuilder builder; @@ -270,4 +262,10 @@ class MockRouterDelegate extends Mock implements RouterDelegate { Widget build(BuildContext context) { return builder(context); } + + @override + Future setInitialRoutePath(Object configuration) async {} + + @override + Future setNewRoutePath(Object configuration) async {} } diff --git a/packages/url_launcher/url_launcher/test/mock_url_launcher_platform.dart b/packages/url_launcher/url_launcher/test/mock_url_launcher_platform.dart new file mode 100644 index 000000000000..87ae99e81024 --- /dev/null +++ b/packages/url_launcher/url_launcher/test/mock_url_launcher_platform.dart @@ -0,0 +1,93 @@ +// 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. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import 'package:url_launcher_platform_interface/link.dart'; +import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; + +class MockUrlLauncher extends Fake + with MockPlatformInterfaceMixin + implements UrlLauncherPlatform { + String? url; + bool? useSafariVC; + bool? useWebView; + bool? enableJavaScript; + bool? enableDomStorage; + bool? universalLinksOnly; + Map? headers; + String? webOnlyWindowName; + + bool? response; + + bool closeWebViewCalled = false; + bool canLaunchCalled = false; + bool launchCalled = false; + + void setCanLaunchExpectations(String url) { + this.url = url; + } + + void setLaunchExpectations({ + required String url, + required bool? useSafariVC, + required bool useWebView, + required bool enableJavaScript, + required bool enableDomStorage, + required bool universalLinksOnly, + required Map headers, + required String? webOnlyWindowName, + }) { + this.url = url; + this.useSafariVC = useSafariVC; + this.useWebView = useWebView; + this.enableJavaScript = enableJavaScript; + this.enableDomStorage = enableDomStorage; + this.universalLinksOnly = universalLinksOnly; + this.headers = headers; + this.webOnlyWindowName = webOnlyWindowName; + } + + void setResponse(bool response) { + this.response = response; + } + + @override + LinkDelegate? get linkDelegate => null; + + @override + Future canLaunch(String url) async { + expect(url, this.url); + canLaunchCalled = true; + return response!; + } + + @override + Future launch( + String url, { + required bool useSafariVC, + required bool useWebView, + required bool enableJavaScript, + required bool enableDomStorage, + required bool universalLinksOnly, + required Map headers, + String? webOnlyWindowName, + }) async { + expect(url, this.url); + expect(useSafariVC, this.useSafariVC); + expect(useWebView, this.useWebView); + expect(enableJavaScript, this.enableJavaScript); + expect(enableDomStorage, this.enableDomStorage); + expect(universalLinksOnly, this.universalLinksOnly); + expect(headers, this.headers); + expect(webOnlyWindowName, this.webOnlyWindowName); + launchCalled = true; + return response!; + } + + @override + Future closeWebView() async { + closeWebViewCalled = true; + } +} diff --git a/packages/url_launcher/url_launcher/test/url_launcher_test.dart b/packages/url_launcher/url_launcher/test/url_launcher_test.dart index bb3fd2ad92b5..9fb16019a543 100644 --- a/packages/url_launcher/url_launcher/test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher/test/url_launcher_test.dart @@ -2,32 +2,31 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(mvanbeusekom): Remove once Mockito is migrated to null safety. -// @dart = 2.9 - import 'dart:async'; import 'dart:ui'; import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; import 'package:flutter/foundation.dart'; -import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; import 'package:flutter/services.dart' show PlatformException; +import 'mock_url_launcher_platform.dart'; + void main() { final MockUrlLauncher mock = MockUrlLauncher(); UrlLauncherPlatform.instance = mock; test('closeWebView default behavior', () async { await closeWebView(); - verify(mock.closeWebView()); + expect(mock.closeWebViewCalled, isTrue); }); group('canLaunch', () { test('returns true', () async { - when(mock.canLaunch('foo')).thenAnswer((_) => Future.value(true)); + mock + ..setCanLaunchExpectations('foo') + ..setResponse(true); final bool result = await canLaunch('foo'); @@ -35,7 +34,9 @@ void main() { }); test('returns false', () async { - when(mock.canLaunch('foo')).thenAnswer((_) => Future.value(false)); + mock + ..setCanLaunchExpectations('foo') + ..setResponse(false); final bool result = await canLaunch('foo'); @@ -44,146 +45,145 @@ void main() { }); group('launch', () { test('default behavior', () async { - await launch('http://flutter.dev/'); - expect( - verify(mock.launch( - captureAny, - useSafariVC: captureAnyNamed('useSafariVC'), - useWebView: captureAnyNamed('useWebView'), - enableJavaScript: captureAnyNamed('enableJavaScript'), - enableDomStorage: captureAnyNamed('enableDomStorage'), - universalLinksOnly: captureAnyNamed('universalLinksOnly'), - headers: captureAnyNamed('headers'), - )).captured, - [ - 'http://flutter.dev/', - true, - false, - false, - false, - false, - {}, - ], - ); + mock + ..setLaunchExpectations( + url: 'http://flutter.dev/', + useSafariVC: true, + useWebView: false, + enableJavaScript: false, + enableDomStorage: false, + universalLinksOnly: false, + headers: {}, + webOnlyWindowName: null, + ) + ..setResponse(true); + expect(await launch('http://flutter.dev/'), isTrue); }); test('with headers', () async { - await launch( - 'http://flutter.dev/', - headers: {'key': 'value'}, - ); + mock + ..setLaunchExpectations( + url: 'http://flutter.dev/', + useSafariVC: true, + useWebView: false, + enableJavaScript: false, + enableDomStorage: false, + universalLinksOnly: false, + headers: {'key': 'value'}, + webOnlyWindowName: null, + ) + ..setResponse(true); expect( - verify(mock.launch( - any, - useSafariVC: anyNamed('useSafariVC'), - useWebView: anyNamed('useWebView'), - enableJavaScript: anyNamed('enableJavaScript'), - enableDomStorage: anyNamed('enableDomStorage'), - universalLinksOnly: anyNamed('universalLinksOnly'), - headers: captureAnyNamed('headers'), - )).captured.single, - {'key': 'value'}, - ); + await launch( + 'http://flutter.dev/', + headers: {'key': 'value'}, + ), + isTrue); }); test('force SafariVC', () async { - await launch('http://flutter.dev/', forceSafariVC: true); - expect( - verify(mock.launch( - any, - useSafariVC: captureAnyNamed('useSafariVC'), - useWebView: anyNamed('useWebView'), - enableJavaScript: anyNamed('enableJavaScript'), - enableDomStorage: anyNamed('enableDomStorage'), - universalLinksOnly: anyNamed('universalLinksOnly'), - headers: anyNamed('headers'), - )).captured.single, - true, - ); + mock + ..setLaunchExpectations( + url: 'http://flutter.dev/', + useSafariVC: true, + useWebView: false, + enableJavaScript: false, + enableDomStorage: false, + universalLinksOnly: false, + headers: {}, + webOnlyWindowName: null, + ) + ..setResponse(true); + expect(await launch('http://flutter.dev/', forceSafariVC: true), isTrue); }); test('universal links only', () async { - await launch('http://flutter.dev/', - forceSafariVC: false, universalLinksOnly: true); + mock + ..setLaunchExpectations( + url: 'http://flutter.dev/', + useSafariVC: false, + useWebView: false, + enableJavaScript: false, + enableDomStorage: false, + universalLinksOnly: true, + headers: {}, + webOnlyWindowName: null, + ) + ..setResponse(true); expect( - verify(mock.launch( - any, - useSafariVC: captureAnyNamed('useSafariVC'), - useWebView: anyNamed('useWebView'), - enableJavaScript: anyNamed('enableJavaScript'), - enableDomStorage: anyNamed('enableDomStorage'), - universalLinksOnly: captureAnyNamed('universalLinksOnly'), - headers: anyNamed('headers'), - )).captured, - [false, true], - ); + await launch('http://flutter.dev/', + forceSafariVC: false, universalLinksOnly: true), + isTrue); }); test('force WebView', () async { - await launch('http://flutter.dev/', forceWebView: true); - expect( - verify(mock.launch( - any, - useSafariVC: anyNamed('useSafariVC'), - useWebView: captureAnyNamed('useWebView'), - enableJavaScript: anyNamed('enableJavaScript'), - enableDomStorage: anyNamed('enableDomStorage'), - universalLinksOnly: anyNamed('universalLinksOnly'), - headers: anyNamed('headers'), - )).captured.single, - true, - ); + mock + ..setLaunchExpectations( + url: 'http://flutter.dev/', + useSafariVC: true, + useWebView: true, + enableJavaScript: false, + enableDomStorage: false, + universalLinksOnly: false, + headers: {}, + webOnlyWindowName: null, + ) + ..setResponse(true); + expect(await launch('http://flutter.dev/', forceWebView: true), isTrue); }); test('force WebView enable javascript', () async { - await launch('http://flutter.dev/', - forceWebView: true, enableJavaScript: true); + mock + ..setLaunchExpectations( + url: 'http://flutter.dev/', + useSafariVC: true, + useWebView: true, + enableJavaScript: true, + enableDomStorage: false, + universalLinksOnly: false, + headers: {}, + webOnlyWindowName: null, + ) + ..setResponse(true); expect( - verify(mock.launch( - any, - useSafariVC: anyNamed('useSafariVC'), - useWebView: captureAnyNamed('useWebView'), - enableJavaScript: captureAnyNamed('enableJavaScript'), - enableDomStorage: anyNamed('enableDomStorage'), - universalLinksOnly: anyNamed('universalLinksOnly'), - headers: anyNamed('headers'), - )).captured, - [true, true], - ); + await launch('http://flutter.dev/', + forceWebView: true, enableJavaScript: true), + isTrue); }); test('force WebView enable DOM storage', () async { - await launch('http://flutter.dev/', - forceWebView: true, enableDomStorage: true); + mock + ..setLaunchExpectations( + url: 'http://flutter.dev/', + useSafariVC: true, + useWebView: true, + enableJavaScript: false, + enableDomStorage: true, + universalLinksOnly: false, + headers: {}, + webOnlyWindowName: null, + ) + ..setResponse(true); expect( - verify(mock.launch( - any, - useSafariVC: anyNamed('useSafariVC'), - useWebView: captureAnyNamed('useWebView'), - enableJavaScript: anyNamed('enableJavaScript'), - enableDomStorage: captureAnyNamed('enableDomStorage'), - universalLinksOnly: anyNamed('universalLinksOnly'), - headers: anyNamed('headers'), - )).captured, - [true, true], - ); + await launch('http://flutter.dev/', + forceWebView: true, enableDomStorage: true), + isTrue); }); test('force SafariVC to false', () async { - await launch('http://flutter.dev/', forceSafariVC: false); - expect( - // ignore: missing_required_param - verify(mock.launch( - any, - useSafariVC: captureAnyNamed('useSafariVC'), - useWebView: anyNamed('useWebView'), - enableJavaScript: anyNamed('enableJavaScript'), - enableDomStorage: anyNamed('enableDomStorage'), - universalLinksOnly: anyNamed('universalLinksOnly'), - headers: anyNamed('headers'), - )).captured.single, - false, - ); + mock + ..setLaunchExpectations( + url: 'http://flutter.dev/', + useSafariVC: false, + useWebView: false, + enableJavaScript: false, + enableDomStorage: false, + universalLinksOnly: false, + headers: {}, + webOnlyWindowName: null, + ) + ..setResponse(true); + expect(await launch('http://flutter.dev/', forceSafariVC: false), isTrue); }); test('cannot launch a non-web in webview', () async { @@ -192,19 +192,20 @@ void main() { }); test('send e-mail', () async { - await launch('mailto:gmail-noreply@google.com?subject=Hello'); - expect( - verify(await mock.launch( - any, - useSafariVC: anyNamed('useSafariVC'), - useWebView: anyNamed('useWebView'), - enableJavaScript: anyNamed('enableJavaScript'), - enableDomStorage: anyNamed('enableDomStorage'), - universalLinksOnly: anyNamed('universalLinksOnly'), - headers: anyNamed('headers'), - )), - isInstanceOf(), - ); + mock + ..setLaunchExpectations( + url: 'mailto:gmail-noreply@google.com?subject=Hello', + useSafariVC: false, + useWebView: false, + enableJavaScript: false, + enableDomStorage: false, + universalLinksOnly: false, + headers: {}, + webOnlyWindowName: null, + ) + ..setResponse(true); + expect(await launch('mailto:gmail-noreply@google.com?subject=Hello'), + isTrue); }); test('cannot send e-mail with forceSafariVC: true', () async { @@ -224,8 +225,22 @@ void main() { }); test('controls system UI when changing statusBarBrightness', () async { + mock + ..setLaunchExpectations( + url: 'http://flutter.dev/', + useSafariVC: true, + useWebView: false, + enableJavaScript: false, + enableDomStorage: false, + universalLinksOnly: false, + headers: {}, + webOnlyWindowName: null, + ) + ..setResponse(true); + final TestWidgetsFlutterBinding binding = - TestWidgetsFlutterBinding.ensureInitialized(); + TestWidgetsFlutterBinding.ensureInitialized() + as TestWidgetsFlutterBinding; debugDefaultTargetPlatformOverride = TargetPlatform.iOS; binding.renderView.automaticSystemUiAdjustment = true; final Future launchResult = @@ -239,8 +254,22 @@ void main() { }); test('sets automaticSystemUiAdjustment to not be null', () async { + mock + ..setLaunchExpectations( + url: 'http://flutter.dev/', + useSafariVC: true, + useWebView: false, + enableJavaScript: false, + enableDomStorage: false, + universalLinksOnly: false, + headers: {}, + webOnlyWindowName: null, + ) + ..setResponse(true); + final TestWidgetsFlutterBinding binding = - TestWidgetsFlutterBinding.ensureInitialized(); + TestWidgetsFlutterBinding.ensureInitialized() + as TestWidgetsFlutterBinding; debugDefaultTargetPlatformOverride = TargetPlatform.android; expect(binding.renderView.automaticSystemUiAdjustment, true); final Future launchResult = @@ -254,7 +283,3 @@ void main() { }); }); } - -class MockUrlLauncher extends Mock - with MockPlatformInterfaceMixin - implements UrlLauncherPlatform {} From beef9a8b9b49ecbfee7bc6a2d8633e62985c28fb Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 2 Mar 2021 14:04:04 -0800 Subject: [PATCH 0238/1565] [android_intent] move unit test to nullsafety (#3659) --- packages/android_intent/pubspec.yaml | 3 +- .../test/android_intent_test.dart | 14 ++-- .../test/android_intent_test.mocks.dart | 64 +++++++++++++++++++ 3 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 packages/android_intent/test/android_intent_test.mocks.dart diff --git a/packages/android_intent/pubspec.yaml b/packages/android_intent/pubspec.yaml index e02c7a270344..8a80370a78a3 100644 --- a/packages/android_intent/pubspec.yaml +++ b/packages/android_intent/pubspec.yaml @@ -17,10 +17,11 @@ dependencies: meta: ^1.3.0 dev_dependencies: test: ^1.16.3 - mockito: ^5.0.0-nullsafety.7 + mockito: ^5.0.0 flutter_test: sdk: flutter pedantic: ^1.10.0 + build_runner: ^1.11.1 environment: sdk: ">=2.12.0-259.9.beta <3.0.0" diff --git a/packages/android_intent/test/android_intent_test.dart b/packages/android_intent/test/android_intent_test.dart index ad0eae3b662d..95ff345395cf 100644 --- a/packages/android_intent/test/android_intent_test.dart +++ b/packages/android_intent/test/android_intent_test.dart @@ -2,23 +2,27 @@ // 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'; import 'package:android_intent/android_intent.dart'; +import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:platform/platform.dart'; +import 'android_intent_test.mocks.dart'; + +@GenerateMocks([MethodChannel]) void main() { - AndroidIntent androidIntent; - MockMethodChannel mockChannel; + late AndroidIntent androidIntent; + late MockMethodChannel mockChannel; setUp(() { mockChannel = MockMethodChannel(); when(mockChannel.invokeMethod('canResolveActivity', any)) .thenAnswer((realInvocation) async => true); + when(mockChannel.invokeMethod('launch', any)) + .thenAnswer((realInvocation) async => {}); }); group('AndroidIntent', () { @@ -178,5 +182,3 @@ void main() { }); }); } - -class MockMethodChannel extends Mock implements MethodChannel {} diff --git a/packages/android_intent/test/android_intent_test.mocks.dart b/packages/android_intent/test/android_intent_test.mocks.dart new file mode 100644 index 000000000000..fed1624ad069 --- /dev/null +++ b/packages/android_intent/test/android_intent_test.mocks.dart @@ -0,0 +1,64 @@ +// Mocks generated by Mockito 5.0.0 from annotations +// in android_intent/test/android_intent_test.dart. +// Do not manually edit this file. + +import 'dart:async' as _i5; + +import 'package:flutter/src/services/binary_messenger.dart' as _i3; +import 'package:flutter/src/services/message_codec.dart' as _i2; +import 'package:flutter/src/services/platform_channel.dart' as _i4; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: comment_references +// ignore_for_file: unnecessary_parenthesis + +class _FakeMethodCodec extends _i1.Fake implements _i2.MethodCodec {} + +class _FakeBinaryMessenger extends _i1.Fake implements _i3.BinaryMessenger {} + +/// A class which mocks [MethodChannel]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockMethodChannel extends _i1.Mock implements _i4.MethodChannel { + MockMethodChannel() { + _i1.throwOnMissingStub(this); + } + + @override + String get name => + (super.noSuchMethod(Invocation.getter(#name), returnValue: '') as String); + @override + _i2.MethodCodec get codec => (super.noSuchMethod(Invocation.getter(#codec), + returnValue: _FakeMethodCodec()) as _i2.MethodCodec); + @override + _i3.BinaryMessenger get binaryMessenger => + (super.noSuchMethod(Invocation.getter(#binaryMessenger), + returnValue: _FakeBinaryMessenger()) as _i3.BinaryMessenger); + @override + _i5.Future invokeMethod(String? method, [dynamic arguments]) => + (super.noSuchMethod(Invocation.method(#invokeMethod, [method, arguments]), + returnValue: Future.value(null)) as _i5.Future); + @override + _i5.Future?> invokeListMethod(String? method, + [dynamic arguments]) => + (super.noSuchMethod( + Invocation.method(#invokeListMethod, [method, arguments]), + returnValue: Future.value([])) as _i5.Future?>); + @override + _i5.Future?> invokeMapMethod(String? method, + [dynamic arguments]) => + (super.noSuchMethod( + Invocation.method(#invokeMapMethod, [method, arguments]), + returnValue: Future.value({})) as _i5.Future?>); + @override + bool checkMethodCallHandler( + _i5.Future Function(_i2.MethodCall)? handler) => + (super.noSuchMethod(Invocation.method(#checkMethodCallHandler, [handler]), + returnValue: false) as bool); + @override + bool checkMockMethodCallHandler( + _i5.Future Function(_i2.MethodCall)? handler) => + (super.noSuchMethod( + Invocation.method(#checkMockMethodCallHandler, [handler]), + returnValue: false) as bool); +} From 4738c8384d3d3dfd68eb2f8b67a296f7a35b8320 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 2 Mar 2021 14:09:02 -0800 Subject: [PATCH 0239/1565] remove unused plugin (#3661) --- .../integration_test/example/pubspec.yaml | 2 -- .../integration_test_macos/CHANGELOG.md | 11 -------- .../integration_test_macos/LICENSE | 25 ------------------- .../macos/Assets/.gitkeep | 0 .../macos/Classes/IntegrationTestPlugin.swift | 22 ---------------- .../macos/integration_test_macos.podspec | 21 ---------------- .../integration_test_macos/pubspec.yaml | 21 ---------------- 7 files changed, 102 deletions(-) delete mode 100644 packages/integration_test/integration_test_macos/CHANGELOG.md delete mode 100644 packages/integration_test/integration_test_macos/LICENSE delete mode 100644 packages/integration_test/integration_test_macos/macos/Assets/.gitkeep delete mode 100644 packages/integration_test/integration_test_macos/macos/Classes/IntegrationTestPlugin.swift delete mode 100644 packages/integration_test/integration_test_macos/macos/integration_test_macos.podspec delete mode 100644 packages/integration_test/integration_test_macos/pubspec.yaml diff --git a/packages/integration_test/example/pubspec.yaml b/packages/integration_test/example/pubspec.yaml index 5ad8be4a818e..558d5f7bc1a1 100644 --- a/packages/integration_test/example/pubspec.yaml +++ b/packages/integration_test/example/pubspec.yaml @@ -24,8 +24,6 @@ dev_dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - integration_test_macos: - path: ../integration_test_macos test: any pedantic: ^1.8.0 diff --git a/packages/integration_test/integration_test_macos/CHANGELOG.md b/packages/integration_test/integration_test_macos/CHANGELOG.md deleted file mode 100644 index ab4bac1a3f3f..000000000000 --- a/packages/integration_test/integration_test_macos/CHANGELOG.md +++ /dev/null @@ -1,11 +0,0 @@ -## 0.0.2 - -* Renames package to integration_test_macos. - -## 0.0.1+1 - -* Remove Android folder from `e2e_macos`. - -## 0.0.1 - -* Initial release diff --git a/packages/integration_test/integration_test_macos/LICENSE b/packages/integration_test/integration_test_macos/LICENSE deleted file mode 100644 index 507569823f1b..000000000000 --- a/packages/integration_test/integration_test_macos/LICENSE +++ /dev/null @@ -1,25 +0,0 @@ -Copyright 2019 The Chromium Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of Google Inc. nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/integration_test/integration_test_macos/macos/Assets/.gitkeep b/packages/integration_test/integration_test_macos/macos/Assets/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/packages/integration_test/integration_test_macos/macos/Classes/IntegrationTestPlugin.swift b/packages/integration_test/integration_test_macos/macos/Classes/IntegrationTestPlugin.swift deleted file mode 100644 index b4eb5fc410d5..000000000000 --- a/packages/integration_test/integration_test_macos/macos/Classes/IntegrationTestPlugin.swift +++ /dev/null @@ -1,22 +0,0 @@ -import FlutterMacOS - -public class IntegrationTestPlugin: NSObject, FlutterPlugin { - - public static func register(with registrar: FlutterPluginRegistrar) { - let channel = FlutterMethodChannel( - name: "plugins.flutter.io/integration_test", - binaryMessenger: registrar.messenger) - - let instance = IntegrationTestPlugin() - registrar.addMethodCallDelegate(instance, channel: channel) - } - - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { - switch call.method { - case "allTestsFinished": - result(nil) - default: - result(FlutterMethodNotImplemented) - } - } -} diff --git a/packages/integration_test/integration_test_macos/macos/integration_test_macos.podspec b/packages/integration_test/integration_test_macos/macos/integration_test_macos.podspec deleted file mode 100644 index 74bf66321319..000000000000 --- a/packages/integration_test/integration_test_macos/macos/integration_test_macos.podspec +++ /dev/null @@ -1,21 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'IntegrationTestMacOS' - s.version = '0.0.1' - s.summary = 'Adapter for integration tests.' - s.description = <<-DESC -Runs tests that use the flutter_test API as integration tests on macOS. - DESC - s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/integration_test/integration_test_macos' - s.license = { :type => 'BSD', :file => '../LICENSE' } - s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } - s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/integration_test' } - s.source_files = 'Classes/**/*' - s.dependency 'FlutterMacOS' - - s.platform = :osx, '10.11' - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } -end - diff --git a/packages/integration_test/integration_test_macos/pubspec.yaml b/packages/integration_test/integration_test_macos/pubspec.yaml deleted file mode 100644 index 46510e32b94a..000000000000 --- a/packages/integration_test/integration_test_macos/pubspec.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: integration_test_macos -description: Desktop implementation of integration_test plugin -version: 0.0.1+1 -author: Flutter Team -homepage: https://github.com/flutter/plugins/tree/master/packages/integration_test/integration_test_macos - -flutter: - plugin: - platforms: - macos: - pluginClass: IntegrationTestPlugin - -environment: - sdk: ">=2.1.0 <3.0.0" - -dependencies: - flutter: - sdk: flutter - -dev_dependencies: - pedantic: ^1.8.0 From 1e3a82316e0389409e60f0197ef49290192a9dcc Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Tue, 2 Mar 2021 14:50:39 -0800 Subject: [PATCH 0240/1565] [device_info] Enable NNBD for unit test (#3658) Removes the opt-out now that the underlying issue is fixed --- .../test/method_channel_device_info_test.dart | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart b/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart index 03ff4b53cda9..b257109fe2f6 100644 --- a/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart +++ b/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(cyanglaz): Remove once https://github.com/flutter/flutter/issues/59879 is fixed. -// @dart = 2.9 - import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:device_info_platform_interface/device_info_platform_interface.dart'; @@ -14,7 +11,7 @@ void main() { TestWidgetsFlutterBinding.ensureInitialized(); group("$MethodChannelDeviceInfo", () { - MethodChannelDeviceInfo methodChannelDeviceInfo; + late MethodChannelDeviceInfo methodChannelDeviceInfo; setUp(() async { methodChannelDeviceInfo = MethodChannelDeviceInfo(); @@ -162,7 +159,7 @@ void main() { group( "$MethodChannelDeviceInfo handles null value in the map returned from method channel", () { - MethodChannelDeviceInfo methodChannelDeviceInfo; + late MethodChannelDeviceInfo methodChannelDeviceInfo; setUp(() async { methodChannelDeviceInfo = MethodChannelDeviceInfo(); @@ -261,7 +258,7 @@ void main() { }); group("$MethodChannelDeviceInfo handles method channel returns null", () { - MethodChannelDeviceInfo methodChannelDeviceInfo; + late MethodChannelDeviceInfo methodChannelDeviceInfo; setUp(() async { methodChannelDeviceInfo = MethodChannelDeviceInfo(); @@ -329,7 +326,7 @@ void main() { }); group("$MethodChannelDeviceInfo android handles null values in list", () { - MethodChannelDeviceInfo methodChannelDeviceInfo; + late MethodChannelDeviceInfo methodChannelDeviceInfo; setUp(() async { methodChannelDeviceInfo = MethodChannelDeviceInfo(); @@ -339,9 +336,9 @@ void main() { switch (methodCall.method) { case 'getAndroidDeviceInfo': return ({ - "supported32BitAbis": ["x86", null], - "supported64BitAbis": ["x86_64", null], - "supportedAbis": ["x86_64", "x86", null], + "supported32BitAbis": ["x86"], + "supported64BitAbis": ["x86_64"], + "supportedAbis": ["x86_64", "x86"], "systemFeatures": [ "android.hardware.sensor.proximity", "android.software.adoptable_storage", @@ -349,7 +346,6 @@ void main() { "android.hardware.faketouch", "android.software.backup", "android.hardware.touchscreen", - null ], }); default: From 9509b7a623a11c4611f83607324b0a231f0493ca Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Tue, 2 Mar 2021 17:48:26 -0800 Subject: [PATCH 0241/1565] [webview_flutter] Run CocoaPods iOS tests in RunnerUITests target (#3664) --- .cirrus.yml | 2 +- .gitignore | 1 + packages/webview_flutter/CHANGELOG.md | 4 ++ packages/webview_flutter/example/ios/Podfile | 45 +++++++++++++ .../ios/Runner.xcodeproj/project.pbxproj | 64 +++++++++++-------- .../xcshareddata/xcschemes/Runner.xcscheme | 4 +- .../xcschemes/RunnerUITests.xcscheme | 52 +++++++++++++++ .../Info.plist | 0 .../ios/webview_flutter.podspec | 2 +- packages/webview_flutter/pubspec.yaml | 2 +- 10 files changed, 145 insertions(+), 31 deletions(-) create mode 100644 packages/webview_flutter/example/ios/Podfile create mode 100644 packages/webview_flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/RunnerUITests.xcscheme rename packages/webview_flutter/example/ios/{webview_flutter_exampleTests => RunnerUITests}/Info.plist (100%) diff --git a/.cirrus.yml b/.cirrus.yml index 118802b74810..d7aebddb92cf 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -179,7 +179,7 @@ task: - name: build-ipas+drive-examples env: PATH: $PATH:/usr/local/bin - PLUGINS_TO_SKIP_XCTESTS: "battery/battery,camera/camera,connectivity/connectivity,device_info/device_info,espresso,google_maps_flutter/google_maps_flutter,google_sign_in/google_sign_in,in_app_purchase,integration_test,ios_platform_images,local_auth,package_info,path_provider/path_provider,sensors,shared_preferences/shared_preferences,url_launcher/url_launcher,video_player/video_player,webview_flutter,wifi_info_flutter/wifi_info_flutter" + PLUGINS_TO_SKIP_XCTESTS: "battery/battery,camera/camera,connectivity/connectivity,device_info/device_info,espresso,google_maps_flutter/google_maps_flutter,google_sign_in/google_sign_in,in_app_purchase,integration_test,ios_platform_images,local_auth,package_info,path_provider/path_provider,sensors,shared_preferences/shared_preferences,url_launcher/url_launcher,video_player/video_player,wifi_info_flutter/wifi_info_flutter" matrix: PLUGIN_SHARDING: "--shardIndex 0 --shardCount 4" PLUGIN_SHARDING: "--shardIndex 1 --shardCount 4" diff --git a/.gitignore b/.gitignore index 3582a15fae57..823f9031d960 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ Pods/ .symlinks/ **/Flutter/App.framework/ **/Flutter/ephemeral/ +**/Flutter/Flutter.podspec **/Flutter/Flutter.framework/ **/Flutter/Generated.xcconfig **/Flutter/flutter_assets/ diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index fb448d245127..139f120f12b2 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +* Run CocoaPods iOS tests in RunnerUITests target + ## 2.0.0 * Migration to null-safety. diff --git a/packages/webview_flutter/example/ios/Podfile b/packages/webview_flutter/example/ios/Podfile new file mode 100644 index 000000000000..ce7f8a5df02b --- /dev/null +++ b/packages/webview_flutter/example/ios/Podfile @@ -0,0 +1,45 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + + target 'RunnerUITests' do + inherit! :search_paths + + # Matches test_spec dependency. + pod 'OCMock', '3.5' + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/webview_flutter/example/ios/Runner.xcodeproj/project.pbxproj b/packages/webview_flutter/example/ios/Runner.xcodeproj/project.pbxproj index 33e9d9745bba..d651613f32dc 100644 --- a/packages/webview_flutter/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/webview_flutter/example/ios/Runner.xcodeproj/project.pbxproj @@ -17,6 +17,7 @@ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 9D26F6F82D91F92CC095EBA9 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B845D8FBDE0AAD6BE1A0386 /* libPods-Runner.a */; }; + EE189BB43C38EE5DE05135A7 /* libPods-RunnerUITests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0EBE6A98F0F7B17A8E813670 /* libPods-RunnerUITests.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -43,12 +44,14 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 06E410020C7D35382771541C /* Pods-RunnerUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerUITests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RunnerUITests/Pods-RunnerUITests.release.xcconfig"; sourceTree = ""; }; + 0EBE6A98F0F7B17A8E813670 /* libPods-RunnerUITests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RunnerUITests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 127772EEA7782174BE0D74B5 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 686B4BF82548DBC7000AEA36 /* FLTWKNavigationDelegateTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FLTWKNavigationDelegateTests.m; path = ../../../ios/Tests/FLTWKNavigationDelegateTests.m; sourceTree = ""; }; - 68BDCAE923C3F7CB00D9C032 /* webview_flutter_exampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = webview_flutter_exampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 68BDCAE923C3F7CB00D9C032 /* RunnerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 68BDCAED23C3F7CB00D9C032 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 68BDCAF523C3F97800D9C032 /* FLTWebViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FLTWebViewTests.m; path = ../../../ios/Tests/FLTWebViewTests.m; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; @@ -64,6 +67,7 @@ 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; C475C484BD510DD9CB2E403C /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + DA434001E038D9F8CFB0EDEC /* Pods-RunnerUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerUITests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RunnerUITests/Pods-RunnerUITests.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -71,6 +75,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + EE189BB43C38EE5DE05135A7 /* libPods-RunnerUITests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -85,14 +90,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 68BDCAEA23C3F7CB00D9C032 /* webview_flutter_exampleTests */ = { + 68BDCAEA23C3F7CB00D9C032 /* RunnerUITests */ = { isa = PBXGroup; children = ( 686B4BF82548DBC7000AEA36 /* FLTWKNavigationDelegateTests.m */, 68BDCAF523C3F97800D9C032 /* FLTWebViewTests.m */, 68BDCAED23C3F7CB00D9C032 /* Info.plist */, ); - path = webview_flutter_exampleTests; + path = RunnerUITests; sourceTree = ""; }; 9740EEB11CF90186004384FC /* Flutter */ = { @@ -111,7 +116,7 @@ children = ( 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, - 68BDCAEA23C3F7CB00D9C032 /* webview_flutter_exampleTests */, + 68BDCAEA23C3F7CB00D9C032 /* RunnerUITests */, 97C146EF1CF9000F007C117D /* Products */, C6FFB52F5C2B8A41A7E39DE2 /* Pods */, B6736FC417BDCCDA377E779D /* Frameworks */, @@ -122,7 +127,7 @@ isa = PBXGroup; children = ( 97C146EE1CF9000F007C117D /* Runner.app */, - 68BDCAE923C3F7CB00D9C032 /* webview_flutter_exampleTests.xctest */, + 68BDCAE923C3F7CB00D9C032 /* RunnerUITests.xctest */, ); name = Products; sourceTree = ""; @@ -155,6 +160,7 @@ isa = PBXGroup; children = ( 8B845D8FBDE0AAD6BE1A0386 /* libPods-Runner.a */, + 0EBE6A98F0F7B17A8E813670 /* libPods-RunnerUITests.a */, ); name = Frameworks; sourceTree = ""; @@ -164,6 +170,8 @@ children = ( 127772EEA7782174BE0D74B5 /* Pods-Runner.debug.xcconfig */, C475C484BD510DD9CB2E403C /* Pods-Runner.release.xcconfig */, + DA434001E038D9F8CFB0EDEC /* Pods-RunnerUITests.debug.xcconfig */, + 06E410020C7D35382771541C /* Pods-RunnerUITests.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -171,10 +179,11 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 68BDCAE823C3F7CB00D9C032 /* webview_flutter_exampleTests */ = { + 68BDCAE823C3F7CB00D9C032 /* RunnerUITests */ = { isa = PBXNativeTarget; - buildConfigurationList = 68BDCAF223C3F7CB00D9C032 /* Build configuration list for PBXNativeTarget "webview_flutter_exampleTests" */; + buildConfigurationList = 68BDCAF223C3F7CB00D9C032 /* Build configuration list for PBXNativeTarget "RunnerUITests" */; buildPhases = ( + 53FD4CBDD9756D74B5A3B4C1 /* [CP] Check Pods Manifest.lock */, 68BDCAE523C3F7CB00D9C032 /* Sources */, 68BDCAE623C3F7CB00D9C032 /* Frameworks */, 68BDCAE723C3F7CB00D9C032 /* Resources */, @@ -184,9 +193,9 @@ dependencies = ( 68BDCAEF23C3F7CB00D9C032 /* PBXTargetDependency */, ); - name = webview_flutter_exampleTests; + name = RunnerUITests; productName = webview_flutter_exampleTests; - productReference = 68BDCAE923C3F7CB00D9C032 /* webview_flutter_exampleTests.xctest */; + productReference = 68BDCAE923C3F7CB00D9C032 /* RunnerUITests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; 97C146ED1CF9000F007C117D /* Runner */ = { @@ -200,7 +209,6 @@ 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - A1F14D6FD37A3C5047F5A5AD /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -243,7 +251,7 @@ projectRoot = ""; targets = ( 97C146ED1CF9000F007C117D /* Runner */, - 68BDCAE823C3F7CB00D9C032 /* webview_flutter_exampleTests */, + 68BDCAE823C3F7CB00D9C032 /* RunnerUITests */, ); }; /* End PBXProject section */ @@ -284,37 +292,41 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin\n"; }; - 9740EEB61CF901F6004384FC /* Run Script */ = { + 53FD4CBDD9756D74B5A3B4C1 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( ); - name = "Run Script"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerUITests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; }; - A1F14D6FD37A3C5047F5A5AD /* [CP] Embed Pods Frameworks */ = { + 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", - "${PODS_ROOT}/../Flutter/Flutter.framework", ); - name = "[CP] Embed Pods Frameworks"; + name = "Run Script"; outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; B71376B4FB8384EF9D5F3F84 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; @@ -388,7 +400,7 @@ /* Begin XCBuildConfiguration section */ 68BDCAF023C3F7CB00D9C032 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + baseConfigurationReference = DA434001E038D9F8CFB0EDEC /* Pods-RunnerUITests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -398,7 +410,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = webview_flutter_exampleTests/Info.plist; + INFOPLIST_FILE = RunnerUITests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 13.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; @@ -412,7 +424,7 @@ }; 68BDCAF123C3F7CB00D9C032 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + baseConfigurationReference = 06E410020C7D35382771541C /* Pods-RunnerUITests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -422,7 +434,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = webview_flutter_exampleTests/Info.plist; + INFOPLIST_FILE = RunnerUITests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 13.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_FAST_MATH = YES; @@ -590,7 +602,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 68BDCAF223C3F7CB00D9C032 /* Build configuration list for PBXNativeTarget "webview_flutter_exampleTests" */ = { + 68BDCAF223C3F7CB00D9C032 /* Build configuration list for PBXNativeTarget "RunnerUITests" */ = { isa = XCConfigurationList; buildConfigurations = ( 68BDCAF023C3F7CB00D9C032 /* Debug */, diff --git a/packages/webview_flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/webview_flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 7bcb47d19031..bcb1de689917 100644 --- a/packages/webview_flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/webview_flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -42,8 +42,8 @@ diff --git a/packages/webview_flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/RunnerUITests.xcscheme b/packages/webview_flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/RunnerUITests.xcscheme new file mode 100644 index 000000000000..917be4f45bfa --- /dev/null +++ b/packages/webview_flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/RunnerUITests.xcscheme @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/webview_flutter/example/ios/webview_flutter_exampleTests/Info.plist b/packages/webview_flutter/example/ios/RunnerUITests/Info.plist similarity index 100% rename from packages/webview_flutter/example/ios/webview_flutter_exampleTests/Info.plist rename to packages/webview_flutter/example/ios/RunnerUITests/Info.plist diff --git a/packages/webview_flutter/ios/webview_flutter.podspec b/packages/webview_flutter/ios/webview_flutter.podspec index 469195ae6449..066dfaacbfb9 100644 --- a/packages/webview_flutter/ios/webview_flutter.podspec +++ b/packages/webview_flutter/ios/webview_flutter.podspec @@ -19,7 +19,7 @@ Downloaded by pub (not CocoaPods). s.dependency 'Flutter' s.platform = :ios, '8.0' - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } s.test_spec 'Tests' do |test_spec| test_spec.source_files = 'Tests/**/*' diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml index bae19fd8b726..0640386c517d 100644 --- a/packages/webview_flutter/pubspec.yaml +++ b/packages/webview_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: webview_flutter description: A Flutter plugin that provides a WebView widget on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter -version: 2.0.0 +version: 2.0.1 environment: sdk: ">=2.12.0-259.9.beta <3.0.0" From 2eba00a05cc147cd89f48657d881edf21cd406db Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Tue, 2 Mar 2021 17:48:43 -0800 Subject: [PATCH 0242/1565] [image_picker] Run CocoaPods iOS tests in RunnerUITests target (#3663) --- .../image_picker/image_picker/CHANGELOG.md | 4 + .../image_picker/example/ios/Podfile | 42 +++++ .../ios/Runner.xcodeproj/project.pbxproj | 175 +++--------------- .../contents.xcworkspacedata | 5 +- .../xcshareddata/xcschemes/Runner.xcscheme | 6 +- .../xcschemes/RunnerUITests.xcscheme | 52 ++++++ .../image_picker/ios/image_picker.podspec | 2 +- .../image_picker/image_picker/pubspec.yaml | 2 +- 8 files changed, 133 insertions(+), 155 deletions(-) create mode 100644 packages/image_picker/image_picker/example/ios/Podfile create mode 100644 packages/image_picker/image_picker/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/RunnerUITests.xcscheme diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md index 4673c01f506e..7be13a574a77 100644 --- a/packages/image_picker/image_picker/CHANGELOG.md +++ b/packages/image_picker/image_picker/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.2 + +* Run CocoaPods iOS tests in RunnerUITests target + ## 0.7.1 * Update platform_plugin_interface version requirement. diff --git a/packages/image_picker/image_picker/example/ios/Podfile b/packages/image_picker/image_picker/example/ios/Podfile new file mode 100644 index 000000000000..48f7bbc93cb5 --- /dev/null +++ b/packages/image_picker/image_picker/example/ios/Podfile @@ -0,0 +1,42 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + + target 'RunnerUITests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/project.pbxproj b/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/project.pbxproj index be3d55f406bf..492dd014ce6d 100644 --- a/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/project.pbxproj @@ -28,13 +28,6 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 6800491C2280D368006DD6AB /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 97C146E61CF9000F007C117D /* Project object */; - proxyType = 1; - remoteGlobalIDString = 97C146ED1CF9000F007C117D; - remoteInfo = Runner; - }; 6801C83B2555D726009DAF8D /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 97C146E61CF9000F007C117D /* Project object */; @@ -58,12 +51,12 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 15BE72415096DFE5D077E563 /* Pods-RunnerUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerUITests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RunnerUITests/Pods-RunnerUITests.debug.xcconfig"; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 515A7EC9B4C971C01E672CF8 /* Pods-RunnerUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerUITests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RunnerUITests/Pods-RunnerUITests.release.xcconfig"; sourceTree = ""; }; 5A9D31B91557877A0E8EF3E7 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 5C9512FF1EC38BD300040975 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 5C9513001EC38BD300040975 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 680049172280D368006DD6AB /* image_picker_exampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = image_picker_exampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 6800491B2280D368006DD6AB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 680049252280D736006DD6AB /* MetaDataUtilTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = MetaDataUtilTests.m; path = ../../../ios/Tests/MetaDataUtilTests.m; sourceTree = ""; }; 680049352280F2B8006DD6AB /* pngImage.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pngImage.png; sourceTree = ""; }; 680049362280F2B8006DD6AB /* jpgImage.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = jpgImage.jpg; sourceTree = ""; }; @@ -86,23 +79,18 @@ 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 9FC8F0E8229FA49E00C8D58F /* gifImage.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = gifImage.gif; sourceTree = ""; }; 9FC8F0ED229FB90B00C8D58F /* ImageUtilTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ImageUtilTests.m; path = ../../../ios/Tests/ImageUtilTests.m; sourceTree = ""; }; + A908FAEEA2A9B26D903C09C5 /* libPods-RunnerUITests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RunnerUITests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; EC32F6993F4529982D9519F1 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; F78AF3172342D9D7008449C7 /* ImagePickerTestImages.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ImagePickerTestImages.h; path = ../../../ios/Tests/ImagePickerTestImages.h; sourceTree = ""; }; F78AF3182342D9D7008449C7 /* ImagePickerTestImages.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ImagePickerTestImages.m; path = ../../../ios/Tests/ImagePickerTestImages.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 680049142280D368006DD6AB /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 6801C8332555D726009DAF8D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F10E2DB84567A50A8721C9C7 /* libPods-RunnerUITests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -117,20 +105,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 680049182280D368006DD6AB /* image_picker_exampleTests */ = { - isa = PBXGroup; - children = ( - 6800491B2280D368006DD6AB /* Info.plist */, - 9FC8F0ED229FB90B00C8D58F /* ImageUtilTests.m */, - 680049252280D736006DD6AB /* MetaDataUtilTests.m */, - 68F4B463228B3AB500C25614 /* PhotoAssetUtilTests.m */, - F78AF3172342D9D7008449C7 /* ImagePickerTestImages.h */, - F78AF3182342D9D7008449C7 /* ImagePickerTestImages.m */, - 68B9AF71243E4B3F00927CE4 /* ImagePickerPluginTests.m */, - ); - path = image_picker_exampleTests; - sourceTree = ""; - }; 680049282280E33D006DD6AB /* TestImages */ = { isa = PBXGroup; children = ( @@ -145,6 +119,12 @@ isa = PBXGroup; children = ( 6801C8382555D726009DAF8D /* ImagePickerFromGalleryUITests.m */, + 9FC8F0ED229FB90B00C8D58F /* ImageUtilTests.m */, + 680049252280D736006DD6AB /* MetaDataUtilTests.m */, + 68F4B463228B3AB500C25614 /* PhotoAssetUtilTests.m */, + F78AF3172342D9D7008449C7 /* ImagePickerTestImages.h */, + F78AF3182342D9D7008449C7 /* ImagePickerTestImages.m */, + 68B9AF71243E4B3F00927CE4 /* ImagePickerPluginTests.m */, 6801C83A2555D726009DAF8D /* Info.plist */, ); path = RunnerUITests; @@ -155,6 +135,8 @@ children = ( 6801632E632668F4349764C9 /* Pods-Runner.debug.xcconfig */, 5A9D31B91557877A0E8EF3E7 /* Pods-Runner.release.xcconfig */, + 15BE72415096DFE5D077E563 /* Pods-RunnerUITests.debug.xcconfig */, + 515A7EC9B4C971C01E672CF8 /* Pods-RunnerUITests.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -176,7 +158,6 @@ 680049282280E33D006DD6AB /* TestImages */, 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, - 680049182280D368006DD6AB /* image_picker_exampleTests */, 6801C8372555D726009DAF8D /* RunnerUITests */, 97C146EF1CF9000F007C117D /* Products */, 840012C8B5EDBCF56B0E4AC1 /* Pods */, @@ -188,7 +169,6 @@ isa = PBXGroup; children = ( 97C146EE1CF9000F007C117D /* Runner.app */, - 680049172280D368006DD6AB /* image_picker_exampleTests.xctest */, 6801C8362555D726009DAF8D /* RunnerUITests.xctest */, ); name = Products; @@ -222,6 +202,7 @@ isa = PBXGroup; children = ( EC32F6993F4529982D9519F1 /* libPods-Runner.a */, + A908FAEEA2A9B26D903C09C5 /* libPods-RunnerUITests.a */, ); name = Frameworks; sourceTree = ""; @@ -229,28 +210,11 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 680049162280D368006DD6AB /* image_picker_exampleTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6800491E2280D368006DD6AB /* Build configuration list for PBXNativeTarget "image_picker_exampleTests" */; - buildPhases = ( - 680049132280D368006DD6AB /* Sources */, - 680049142280D368006DD6AB /* Frameworks */, - 680049152280D368006DD6AB /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 6800491D2280D368006DD6AB /* PBXTargetDependency */, - ); - name = image_picker_exampleTests; - productName = image_picker_exampleTests; - productReference = 680049172280D368006DD6AB /* image_picker_exampleTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; 6801C8352555D726009DAF8D /* RunnerUITests */ = { isa = PBXNativeTarget; buildConfigurationList = 6801C83F2555D726009DAF8D /* Build configuration list for PBXNativeTarget "RunnerUITests" */; buildPhases = ( + 4F8C1F500AF4DCAB62651A1E /* [CP] Check Pods Manifest.lock */, 6801C8322555D726009DAF8D /* Sources */, 6801C8332555D726009DAF8D /* Frameworks */, 6801C8342555D726009DAF8D /* Resources */, @@ -275,7 +239,6 @@ 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, - 95BB15E9E1769C0D146AA592 /* [CP] Embed Pods Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, ); buildRules = ( @@ -297,11 +260,6 @@ LastUpgradeCheck = 1100; ORGANIZATIONNAME = "The Chromium Authors"; TargetAttributes = { - 680049162280D368006DD6AB = { - CreatedOnToolsVersion = 10.2.1; - ProvisioningStyle = Automatic; - TestTargetID = 97C146ED1CF9000F007C117D; - }; 6801C8352555D726009DAF8D = { CreatedOnToolsVersion = 11.7; ProvisioningStyle = Automatic; @@ -331,31 +289,22 @@ projectRoot = ""; targets = ( 97C146ED1CF9000F007C117D /* Runner */, - 680049162280D368006DD6AB /* image_picker_exampleTests */, 6801C8352555D726009DAF8D /* RunnerUITests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - 680049152280D368006DD6AB /* Resources */ = { + 6801C8342555D726009DAF8D /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 680049272280D79A006DD6AB /* Assets.xcassets in Resources */, 9FC8F0EC229FA68500C8D58F /* gifImage.gif in Resources */, 680049382280F2B9006DD6AB /* pngImage.png in Resources */, 680049392280F2B9006DD6AB /* jpgImage.jpg in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 6801C8342555D726009DAF8D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 97C146EC1CF9000F007C117D /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -384,22 +333,26 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - 95BB15E9E1769C0D146AA592 /* [CP] Embed Pods Frameworks */ = { + 4F8C1F500AF4DCAB62651A1E /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", - "${PODS_ROOT}/../Flutter/Flutter.framework", + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( ); - name = "[CP] Embed Pods Frameworks"; outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", + "$(DERIVED_FILE_DIR)/Pods-RunnerUITests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; 9740EEB61CF901F6004384FC /* Run Script */ = { @@ -437,10 +390,11 @@ /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 680049132280D368006DD6AB /* Sources */ = { + 6801C8322555D726009DAF8D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 6801C8392555D726009DAF8D /* ImagePickerFromGalleryUITests.m in Sources */, 9FC8F0EE229FB90B00C8D58F /* ImageUtilTests.m in Sources */, F78AF3192342D9D7008449C7 /* ImagePickerTestImages.m in Sources */, 680049262280D736006DD6AB /* MetaDataUtilTests.m in Sources */, @@ -449,14 +403,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 6801C8322555D726009DAF8D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6801C8392555D726009DAF8D /* ImagePickerFromGalleryUITests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 97C146EA1CF9000F007C117D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -470,11 +416,6 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 6800491D2280D368006DD6AB /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 97C146ED1CF9000F007C117D /* Runner */; - targetProxy = 6800491C2280D368006DD6AB /* PBXContainerItemProxy */; - }; 6801C83C2555D726009DAF8D /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 97C146ED1CF9000F007C117D /* Runner */; @@ -502,59 +443,9 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ - 6800491F2280D368006DD6AB /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - INFOPLIST_FILE = image_picker_exampleTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "com.google.transformTest.image-picker-exampleTests"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner"; - }; - name = Debug; - }; - 680049202280D368006DD6AB /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - INFOPLIST_FILE = image_picker_exampleTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "com.google.transformTest.image-picker-exampleTests"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner"; - }; - name = Release; - }; 6801C83D2555D726009DAF8D /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -579,6 +470,7 @@ }; 6801C83E2555D726009DAF8D /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -753,15 +645,6 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 6800491E2280D368006DD6AB /* Build configuration list for PBXNativeTarget "image_picker_exampleTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6800491F2280D368006DD6AB /* Debug */, - 680049202280D368006DD6AB /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 6801C83F2555D726009DAF8D /* Build configuration list for PBXNativeTarget "RunnerUITests" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 21a3cc14c74e..919434a6254f 100755 --- a/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,9 +2,6 @@ - - + location = "self:"> diff --git a/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 7a9aea57bd9d..641cb8ccafa4 100755 --- a/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -41,9 +41,9 @@ skipped = "NO"> diff --git a/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/RunnerUITests.xcscheme b/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/RunnerUITests.xcscheme new file mode 100644 index 000000000000..1a97d9638346 --- /dev/null +++ b/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/RunnerUITests.xcscheme @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/image_picker/image_picker/ios/image_picker.podspec b/packages/image_picker/image_picker/ios/image_picker.podspec index 5c13cef272dd..f0c8aa47e1b2 100644 --- a/packages/image_picker/image_picker/ios/image_picker.podspec +++ b/packages/image_picker/image_picker/ios/image_picker.podspec @@ -18,7 +18,7 @@ Downloaded by pub (not CocoaPods). s.public_header_files = 'Classes/**/*.h' s.dependency 'Flutter' s.platform = :ios, '8.0' - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } s.test_spec 'Tests' do |test_spec| test_spec.source_files = 'Tests/**/*' diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index fb351b3ece75..562528466861 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker description: Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker -version: 0.7.1 +version: 0.7.2 flutter: plugin: From 65768856ba965f024cfd45638dd6bb49ceae0fa5 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 2 Mar 2021 18:59:04 -0800 Subject: [PATCH 0243/1565] [google_maps_flutter_web] update min flutter sdk version to 1.20.0 (#3662) --- .../google_maps_flutter/google_maps_flutter_web/CHANGELOG.md | 2 +- .../google_maps_flutter/google_maps_flutter_web/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md index f5e289cb19ae..4277d7b02769 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -1,6 +1,6 @@ ## 0.1.2 -* Add support for Custom Tiles. +* Update min Flutter SDK to 1.20.0. ## 0.1.1 diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index 83ac0fbdde5f..595ca20db78d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -33,4 +33,4 @@ dev_dependencies: environment: sdk: ">=2.3.0 <3.0.0" - flutter: ">=1.10.0" + flutter: ">=1.20.0" From 60d85fdcb24c4b7c3f350073e931077cbf3de30d Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Tue, 2 Mar 2021 19:27:48 -0800 Subject: [PATCH 0244/1565] Run static analyzer during xctest (#3667) --- .cirrus.yml | 4 +- CONTRIBUTING.md | 2 +- .../tool/lib/src/lint_podspecs_command.dart | 25 +-- script/tool/lib/src/xctest_command.dart | 104 +++++-------- .../tool/test/lint_podspecs_command_test.dart | 43 +----- script/tool/test/xctest_command_test.dart | 145 ++---------------- 6 files changed, 64 insertions(+), 259 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index d7aebddb92cf..ff8cc0ca3ad7 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -179,7 +179,7 @@ task: - name: build-ipas+drive-examples env: PATH: $PATH:/usr/local/bin - PLUGINS_TO_SKIP_XCTESTS: "battery/battery,camera/camera,connectivity/connectivity,device_info/device_info,espresso,google_maps_flutter/google_maps_flutter,google_sign_in/google_sign_in,in_app_purchase,integration_test,ios_platform_images,local_auth,package_info,path_provider/path_provider,sensors,shared_preferences/shared_preferences,url_launcher/url_launcher,video_player/video_player,wifi_info_flutter/wifi_info_flutter" + PLUGINS_TO_SKIP_XCTESTS: "integration_test" matrix: PLUGIN_SHARDING: "--shardIndex 0 --shardCount 4" PLUGIN_SHARDING: "--shardIndex 1 --shardCount 4" @@ -197,7 +197,7 @@ task: - flutter channel $CHANNEL - flutter upgrade - ./script/incremental_build.sh build-examples --ipa - - ./script/incremental_build.sh xctest --target RunnerUITests --skip $PLUGINS_TO_SKIP_XCTESTS --ios-destination "platform=iOS Simulator,name=iPhone 11,OS=14.3" + - ./script/incremental_build.sh xctest --skip $PLUGINS_TO_SKIP_XCTESTS --ios-destination "platform=iOS Simulator,name=iPhone 11,OS=latest" # `drive-examples` contains integration tests, which changes the UI of the application. # This UI change sometimes affects `xctest`. # So we run `drive-examples` after `xctest`, changing the order will result ci failure. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6c4abd0cb516..5a8a9ec5522f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -69,7 +69,7 @@ If XCUITests has not been set up for the plugin, follow these steps to set it up 1. Open /example/ios/Runner.xcworkspace using XCode. 1. Create a new "UI Testing Bundle". 1. In the target options window, populate details as following, then click on "Finish". - * In the "product name" field, type in "RunnerUITests" (this is the test target name our CI looks for.). + * In the "product name" field, type in "RunnerUITests". * In the "Team" field, select "None". * In the Organization Name field, type in "Flutter". This should usually be pre-populated. * In the organization identifer field, type in "com.google". This should usually be pre-populated. diff --git a/script/tool/lib/src/lint_podspecs_command.dart b/script/tool/lib/src/lint_podspecs_command.dart index 68fd4b61dd66..b10031162fee 100644 --- a/script/tool/lib/src/lint_podspecs_command.dart +++ b/script/tool/lib/src/lint_podspecs_command.dart @@ -14,8 +14,7 @@ import 'common.dart'; typedef void Print(Object object); -/// Lint the CocoaPod podspecs, run the static analyzer on iOS/macOS plugin -/// platform code, and run unit tests. +/// Lint the CocoaPod podspecs and run unit tests. /// /// See https://guides.cocoapods.org/terminal/commands.html#pod_lib_lint. class LintPodspecsCommand extends PluginCommand { @@ -35,10 +34,6 @@ class LintPodspecsCommand extends PluginCommand { help: 'Do not pass --allow-warnings flag to "pod lib lint" for podspecs with this basename (example: plugins with known warnings)', valueHelp: 'podspec_file_name'); - argParser.addMultiOption('no-analyze', - help: - 'Do not pass --analyze flag to "pod lib lint" for podspecs with this basename (example: plugins with known analyzer warnings)', - valueHelp: 'podspec_file_name'); } @override @@ -102,25 +97,17 @@ class LintPodspecsCommand extends PluginCommand { Future _lintPodspec(File podspec) async { // Do not run the static analyzer on plugins with known analyzer issues. final String podspecPath = podspec.path; - final bool runAnalyzer = !argResults['no-analyze'] - .contains(p.basenameWithoutExtension(podspecPath)); final String podspecBasename = p.basename(podspecPath); - if (runAnalyzer) { - _print('Linting and analyzing $podspecBasename'); - } else { - _print('Linting $podspecBasename'); - } + _print('Linting $podspecBasename'); // Lint plugin as framework (use_frameworks!). - final ProcessResult frameworkResult = await _runPodLint(podspecPath, - runAnalyzer: runAnalyzer, libraryLint: true); + final ProcessResult frameworkResult = await _runPodLint(podspecPath, libraryLint: true); _print(frameworkResult.stdout); _print(frameworkResult.stderr); // Lint plugin as library. - final ProcessResult libraryResult = await _runPodLint(podspecPath, - runAnalyzer: runAnalyzer, libraryLint: false); + final ProcessResult libraryResult = await _runPodLint(podspecPath, libraryLint: false); _print(libraryResult.stdout); _print(libraryResult.stderr); @@ -128,7 +115,7 @@ class LintPodspecsCommand extends PluginCommand { } Future _runPodLint(String podspecPath, - {bool runAnalyzer, bool libraryLint}) async { + {bool libraryLint}) async { final bool allowWarnings = argResults['ignore-warnings'] .contains(p.basenameWithoutExtension(podspecPath)); final List arguments = [ @@ -136,10 +123,10 @@ class LintPodspecsCommand extends PluginCommand { 'lint', podspecPath, if (allowWarnings) '--allow-warnings', - if (runAnalyzer) '--analyze', if (libraryLint) '--use-libraries' ]; + _print('Running "pod ${arguments.join(' ')}"'); return processRunner.run('pod', arguments, workingDir: packagesDir, stdoutEncoding: utf8, stderrEncoding: utf8); } diff --git a/script/tool/lib/src/xctest_command.dart b/script/tool/lib/src/xctest_command.dart index d90b7a8fbfea..a4d03360b292 100644 --- a/script/tool/lib/src/xctest_command.dart +++ b/script/tool/lib/src/xctest_command.dart @@ -12,17 +12,15 @@ import 'package:path/path.dart' as p; import 'common.dart'; const String _kiOSDestination = 'ios-destination'; -const String _kTarget = 'target'; const String _kSkip = 'skip'; const String _kXcodeBuildCommand = 'xcodebuild'; const String _kXCRunCommand = 'xcrun'; const String _kFoundNoSimulatorsMessage = 'Cannot find any available simulators, tests failed'; -/// The command to run iOS' XCTests in plugins, this should work for both XCUnitTest and XCUITest targets. -/// The tests target have to be added to the xcode project of the example app. Usually at "example/ios/Runner.xcodeproj". -/// The command takes a "-target" argument which has to match the target of the test target. -/// For information on how to add test target in an xcode project, see https://developer.apple.com/library/archive/documentation/ToolsLanguages/Conceptual/Xcode_Overview/UnitTesting.html +/// The command to run iOS XCTests in plugins, this should work for both XCUnitTest and XCUITest targets. +/// The tests target have to be added to the xcode project of the example app. Usually at "example/ios/Runner.xcworkspace". +/// The static analyzer is also run. class XCTestCommand extends PluginCommand { XCTestCommand( Directory packagesDir, @@ -36,10 +34,6 @@ class XCTestCommand extends PluginCommand { 'this is passed to the `-destination` argument in xcodebuild command.\n' 'See https://developer.apple.com/library/archive/technotes/tn2339/_index.html#//apple_ref/doc/uid/DTS40014588-CH1-UNIT for details on how to specify the destination.', ); - argParser.addOption(_kTarget, - help: 'The test target.\n' - 'This is the xcode project test target. This is passed to the `-scheme` argument in the xcodebuild command. \n' - 'See https://developer.apple.com/library/archive/technotes/tn2339/_index.html#//apple_ref/doc/uid/DTS40014588-CH1-UNIT for details on how to specify the scheme'); argParser.addMultiOption(_kSkip, help: 'Plugins to skip while running this command. \n'); } @@ -49,17 +43,10 @@ class XCTestCommand extends PluginCommand { @override final String description = 'Runs the xctests in the iOS example apps.\n\n' - 'This command requires "flutter" to be in your path.'; + 'This command requires "flutter" and "xcrun" to be in your path.'; @override Future run() async { - if (argResults[_kTarget] == null) { - // TODO(cyanglaz): Automatically find all the available testing schemes if this argument is not specified. - // https://github.com/flutter/flutter/issues/68419 - print('--$_kTarget must be specified'); - throw ToolExit(1); - } - String destination = argResults[_kiOSDestination]; if (destination == null) { String simulatorId = await _findAvailableIphoneSimulator(); @@ -72,7 +59,6 @@ class XCTestCommand extends PluginCommand { checkSharding(); - final String target = argResults[_kTarget]; final List skipped = argResults[_kSkip]; List failingPackages = []; @@ -92,57 +78,14 @@ class XCTestCommand extends PluginCommand { continue; } for (Directory example in getExamplesForPlugin(plugin)) { - // Look for the test scheme in the example app. - print('Look for target named: $_kTarget ...'); - final List findSchemeArgs = [ - '-project', - 'ios/Runner.xcodeproj', - '-list', - '-json' - ]; - final String completeFindSchemeCommand = - '$_kXcodeBuildCommand ${findSchemeArgs.join(' ')}'; - print(completeFindSchemeCommand); - final io.ProcessResult xcodeprojListResult = await processRunner - .run(_kXcodeBuildCommand, findSchemeArgs, workingDir: example); - if (xcodeprojListResult.exitCode != 0) { - print('Error occurred while running "$completeFindSchemeCommand":\n' - '${xcodeprojListResult.stderr}'); - failingPackages.add(packageName); - print('\n\n'); - continue; - } - - final String xcodeprojListOutput = xcodeprojListResult.stdout; - Map xcodeprojListOutputJson = - jsonDecode(xcodeprojListOutput); - if (!xcodeprojListOutputJson['project']['targets'].contains(target)) { - failingPackages.add(packageName); - print('$target not configured for $packageName, test failed.'); - print( - 'Please check the scheme for the test target if it matches the name $target.\n' - 'If this plugin does not have an XCTest target, use the $_kSkip flag in the $name command to skip the plugin.'); - print('\n\n'); - continue; + // Running tests and static analyzer. + print('Running tests and analyzer for $packageName ...'); + int exitCode = await _runTests(true, destination, example); + // 66 = there is no test target (this fails fast). Try again with just the analyzer. + if (exitCode == 66) { + print('Tests not found for $packageName, running analyzer only...'); + exitCode = await _runTests(false, destination, example); } - // Found the scheme, running tests - print('Running XCTests:$target for $packageName ...'); - final List xctestArgs = [ - 'test', - '-workspace', - 'ios/Runner.xcworkspace', - '-scheme', - target, - '-destination', - destination, - 'CODE_SIGN_IDENTITY=""', - 'CODE_SIGNING_REQUIRED=NO' - ]; - final String completeTestCommand = - '$_kXcodeBuildCommand ${xctestArgs.join(' ')}'; - print(completeTestCommand); - final int exitCode = await processRunner - .runAndStream(_kXcodeBuildCommand, xctestArgs, workingDir: example); if (exitCode == 0) { print('Successfully ran xctest for $packageName'); } else { @@ -164,6 +107,31 @@ class XCTestCommand extends PluginCommand { } } + Future _runTests(bool runTests, String destination, Directory example) { + final List xctestArgs = [ + _kXcodeBuildCommand, + if (runTests) + 'test', + 'analyze', + '-workspace', + 'ios/Runner.xcworkspace', + '-configuration', + 'Debug', + '-scheme', + 'Runner', + '-destination', + destination, + 'CODE_SIGN_IDENTITY=""', + 'CODE_SIGNING_REQUIRED=NO', + 'GCC_TREAT_WARNINGS_AS_ERRORS=YES', + ]; + final String completeTestCommand = + '$_kXCRunCommand ${xctestArgs.join(' ')}'; + print(completeTestCommand); + return processRunner + .runAndStream(_kXCRunCommand, xctestArgs, workingDir: example, exitOnError: false); + } + Future _findAvailableIphoneSimulator() async { // Find the first available destination if not specified. final List findSimulatorsArguments = [ diff --git a/script/tool/test/lint_podspecs_command_test.dart b/script/tool/test/lint_podspecs_command_test.dart index 49d6ad4d8e20..1014dcd170be 100644 --- a/script/tool/test/lint_podspecs_command_test.dart +++ b/script/tool/test/lint_podspecs_command_test.dart @@ -81,7 +81,6 @@ void main() { 'lib', 'lint', p.join(plugin1Dir.path, 'ios', 'plugin1.podspec'), - '--analyze', '--use-libraries' ], mockPackagesDir.path), @@ -91,14 +90,13 @@ void main() { 'lib', 'lint', p.join(plugin1Dir.path, 'ios', 'plugin1.podspec'), - '--analyze', ], mockPackagesDir.path), ]), ); expect( - printedMessages, contains('Linting and analyzing plugin1.podspec')); + printedMessages, contains('Linting plugin1.podspec')); expect(printedMessages, contains('Foo')); expect(printedMessages, contains('Bar')); }); @@ -122,41 +120,6 @@ void main() { ); }); - test('skips analyzer for podspecs with known warnings', () async { - Directory plugin1Dir = - createFakePlugin('plugin1', withExtraFiles: >[ - ['plugin1.podspec'], - ]); - - await runner.run(['podspecs', '--no-analyze=plugin1']); - - expect( - processRunner.recordedCalls, - orderedEquals([ - ProcessCall('which', ['pod'], mockPackagesDir.path), - ProcessCall( - 'pod', - [ - 'lib', - 'lint', - p.join(plugin1Dir.path, 'plugin1.podspec'), - '--use-libraries' - ], - mockPackagesDir.path), - ProcessCall( - 'pod', - [ - 'lib', - 'lint', - p.join(plugin1Dir.path, 'plugin1.podspec'), - ], - mockPackagesDir.path), - ]), - ); - - expect(printedMessages, contains('Linting plugin1.podspec')); - }); - test('allow warnings for podspecs with known warnings', () async { Directory plugin1Dir = createFakePlugin('plugin1', withExtraFiles: >[ @@ -176,7 +139,6 @@ void main() { 'lint', p.join(plugin1Dir.path, 'plugin1.podspec'), '--allow-warnings', - '--analyze', '--use-libraries' ], mockPackagesDir.path), @@ -187,14 +149,13 @@ void main() { 'lint', p.join(plugin1Dir.path, 'plugin1.podspec'), '--allow-warnings', - '--analyze', ], mockPackagesDir.path), ]), ); expect( - printedMessages, contains('Linting and analyzing plugin1.podspec')); + printedMessages, contains('Linting plugin1.podspec')); }); }); } diff --git a/script/tool/test/xctest_command_test.dart b/script/tool/test/xctest_command_test.dart index 007c2e12188c..2b75ccde4210 100644 --- a/script/tool/test/xctest_command_test.dart +++ b/script/tool/test/xctest_command_test.dart @@ -8,7 +8,6 @@ import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/xctest_command.dart'; import 'package:test/test.dart'; -import 'package:flutter_plugin_tools/src/common.dart'; import 'mocks.dart'; import 'util.dart'; @@ -81,7 +80,6 @@ final _kDeviceListMap = { void main() { const String _kDestination = '--ios-destination'; - const String _kTarget = '--target'; const String _kSkip = '--skip'; group('test xctest_command', () { @@ -100,12 +98,6 @@ void main() { cleanupPackages(); }); - test('Not specifying --target throws', () async { - await expectLater( - () => runner.run(['xctest', _kDestination, 'a_destination']), - throwsA(const TypeMatcher())); - }); - test('skip if ios is not supported', () async { createFakePlugin('plugin', withExtraFiles: >[ @@ -123,8 +115,6 @@ void main() { processRunner.processToReturn = mockProcess; final List output = await runCapturingPrint(runner, [ 'xctest', - _kTarget, - 'foo_scheme', _kDestination, 'foo_destination' ]); @@ -134,106 +124,7 @@ void main() { cleanupPackages(); }); - test('running with correct scheme and destination, did not find scheme', - () async { - createFakePlugin('plugin', - withExtraFiles: >[ - ['example', 'test'], - ], - isIosPlugin: true); - - final Directory pluginExampleDirectory = - mockPackagesDir.childDirectory('plugin').childDirectory('example'); - - createFakePubspec(pluginExampleDirectory, isFlutter: true); - - final MockProcess mockProcess = MockProcess(); - mockProcess.exitCodeCompleter.complete(0); - processRunner.processToReturn = mockProcess; - processRunner.resultStdout = '{"project":{"targets":["bar_scheme"]}}'; - - await expectLater(() async { - final List output = await runCapturingPrint(runner, [ - 'xctest', - _kTarget, - 'foo_scheme', - _kDestination, - 'foo_destination' - ]); - expect(output, - contains('foo_scheme not configured for plugin, test failed.')); - expect( - processRunner.recordedCalls, - orderedEquals([ - ProcessCall('xcrun', ['simctl', 'list', '--json'], null), - ProcessCall( - 'xcodebuild', - [ - '-project', - 'ios/Runner.xcodeproj', - '-list', - '-json' - ], - pluginExampleDirectory.path), - ])); - }, throwsA(const TypeMatcher())); - cleanupPackages(); - }); - - test('running with correct scheme and destination, found scheme', () async { - createFakePlugin('plugin', - withExtraFiles: >[ - ['example', 'test'], - ], - isIosPlugin: true); - - final Directory pluginExampleDirectory = - mockPackagesDir.childDirectory('plugin').childDirectory('example'); - - createFakePubspec(pluginExampleDirectory, isFlutter: true); - - final MockProcess mockProcess = MockProcess(); - mockProcess.exitCodeCompleter.complete(0); - processRunner.processToReturn = mockProcess; - processRunner.resultStdout = - '{"project":{"targets":["bar_scheme", "foo_scheme"]}}'; - List output = await runCapturingPrint(runner, [ - 'xctest', - _kTarget, - 'foo_scheme', - _kDestination, - 'foo_destination' - ]); - - expect(output, contains('Successfully ran xctest for plugin')); - - expect( - processRunner.recordedCalls, - orderedEquals([ - ProcessCall( - 'xcodebuild', - ['-project', 'ios/Runner.xcodeproj', '-list', '-json'], - pluginExampleDirectory.path), - ProcessCall( - 'xcodebuild', - [ - 'test', - '-workspace', - 'ios/Runner.xcworkspace', - '-scheme', - 'foo_scheme', - '-destination', - 'foo_destination', - 'CODE_SIGN_IDENTITY=""', - 'CODE_SIGNING_REQUIRED=NO' - ], - pluginExampleDirectory.path), - ])); - - cleanupPackages(); - }); - - test('running with correct scheme and destination, skip 1 plugin', + test('running with correct destination, skip 1 plugin', () async { createFakePlugin('plugin1', withExtraFiles: >[ @@ -260,8 +151,6 @@ void main() { '{"project":{"targets":["bar_scheme", "foo_scheme"]}}'; List output = await runCapturingPrint(runner, [ 'xctest', - _kTarget, - 'foo_scheme', _kDestination, 'foo_destination', _kSkip, @@ -275,21 +164,22 @@ void main() { processRunner.recordedCalls, orderedEquals([ ProcessCall( - 'xcodebuild', - ['-project', 'ios/Runner.xcodeproj', '-list', '-json'], - pluginExampleDirectory2.path), - ProcessCall( - 'xcodebuild', + 'xcrun', [ + 'xcodebuild', 'test', + 'analyze', '-workspace', 'ios/Runner.xcworkspace', + '-configuration', + 'Debug', '-scheme', - 'foo_scheme', + 'Runner', '-destination', 'foo_destination', 'CODE_SIGN_IDENTITY=""', - 'CODE_SIGNING_REQUIRED=NO' + 'CODE_SIGNING_REQUIRED=NO', + 'GCC_TREAT_WARNINGS_AS_ERRORS=YES', ], pluginExampleDirectory2.path), ])); @@ -324,8 +214,6 @@ void main() { jsonEncode(schemeCommandResult..addAll(_kDeviceListMap)); await runner.run([ 'xctest', - _kTarget, - 'foo_scheme', ]); expect( @@ -333,21 +221,22 @@ void main() { orderedEquals([ ProcessCall('xcrun', ['simctl', 'list', '--json'], null), ProcessCall( - 'xcodebuild', - ['-project', 'ios/Runner.xcodeproj', '-list', '-json'], - pluginExampleDirectory.path), - ProcessCall( - 'xcodebuild', + 'xcrun', [ + 'xcodebuild', 'test', + 'analyze', '-workspace', 'ios/Runner.xcworkspace', + '-configuration', + 'Debug', '-scheme', - 'foo_scheme', + 'Runner', '-destination', 'id=1E76A0FD-38AC-4537-A989-EA639D7D012A', 'CODE_SIGN_IDENTITY=""', - 'CODE_SIGNING_REQUIRED=NO' + 'CODE_SIGNING_REQUIRED=NO', + 'GCC_TREAT_WARNINGS_AS_ERRORS=YES', ], pluginExampleDirectory.path), ])); From 025c8c199b3a0aad7c886b1288b94cf4bddf4de2 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Wed, 3 Mar 2021 10:56:12 -0800 Subject: [PATCH 0245/1565] Adopt Xcode 12 for podspec lints (#3653) --- .cirrus.yml | 20 ------------------- .../tool/lib/src/lint_podspecs_command.dart | 1 + .../tool/test/lint_podspecs_command_test.dart | 4 ++++ 3 files changed, 5 insertions(+), 20 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index ff8cc0ca3ad7..924cb63492a0 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -202,26 +202,6 @@ task: # This UI change sometimes affects `xctest`. # So we run `drive-examples` after `xctest`, changing the order will result ci failure. - ./script/incremental_build.sh drive-examples --ios - -task: - # Xcode 11 task - # TODO(cyanglaz): merge Xcode 11 task to Xcode 12 task when all the matrix can be run in Xcode 12. - # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins - only_if: $CIRRUS_TAG == '' - use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' - osx_instance: - image: catalina-xcode-11.3.1-flutter - upgrade_script: - - sudo gem install cocoapods - - flutter channel stable - - flutter upgrade - - flutter channel master - - flutter upgrade - - git fetch origin master - create_simulator_script: - - xcrun simctl list - - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-X com.apple.CoreSimulator.SimRuntime.iOS-13-3 | xargs xcrun simctl boot - matrix: - name: lint_darwin_plugins env: matrix: diff --git a/script/tool/lib/src/lint_podspecs_command.dart b/script/tool/lib/src/lint_podspecs_command.dart index b10031162fee..749d67ee5f16 100644 --- a/script/tool/lib/src/lint_podspecs_command.dart +++ b/script/tool/lib/src/lint_podspecs_command.dart @@ -122,6 +122,7 @@ class LintPodspecsCommand extends PluginCommand { 'lib', 'lint', podspecPath, + '--configuration=Debug', // Release targets unsupported arm64 simulators. Use Debug to only build against targeted x86_64 simulator devices. if (allowWarnings) '--allow-warnings', if (libraryLint) '--use-libraries' ]; diff --git a/script/tool/test/lint_podspecs_command_test.dart b/script/tool/test/lint_podspecs_command_test.dart index 1014dcd170be..e0411d5cffd1 100644 --- a/script/tool/test/lint_podspecs_command_test.dart +++ b/script/tool/test/lint_podspecs_command_test.dart @@ -81,6 +81,7 @@ void main() { 'lib', 'lint', p.join(plugin1Dir.path, 'ios', 'plugin1.podspec'), + '--configuration=Debug', '--use-libraries' ], mockPackagesDir.path), @@ -90,6 +91,7 @@ void main() { 'lib', 'lint', p.join(plugin1Dir.path, 'ios', 'plugin1.podspec'), + '--configuration=Debug', ], mockPackagesDir.path), ]), @@ -138,6 +140,7 @@ void main() { 'lib', 'lint', p.join(plugin1Dir.path, 'plugin1.podspec'), + '--configuration=Debug', '--allow-warnings', '--use-libraries' ], @@ -148,6 +151,7 @@ void main() { 'lib', 'lint', p.join(plugin1Dir.path, 'plugin1.podspec'), + '--configuration=Debug', '--allow-warnings', ], mockPackagesDir.path), From bc2514ebd824adb1c85709e53bc57235af7b5212 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Wed, 3 Mar 2021 15:07:07 -0800 Subject: [PATCH 0246/1565] [google_maps_flutter_web] Make google_maps_flutter_web work with latest plugins (#3673) Co-authored-by: David Iglesias Teixeira --- .../google_maps_flutter_web/CHANGELOG.md | 7 + .../lib/src/convert.dart | 167 ++---------------- .../lib/src/google_maps_controller.dart | 61 ++++--- .../lib/src/google_maps_flutter_web.dart | 54 ++++-- .../google_maps_flutter_web/pubspec.yaml | 16 +- .../google_maps_controller_integration.dart | 154 ++++++++-------- .../google_maps_plugin_integration.dart | 49 +++-- script/nnbd_plugins.sh | 4 +- 8 files changed, 224 insertions(+), 288 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md index 4277d7b02769..826f1ea53023 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.2.0 + +* Make this plugin compatible with the rest of null-safe plugins. +* Noop tile overlays methods, so they don't crash on web. + +**NOTE**: This plugin is **not** null-safe yet! + ## 0.1.2 * Update min Flutter SDK to 1.20.0. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index 95f481a9bdc5..5212679fb5fe 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -11,8 +11,6 @@ final _nullLatLngBounds = LatLngBounds( ); // Defaults taken from the Google Maps Platform SDK documentation. -final _defaultStrokeColor = Colors.black.value; -final _defaultFillColor = Colors.transparent.value; final _defaultCssColor = '#000000'; final _defaultCssOpacity = 0.0; @@ -59,41 +57,39 @@ double _getCssOpacity(Color color) { // buildingsEnabled seems to not have an equivalent in web // padding seems to behave differently in web than mobile. You can't move UI elements in web. gmaps.MapOptions _rawOptionsToGmapsOptions(Map rawOptions) { - Map optionsUpdate = rawOptions['options'] ?? {}; - gmaps.MapOptions options = gmaps.MapOptions(); - if (_mapTypeToMapTypeId.containsKey(optionsUpdate['mapType'])) { - options.mapTypeId = _mapTypeToMapTypeId[optionsUpdate['mapType']]; + if (_mapTypeToMapTypeId.containsKey(rawOptions['mapType'])) { + options.mapTypeId = _mapTypeToMapTypeId[rawOptions['mapType']]; } - if (optionsUpdate['minMaxZoomPreference'] != null) { + if (rawOptions['minMaxZoomPreference'] != null) { options - ..minZoom = optionsUpdate['minMaxZoomPreference'][0] - ..maxZoom = optionsUpdate['minMaxZoomPreference'][1]; + ..minZoom = rawOptions['minMaxZoomPreference'][0] + ..maxZoom = rawOptions['minMaxZoomPreference'][1]; } - if (optionsUpdate['cameraTargetBounds'] != null) { + if (rawOptions['cameraTargetBounds'] != null) { // Needs gmaps.MapOptions.restriction and gmaps.MapRestriction // see: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.restriction } - if (optionsUpdate['zoomControlsEnabled'] != null) { - options.zoomControl = optionsUpdate['zoomControlsEnabled']; + if (rawOptions['zoomControlsEnabled'] != null) { + options.zoomControl = rawOptions['zoomControlsEnabled']; } - if (optionsUpdate['styles'] != null) { - options.styles = optionsUpdate['styles']; + if (rawOptions['styles'] != null) { + options.styles = rawOptions['styles']; } - if (optionsUpdate['scrollGesturesEnabled'] == false || - optionsUpdate['zoomGesturesEnabled'] == false) { + if (rawOptions['scrollGesturesEnabled'] == false || + rawOptions['zoomGesturesEnabled'] == false) { options.gestureHandling = 'none'; } else { options.gestureHandling = 'auto'; } - // These don't have any optionUpdate entry, but they seem to be off in the native maps. + // These don't have any rawOptions entry, but they seem to be off in the native maps. options.mapTypeControl = false; options.fullscreenControl = false; options.streetViewControl = false; @@ -102,26 +98,21 @@ gmaps.MapOptions _rawOptionsToGmapsOptions(Map rawOptions) { } gmaps.MapOptions _applyInitialPosition( - Map rawOptions, + CameraPosition initialPosition, gmaps.MapOptions options, ) { // Adjust the initial position, if passed... - Map initialPosition = rawOptions['initialCameraPosition']; if (initialPosition != null) { - final position = CameraPosition.fromMap(initialPosition); - options.zoom = position.zoom; - options.center = - gmaps.LatLng(position.target.latitude, position.target.longitude); + options.zoom = initialPosition.zoom; + options.center = gmaps.LatLng( + initialPosition.target.latitude, initialPosition.target.longitude); } return options; } // Extracts the status of the traffic layer from the rawOptions map. bool _isTrafficLayerEnabled(Map rawOptions) { - if (rawOptions['options'] == null) { - return false; - } - return rawOptions['options']['trafficEnabled'] ?? false; + return rawOptions['trafficEnabled'] ?? false; } // Coverts the incoming JSON object into a List of MapTypeStyler objects. @@ -257,126 +248,6 @@ CameraPosition _gmViewportToCameraPosition(gmaps.GMap map) { ); } -Set _rawOptionsToInitialMarkers(Map rawOptions) { - final List> list = rawOptions['markersToAdd']; - Set markers = {}; - markers.addAll(list?.map((rawMarker) { - Offset offset; - LatLng position; - InfoWindow infoWindow; - BitmapDescriptor icon; - if (rawMarker['anchor'] != null) { - offset = Offset((rawMarker['anchor'][0]), (rawMarker['anchor'][1])); - } - if (rawMarker['position'] != null) { - position = LatLng.fromJson(rawMarker['position']); - } - if (rawMarker['infoWindow'] != null) { - final String title = rawMarker['infoWindow']['title']; - final String snippet = rawMarker['infoWindow']['snippet']; - if (title != null || snippet != null) { - infoWindow = InfoWindow( - title: title ?? '', - snippet: snippet ?? '', - ); - } - } - if (rawMarker['icon'] != null) { - icon = BitmapDescriptor.fromJson(rawMarker['icon']); - } - return Marker( - markerId: MarkerId(rawMarker['markerId']), - alpha: rawMarker['alpha'], - anchor: offset, - consumeTapEvents: rawMarker['consumeTapEvents'], - draggable: rawMarker['draggable'], - flat: rawMarker['flat'], - icon: icon, - infoWindow: infoWindow, - position: position ?? _nullLatLng, - rotation: rawMarker['rotation'], - visible: rawMarker['visible'], - zIndex: rawMarker['zIndex'], - ); - }) ?? - []); - return markers; -} - -Set _rawOptionsToInitialCircles(Map rawOptions) { - final List> list = rawOptions['circlesToAdd']; - Set circles = {}; - circles.addAll(list?.map((rawCircle) { - LatLng center; - if (rawCircle['center'] != null) { - center = LatLng.fromJson(rawCircle['center']); - } - return Circle( - circleId: CircleId(rawCircle['circleId']), - consumeTapEvents: rawCircle['consumeTapEvents'], - fillColor: Color(rawCircle['fillColor'] ?? _defaultFillColor), - center: center ?? _nullLatLng, - radius: rawCircle['radius'], - strokeColor: Color(rawCircle['strokeColor'] ?? _defaultStrokeColor), - strokeWidth: rawCircle['strokeWidth'], - visible: rawCircle['visible'], - zIndex: rawCircle['zIndex'], - ); - }) ?? - []); - return circles; -} - -// Unsupported on the web: endCap, jointType, patterns and startCap. -Set _rawOptionsToInitialPolylines(Map rawOptions) { - final List> list = rawOptions['polylinesToAdd']; - Set polylines = {}; - polylines.addAll(list?.map((rawPolyline) { - return Polyline( - polylineId: PolylineId(rawPolyline['polylineId']), - consumeTapEvents: rawPolyline['consumeTapEvents'], - color: Color(rawPolyline['color'] ?? _defaultStrokeColor), - geodesic: rawPolyline['geodesic'], - visible: rawPolyline['visible'], - zIndex: rawPolyline['zIndex'], - width: rawPolyline['width'], - points: rawPolyline['points'] - ?.map((rawPoint) => LatLng.fromJson(rawPoint)) - ?.toList(), - ); - }) ?? - []); - return polylines; -} - -Set _rawOptionsToInitialPolygons(Map rawOptions) { - final List> list = rawOptions['polygonsToAdd']; - Set polygons = {}; - - polygons.addAll(list?.map((rawPolygon) { - return Polygon( - polygonId: PolygonId(rawPolygon['polygonId']), - consumeTapEvents: rawPolygon['consumeTapEvents'], - fillColor: Color(rawPolygon['fillColor'] ?? _defaultFillColor), - geodesic: rawPolygon['geodesic'], - strokeColor: Color(rawPolygon['strokeColor'] ?? _defaultStrokeColor), - strokeWidth: rawPolygon['strokeWidth'], - visible: rawPolygon['visible'], - zIndex: rawPolygon['zIndex'], - points: rawPolygon['points'] - ?.map((rawPoint) => LatLng.fromJson(rawPoint)) - ?.toList(), - holes: rawPolygon['holes'] - ?.map>((List hole) => hole - ?.map((rawPoint) => LatLng.fromJson(rawPoint)) - ?.toList()) - ?.toList(), - ); - }) ?? - []); - return polygons; -} - // Convert plugin objects to gmaps.Options objects // TODO: Move to their appropriate objects, maybe make these copy constructors: // Marker.fromMarker(anotherMarker, moreOptions); @@ -550,7 +421,7 @@ gmaps.PolylineOptions _polylineOptionsFromPolyline( // Translates a [CameraUpdate] into operations on a [gmaps.GMap]. void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) { - final json = update.toJson(); + final json = update.toJson() as List; switch (json[0]) { case 'newCameraPosition': map.heading = json[1]['bearing']; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index 8195473ee6ba..a119f2aab9f2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -14,11 +14,14 @@ class GoogleMapController { // The internal ID of the map. Used to broadcast events, DOM IDs and everything where a unique ID is needed. final int _mapId; + final CameraPosition _initialCameraPosition; + final Set _markers; + final Set _polygons; + final Set _polylines; + final Set _circles; // The raw options passed by the user, before converting to gmaps. // Caching this allows us to re-create the map faithfully when needed. - Map _rawOptions = { - 'options': {}, - }; + Map _rawMapOptions = {}; // Creates the 'viewType' for the _widget String _getViewType(int mapId) => 'plugins.flutter.io/google_maps_$mapId'; @@ -68,10 +71,23 @@ class GoogleMapController { GoogleMapController({ @required int mapId, @required StreamController streamController, - @required Map rawOptions, - }) : this._mapId = mapId, - this._streamController = streamController, - this._rawOptions = rawOptions { + @required CameraPosition initialCameraPosition, + Set markers = const {}, + Set polygons = const {}, + Set polylines = const {}, + Set circles = const {}, + Set tileOverlays = const {}, + Set> gestureRecognizers = + const >{}, + Map mapOptions = const {}, + }) : _mapId = mapId, + _streamController = streamController, + _initialCameraPosition = initialCameraPosition, + _markers = markers, + _polygons = polygons, + _polylines = polylines, + _circles = circles, + _rawMapOptions = mapOptions { _circlesController = CirclesController(stream: this._streamController); _polygonsController = PolygonsController(stream: this._streamController); _polylinesController = PolylinesController(stream: this._streamController); @@ -121,9 +137,9 @@ class GoogleMapController { /// Failure to call this method would result in the GMap not rendering at all, /// and most of the public methods on this class no-op'ing. void init() { - var options = _rawOptionsToGmapsOptions(_rawOptions); + var options = _rawOptionsToGmapsOptions(_rawMapOptions); // Initial position can only to be set here! - options = _applyInitialPosition(_rawOptions, options); + options = _applyInitialPosition(_initialCameraPosition, options); // Create the map... _googleMap = _createMap(_div, options); @@ -132,13 +148,13 @@ class GoogleMapController { _attachGeometryControllers(_googleMap); _renderInitialGeometry( - markers: _rawOptionsToInitialMarkers(_rawOptions), - circles: _rawOptionsToInitialCircles(_rawOptions), - polygons: _rawOptionsToInitialPolygons(_rawOptions), - polylines: _rawOptionsToInitialPolylines(_rawOptions), + markers: _markers, + circles: _circles, + polygons: _polygons, + polylines: _polylines, ); - _setTrafficLayer(_googleMap, _isTrafficLayerEnabled(_rawOptions)); + _setTrafficLayer(_googleMap, _isTrafficLayerEnabled(_rawMapOptions)); } // Funnels map gmap events into the plugin's stream controller. @@ -196,20 +212,15 @@ class GoogleMapController { _polylinesController.addPolylines(polylines); } - // Merges new options coming from the plugin into the `key` entry of the _rawOptions map. + // Merges new options coming from the plugin into the _rawMapOptions map. // - // By default: `key` is 'options'. - // - // Returns the updated _rawOptions object. - Map _mergeRawOptions( - Map newOptions, { - String key = 'options', - }) { - _rawOptions[key] = { - ...(_rawOptions[key] ?? {}), + // Returns the updated _rawMapOptions object. + Map _mergeRawOptions(Map newOptions) { + _rawMapOptions = { + ..._rawMapOptions, ...newOptions, }; - return _rawOptions; + return _rawMapOptions; } /// Updates the map options from a `Map`. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart index cf549e8e375e..cb2a8aa238f9 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart @@ -86,6 +86,22 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { _map(mapId).updateCircles(circleUpdates); } + @override + Future updateTileOverlays({ + @required Set newTileOverlays, + @required int mapId, + }) async { + return; // Noop for now! + } + + @override + Future clearTileCache( + TileOverlayId tileOverlayId, { + @required int mapId, + }) async { + return; // Noop for now! + } + /// Applies the given `cameraUpdate` to the current viewport (with animation). @override Future animateCamera( @@ -260,31 +276,43 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { @override Widget buildView( - Map creationParams, - Set> gestureRecognizers, - PlatformViewCreatedCallback onPlatformViewCreated) { - int mapId = creationParams.remove('_webOnlyMapCreationId'); - - assert(mapId != null, + int creationId, + PlatformViewCreatedCallback onPlatformViewCreated, { + @required CameraPosition initialCameraPosition, + Set markers = const {}, + Set polygons = const {}, + Set polylines = const {}, + Set circles = const {}, + Set tileOverlays = const {}, + Set> gestureRecognizers = + const >{}, + Map mapOptions = const {}, + }) { + assert(creationId != null, 'buildView needs a `_webOnlyMapCreationId` in its creationParams to prevent widget reloads in web.'); - // Bail fast if we've already rendered this mapId... - if (_mapById[mapId]?.widget != null) { - return _mapById[mapId].widget; + // Bail fast if we've already rendered this map ID... + if (_mapById[creationId]?.widget != null) { + return _mapById[creationId].widget; } final StreamController controller = StreamController.broadcast(); final mapController = GoogleMapController( - mapId: mapId, + initialCameraPosition: initialCameraPosition, + mapId: creationId, streamController: controller, - rawOptions: creationParams, + markers: markers, + polygons: polygons, + polylines: polylines, + circles: circles, + mapOptions: mapOptions, ); - _mapById[mapId] = mapController; + _mapById[creationId] = mapController; - onPlatformViewCreated.call(mapId); + onPlatformViewCreated.call(creationId); return mapController.widget; } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index 595ca20db78d..20d078284742 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -1,7 +1,7 @@ name: google_maps_flutter_web description: Web platform implementation of google_maps_flutter homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter -version: 0.1.2 +version: 0.2.0 flutter: plugin: @@ -15,19 +15,19 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - meta: ^1.1.7 - google_maps_flutter_platform_interface: ^1.1.0 + meta: ^1.3.0 + google_maps_flutter_platform_interface: ^2.0.1 google_maps: ^3.4.5 - stream_transform: ^1.2.0 - sanitize_html: ^1.4.1 + stream_transform: ^2.0.0 + sanitize_html: ^2.0.0 dev_dependencies: flutter_test: sdk: flutter - http: ^0.12.2 - url_launcher: ^5.2.5 + http: ^0.13.0 + url_launcher: ^6.0.2 pedantic: ^1.8.0 - mockito: ^4.1.1 + mockito: ^5.0.0 integration_test: path: ../../integration_test diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration.dart index 302057f0ea57..0eca5b82d922 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration.dart @@ -50,11 +50,24 @@ void main() { StreamController stream; // Creates a controller with the default mapId and stream controller, and any `options` needed. - GoogleMapController _createController({Map options}) { + GoogleMapController _createController({ + CameraPosition initialCameraPosition = + const CameraPosition(target: LatLng(0, 0)), + Set markers = const {}, + Set polygons = const {}, + Set polylines = const {}, + Set circles = const {}, + Map options, + }) { return GoogleMapController( mapId: mapId, streamController: stream, - rawOptions: options ?? {}); + initialCameraPosition: initialCameraPosition, + markers: markers, + polygons: polygons, + polylines: polylines, + circles: circles, + mapOptions: options ?? {}); } setUp(() { @@ -143,58 +156,45 @@ void main() { }); testWidgets('renders initial geometry', (WidgetTester tester) async { - controller = _createController(options: { - 'circlesToAdd': [ - {'circleId': 'circle-1'} - ], - 'markersToAdd': [ - { - 'markerId': 'marker-1', - 'infoWindow': { - 'title': 'title for test', - 'snippet': 'snippet for test', - }, - }, - ], - 'polygonsToAdd': [ - { - 'polygonId': 'polygon-1', - 'points': [ - [43.355114, -5.851333], - [43.354797, -5.851860], - [43.354469, -5.851318], - [43.354762, -5.850824], - ], - }, - { - 'polygonId': 'polygon-2-with-holes', - 'points': [ - [43.355114, -5.851333], - [43.354797, -5.851860], - [43.354469, -5.851318], - [43.354762, -5.850824], - ], - 'holes': [ - [ - [41.354797, -6.851860], - [41.354469, -6.851318], - [41.354762, -6.850824], - ] + controller = _createController(circles: { + Circle(circleId: CircleId('circle-1')) + }, markers: { + Marker( + markerId: MarkerId('marker-1'), + infoWindow: InfoWindow( + title: 'title for test', snippet: 'snippet for test')) + }, polygons: { + Polygon(polygonId: PolygonId('polygon-1'), points: [ + LatLng(43.355114, -5.851333), + LatLng(43.354797, -5.851860), + LatLng(43.354469, -5.851318), + LatLng(43.354762, -5.850824), + ]), + Polygon( + polygonId: PolygonId('polygon-2-with-holes'), + points: [ + LatLng(43.355114, -5.851333), + LatLng(43.354797, -5.851860), + LatLng(43.354469, -5.851318), + LatLng(43.354762, -5.850824), + ], + holes: [ + [ + LatLng(41.354797, -6.851860), + LatLng(41.354469, -6.851318), + LatLng(41.354762, -6.850824), ] - }, - ], - 'polylinesToAdd': [ - { - 'polylineId': 'polyline-1', - 'points': [ - [43.355114, -5.851333], - [43.354797, -5.851860], - [43.354469, -5.851318], - [43.354762, -5.850824], - ], - }, - ], + ], + ), + }, polylines: { + Polyline(polylineId: PolylineId('polyline-1'), points: [ + LatLng(43.355114, -5.851333), + LatLng(43.354797, -5.851860), + LatLng(43.354469, -5.851318), + LatLng(43.354762, -5.850824), + ]) }); + controller.debugSetOverrides( circles: circles, markers: markers, @@ -226,14 +226,10 @@ void main() { testWidgets('empty infoWindow does not create InfoWindow instance.', (WidgetTester tester) async { - controller = _createController(options: { - 'markersToAdd': [ - { - 'markerId': 'marker-1', - 'infoWindow': {}, - }, - ], + controller = _createController(markers: { + Marker(markerId: MarkerId('marker-1'), infoWindow: null), }); + controller.debugSetOverrides( markers: markers, ); @@ -253,10 +249,8 @@ void main() { }); testWidgets('translates initial options', (WidgetTester tester) async { controller = _createController(options: { - 'options': { - 'mapType': 2, - 'zoomControlsEnabled': true, - } + 'mapType': 2, + 'zoomControlsEnabled': true, }); controller.debugSetOverrides(createMap: (_, options) { capturedOptions = options; @@ -276,9 +270,7 @@ void main() { testWidgets('disables gestureHandling with scrollGesturesEnabled false', (WidgetTester tester) async { controller = _createController(options: { - 'options': { - 'scrollGesturesEnabled': false, - } + 'scrollGesturesEnabled': false, }); controller.debugSetOverrides(createMap: (_, options) { capturedOptions = options; @@ -296,9 +288,7 @@ void main() { testWidgets('disables gestureHandling with zoomGesturesEnabled false', (WidgetTester tester) async { controller = _createController(options: { - 'options': { - 'zoomGesturesEnabled': false, - } + 'zoomGesturesEnabled': false, }); controller.debugSetOverrides(createMap: (_, options) { capturedOptions = options; @@ -315,7 +305,10 @@ void main() { testWidgets('does not set initial position if absent', (WidgetTester tester) async { - controller = _createController(); + controller = _createController( + initialCameraPosition: null, + ); + controller.debugSetOverrides(createMap: (_, options) { capturedOptions = options; return map; @@ -330,14 +323,15 @@ void main() { testWidgets('sets initial position when passed', (WidgetTester tester) async { - controller = _createController(options: { - 'initialCameraPosition': { - 'target': [43.308, -5.6910], - 'zoom': 12, - 'bearing': 0, - 'tilt': 0, - } - }); + controller = _createController( + initialCameraPosition: CameraPosition( + target: LatLng(43.308, -5.6910), + zoom: 12, + bearing: 0, + tilt: 0, + ), + ); + controller.debugSetOverrides(createMap: (_, options) { capturedOptions = options; return map; @@ -361,9 +355,7 @@ void main() { testWidgets('initializes with traffic layer', (WidgetTester tester) async { controller = _createController(options: { - 'options': { - 'trafficEnabled': true, - } + 'trafficEnabled': true, }); controller.debugSetOverrides(createMap: (_, __) => map); controller.init(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_plugin_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_plugin_integration.dart index 6276d26753a4..f0cae1dcdaf6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_plugin_integration.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_plugin_integration.dart @@ -70,11 +70,16 @@ void main() { group('buildView', () { final testMapId = 33930; + final initialCameraPosition = CameraPosition(target: LatLng(0, 0)); testWidgets('throws without _webOnlyMapCreationId', (WidgetTester tester) async { expect( - () => plugin.buildView({}, null, onPlatformViewCreated), + () => plugin.buildView( + null, + onPlatformViewCreated, + initialCameraPosition: initialCameraPosition, + ), throwsAssertionError, reason: '_webOnlyMapCreationId is mandatory to prevent unnecessary reloads in web.', @@ -87,9 +92,11 @@ void main() { final Map cache = {}; plugin.debugSetMapById(cache); - final HtmlElementView widget = plugin.buildView({ - '_webOnlyMapCreationId': testMapId, - }, null, onPlatformViewCreated); + final HtmlElementView widget = plugin.buildView( + testMapId, + onPlatformViewCreated, + initialCameraPosition: initialCameraPosition, + ); expect( widget.viewType, @@ -116,9 +123,11 @@ void main() { when(controller.widget).thenReturn(expected); plugin.debugSetMapById({testMapId: controller}); - final widget = plugin.buildView({ - '_webOnlyMapCreationId': testMapId, - }, null, onPlatformViewCreated); + final widget = plugin.buildView( + testMapId, + onPlatformViewCreated, + initialCameraPosition: initialCameraPosition, + ); expect(widget, equals(expected)); expect( @@ -159,6 +168,24 @@ void main() { }); }); + group('Noop methods:', () { + int mapId = 0; + setUp(() { + plugin.debugSetMapById({mapId: controller}); + }); + // Options + testWidgets('updateTileOverlays', (WidgetTester tester) async { + final update = + plugin.updateTileOverlays(mapId: mapId, newTileOverlays: {}); + expect(update, completion(null)); + }); + testWidgets('updateTileOverlays', (WidgetTester tester) async { + final update = + plugin.clearTileCache(TileOverlayId('any'), mapId: mapId); + expect(update, completion(null)); + }); + }); + // These methods only pass-through values from the plugin to the controller // so we verify them all together here... group('Pass-through methods:', () { @@ -176,28 +203,28 @@ void main() { }); // Geometry testWidgets('updateMarkers', (WidgetTester tester) async { - final expectedUpdates = MarkerUpdates.from(null, null); + final expectedUpdates = MarkerUpdates.from({}, {}); await plugin.updateMarkers(expectedUpdates, mapId: mapId); verify(controller.updateMarkers(expectedUpdates)); }); testWidgets('updatePolygons', (WidgetTester tester) async { - final expectedUpdates = PolygonUpdates.from(null, null); + final expectedUpdates = PolygonUpdates.from({}, {}); await plugin.updatePolygons(expectedUpdates, mapId: mapId); verify(controller.updatePolygons(expectedUpdates)); }); testWidgets('updatePolylines', (WidgetTester tester) async { - final expectedUpdates = PolylineUpdates.from(null, null); + final expectedUpdates = PolylineUpdates.from({}, {}); await plugin.updatePolylines(expectedUpdates, mapId: mapId); verify(controller.updatePolylines(expectedUpdates)); }); testWidgets('updateCircles', (WidgetTester tester) async { - final expectedUpdates = CircleUpdates.from(null, null); + final expectedUpdates = CircleUpdates.from({}, {}); await plugin.updateCircles(expectedUpdates, mapId: mapId); diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh index fb5f8eac44e9..5681775cdb3f 100644 --- a/script/nnbd_plugins.sh +++ b/script/nnbd_plugins.sh @@ -34,6 +34,7 @@ readonly NNBD_PLUGINS_LIST=( "webview_flutter" "wifi_info_flutter" "in_app_purchase" + "google_maps_flutter_web" # Not yet migrated, but compatible with others ) # This list contains the list of plugins that have *not* been @@ -41,8 +42,7 @@ readonly NNBD_PLUGINS_LIST=( # building the all plugins app. This list should be kept empty. readonly NON_NNBD_PLUGINS_LIST=( - "extension_google_sign_in_as_googleapis_auth" - "google_maps_flutter_web" # Not yet migrated. + "extension_google_sign_in_as_googleapis_auth" # Some deps are still clashing ) export EXCLUDED_PLUGINS_FROM_STABLE=$(IFS=, ; echo "${NNBD_PLUGINS_LIST[*]}") From 8ab62c5b0c99b87b3aa4f745f3dfda09c20128b6 Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Wed, 3 Mar 2021 18:21:16 -0800 Subject: [PATCH 0247/1565] [google_maps_flutter_web] Move integration tests to example. (#3675) This PR moves the integration tests of this package to conform with the latest best practices for web plugins. --- .../google_maps_flutter_web/CHANGELOG.md | 5 +++++ .../google_maps_flutter_web/example/README.md | 21 +++++++++++++++++++ .../google_maps_controller_test.dart} | 0 .../google_maps_plugin_test.dart} | 0 .../integration_test/marker_test.dart} | 0 .../integration_test/markers_test.dart} | 2 +- .../resources/icon_image_base64.dart | 0 .../integration_test/shape_test.dart} | 0 .../integration_test/shapes_test.dart} | 0 .../{test => example}/lib/main.dart | 0 .../{test => example}/pubspec.yaml | 16 +++++++------- .../{test/run_test => example/run_test.sh} | 5 +++-- .../test_driver/integration_driver.dart} | 0 .../{test => example}/web/index.html | 0 .../google_maps_flutter_web/pubspec.yaml | 9 ++------ .../google_maps_flutter_web/test/README.md | 18 +++------------- .../google_maps_plugin_integration_test.dart | 7 ------- .../test_driver/marker_integration_test.dart | 7 ------- .../test_driver/markers_integration_test.dart | 7 ------- .../test_driver/shape_integration_test.dart | 7 ------- .../test_driver/shapes_integration_test.dart | 7 ------- .../test/tests_exist_elsewhere_test.dart | 10 +++++++++ 22 files changed, 53 insertions(+), 68 deletions(-) create mode 100644 packages/google_maps_flutter/google_maps_flutter_web/example/README.md rename packages/google_maps_flutter/google_maps_flutter_web/{test/test_driver/google_maps_controller_integration.dart => example/integration_test/google_maps_controller_test.dart} (100%) rename packages/google_maps_flutter/google_maps_flutter_web/{test/test_driver/google_maps_plugin_integration.dart => example/integration_test/google_maps_plugin_test.dart} (100%) rename packages/google_maps_flutter/google_maps_flutter_web/{test/test_driver/marker_integration.dart => example/integration_test/marker_test.dart} (100%) rename packages/google_maps_flutter/google_maps_flutter_web/{test/test_driver/markers_integration.dart => example/integration_test/markers_test.dart} (99%) rename packages/google_maps_flutter/google_maps_flutter_web/{test/test_driver => example/integration_test}/resources/icon_image_base64.dart (100%) rename packages/google_maps_flutter/google_maps_flutter_web/{test/test_driver/shape_integration.dart => example/integration_test/shape_test.dart} (100%) rename packages/google_maps_flutter/google_maps_flutter_web/{test/test_driver/shapes_integration.dart => example/integration_test/shapes_test.dart} (100%) rename packages/google_maps_flutter/google_maps_flutter_web/{test => example}/lib/main.dart (100%) rename packages/google_maps_flutter/google_maps_flutter_web/{test => example}/pubspec.yaml (52%) rename packages/google_maps_flutter/google_maps_flutter_web/{test/run_test => example/run_test.sh} (51%) rename packages/google_maps_flutter/google_maps_flutter_web/{test/test_driver/google_maps_controller_integration_test.dart => example/test_driver/integration_driver.dart} (100%) rename packages/google_maps_flutter/google_maps_flutter_web/{test => example}/web/index.html (100%) delete mode 100644 packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_plugin_integration_test.dart delete mode 100644 packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/marker_integration_test.dart delete mode 100644 packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/markers_integration_test.dart delete mode 100644 packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shape_integration_test.dart delete mode 100644 packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration_test.dart create mode 100644 packages/google_maps_flutter/google_maps_flutter_web/test/tests_exist_elsewhere_test.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md index 826f1ea53023..29e9287a14fb 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.2.1 + +* Move integration tests to `example`. +* Tweak pubspec dependencies for main package. + ## 0.2.0 * Make this plugin compatible with the rest of null-safe plugins. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/README.md b/packages/google_maps_flutter/google_maps_flutter_web/example/README.md new file mode 100644 index 000000000000..0ec01e025570 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/README.md @@ -0,0 +1,21 @@ +# Testing + +This package utilizes the `integration_test` package to run its tests in a web browser. + +See [flutter.dev > Integration testing](https://flutter.dev/docs/testing/integration-tests) for more info. + +## Running the tests + +Make sure you have updated to the latest Flutter master. + +1. Check what version of Chrome is running on the machine you're running tests on. + +2. Download and install driver for that version from here: + * + +3. Start the driver using `chromedriver --port=4444` + +4. Run tests: `flutter drive -d web-server --browser-name=chrome --driver=test_driver/integration_driver.dart --target=integration_test/TEST_NAME.dart`, or (in Linux): + + * Single: `./run_test.sh integration_test/TEST_NAME.dart` + * All: `./run_test.sh` diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart similarity index 100% rename from packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration.dart rename to packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_plugin_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart similarity index 100% rename from packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_plugin_integration.dart rename to packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/marker_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart similarity index 100% rename from packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/marker_integration.dart rename to packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/markers_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart similarity index 99% rename from packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/markers_integration.dart rename to packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart index 9c3ed8ea3860..71cf41522d67 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/markers_integration.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart @@ -164,7 +164,7 @@ void main() { startsWith('blob:')); final blobUrl = controller.markers[MarkerId('1')].marker.icon.url; - final response = await http.get(blobUrl); + final response = await http.get(Uri.parse(blobUrl)); expect(response.bodyBytes, bytes, reason: diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/resources/icon_image_base64.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/resources/icon_image_base64.dart similarity index 100% rename from packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/resources/icon_image_base64.dart rename to packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/resources/icon_image_base64.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shape_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart similarity index 100% rename from packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shape_integration.dart rename to packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart similarity index 100% rename from packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration.dart rename to packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart similarity index 100% rename from packages/google_maps_flutter/google_maps_flutter_web/test/lib/main.dart rename to packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml similarity index 52% rename from packages/google_maps_flutter/google_maps_flutter_web/test/pubspec.yaml rename to packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml index 008cc0350430..96da8ab90d82 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/test/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml @@ -1,23 +1,23 @@ -name: regular_integration_tests +name: google_maps_flutter_web_integration_tests publish_to: none environment: - sdk: ">=2.2.2 <3.0.0" + sdk: ">=2.2.2 <3.0.0" # Bump this to 2.12 when migrating to nnbd. + flutter: ">=1.27.0-0" # For integration_test from sdk dependencies: + google_maps_flutter_web: + path: ../ flutter: sdk: flutter dev_dependencies: google_maps: ^3.4.4 + http: ^0.13.0 + mockito: ^5.0.0 flutter_driver: sdk: flutter flutter_test: sdk: flutter - http: ^0.12.2 - mockito: ^4.1.1 - google_maps_flutter_web: - path: ../ integration_test: - path: ../../../integration_test - + sdk: flutter diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/run_test b/packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh similarity index 51% rename from packages/google_maps_flutter/google_maps_flutter_web/test/run_test rename to packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh index 74a8526a0fa3..8e6f149358c9 100755 --- a/packages/google_maps_flutter/google_maps_flutter_web/test/run_test +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh @@ -4,14 +4,15 @@ if pgrep -lf chromedriver > /dev/null; then if [ $# -eq 0 ]; then echo "No target specified, running all tests..." - find test_driver/ -iname *_integration.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --target='{}' + find integration_test/ -iname *_test.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_driver.dart --target='{}' else echo "Running test target: $1..." set -x - flutter drive -d web-server --web-port=7357 --browser-name=chrome --target=$1 + flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_driver.dart --target=$1 fi else echo "chromedriver is not running." + echo "Please, check the README.md for instructions on how to use run_test.sh" fi diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/test_driver/integration_driver.dart similarity index 100% rename from packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_controller_integration_test.dart rename to packages/google_maps_flutter/google_maps_flutter_web/example/test_driver/integration_driver.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/web/index.html b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html similarity index 100% rename from packages/google_maps_flutter/google_maps_flutter_web/test/web/index.html rename to packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index 20d078284742..22df1b24afe0 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -1,7 +1,7 @@ name: google_maps_flutter_web description: Web platform implementation of google_maps_flutter homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter -version: 0.2.0 +version: 0.2.1 flutter: plugin: @@ -24,12 +24,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - http: ^0.13.0 - url_launcher: ^6.0.2 - pedantic: ^1.8.0 - mockito: ^5.0.0 - integration_test: - path: ../../integration_test + pedantic: ^1.10.0 environment: sdk: ">=2.3.0 <3.0.0" diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/README.md b/packages/google_maps_flutter/google_maps_flutter_web/test/README.md index 7c48d024ba57..7c5b4ad682ba 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/test/README.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/README.md @@ -1,17 +1,5 @@ -# Running browser_tests +## test -Make sure you have updated to the latest Flutter master. +This package uses integration tests for testing. -1. Check what version of Chrome is running on the machine you're running tests on. - -2. Download and install driver for that version from here: - * - -3. Start the driver using `chromedriver --port=4444` - -4. Change into the `test` directory of your clone. - -5. Run tests: `flutter drive -d web-server --browser-name=chrome --target=test_driver/TEST_NAME_integration.dart`, or (in Linux): - - * Single: `./run_test test_driver/TEST_NAME_integration.dart` - * All: `./run_test` +See `example/README.md` for more info. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_plugin_integration_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_plugin_integration_test.dart deleted file mode 100644 index 39444c0daa24..000000000000 --- a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/google_maps_plugin_integration_test.dart +++ /dev/null @@ -1,7 +0,0 @@ -// 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. - -import 'package:integration_test/integration_test_driver.dart'; - -Future main() async => integrationDriver(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/marker_integration_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/marker_integration_test.dart deleted file mode 100644 index 39444c0daa24..000000000000 --- a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/marker_integration_test.dart +++ /dev/null @@ -1,7 +0,0 @@ -// 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. - -import 'package:integration_test/integration_test_driver.dart'; - -Future main() async => integrationDriver(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/markers_integration_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/markers_integration_test.dart deleted file mode 100644 index 39444c0daa24..000000000000 --- a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/markers_integration_test.dart +++ /dev/null @@ -1,7 +0,0 @@ -// 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. - -import 'package:integration_test/integration_test_driver.dart'; - -Future main() async => integrationDriver(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shape_integration_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shape_integration_test.dart deleted file mode 100644 index 39444c0daa24..000000000000 --- a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shape_integration_test.dart +++ /dev/null @@ -1,7 +0,0 @@ -// 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. - -import 'package:integration_test/integration_test_driver.dart'; - -Future main() async => integrationDriver(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration_test.dart deleted file mode 100644 index 39444c0daa24..000000000000 --- a/packages/google_maps_flutter/google_maps_flutter_web/test/test_driver/shapes_integration_test.dart +++ /dev/null @@ -1,7 +0,0 @@ -// 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. - -import 'package:integration_test/integration_test_driver.dart'; - -Future main() async => integrationDriver(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/tests_exist_elsewhere_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/tests_exist_elsewhere_test.dart new file mode 100644 index 000000000000..334f52186d9d --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/tests_exist_elsewhere_test.dart @@ -0,0 +1,10 @@ +import 'package:flutter_test/flutter_test.dart'; + +void main() { + test('Tell the user where to find the real tests', () { + print('---'); + print('This package uses integration_test for its tests.'); + print('See `example/README.md` for more info.'); + print('---'); + }); +} From 2518218fade2207cb39e72e5bc29d549665f3386 Mon Sep 17 00:00:00 2001 From: Harsh Bhikadia Date: Thu, 4 Mar 2021 23:34:04 +0530 Subject: [PATCH 0248/1565] [image_picker] fix flutter/flutter#71927 (#3676) --- .../ios/RunnerUITests/ImagePickerFromGalleryUITests.m | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m b/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m index e30fabd2d071..8be41dc63587 100644 --- a/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m +++ b/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m @@ -120,17 +120,6 @@ - (void)launchPickerAndCancel { elementMatchingPredicate:[NSPredicate predicateWithFormat:@"label == %@", @"You have not yet picked an image."]]; - if (![imageNotPickedText waitForExistenceWithTimeout:kElementWaitingTime]) { - // Before https://github.com/flutter/engine/pull/22811 the label's a11y type was otherElements. - // TODO(cyanglaz): Remove this after - // https://github.com/flutter/flutter/commit/057e8230743ec96f33b73948ccd6b80081e3615e rolled to - // stable. - // https://github.com/flutter/flutter/issues/71927 - imageNotPickedText = [self.app.otherElements - elementMatchingPredicate:[NSPredicate - predicateWithFormat:@"label == %@", - @"You have not yet picked an image."]]; - } if (![imageNotPickedText waitForExistenceWithTimeout:kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTFail(@"Failed due to not able to find imageNotPickedText with %@ seconds", From 47c380a9bbc78bae8b18a849183cab0e21a703f4 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Thu, 4 Mar 2021 13:59:21 -0800 Subject: [PATCH 0249/1565] Update CI config for Flutter 2 (#3674) Includes cleanup to simplify our setup. Major changes: - Eliminate the NNBD plugin filtering for stable. - Remove the temporarily-added beta branch testing. - Enable Linux, macOS, and web on stable (Windows is LUCI-based) - Combine the two different macOS matrix configurations now that they are the same. - Combine the two different Linux matrix configurations by using a single Dockerfile (which now also includes clang-format) - The web integration smoke test temporarily still uses the old Dockerfile, now renamed, because the driver installer script doesn't support Chrome 89 yet. - Move most of the Linux tasks to lower-CPU machines to allow more tasks to run in parallel without hitting the community limit. - Reorder the tasks slightly and give them comments to identify platform groupings - Enabled web "build all plugins together" and "build all examples" tests --- .ci/Dockerfile | 16 +- ...e-LinuxDesktop => Dockerfile-LegacyChrome} | 20 +- .cirrus.yml | 208 ++++++++++-------- .../ios/Classes/WifiInfoFlutterPlugin.m | 4 +- script/build_all_plugins_app.sh | 22 +- script/incremental_build.sh | 6 - script/nnbd_plugins.sh | 49 ----- .../tool/lib/src/build_examples_command.dart | 51 +++-- script/tool/lib/src/format_command.dart | 6 +- .../test/build_examples_command_test.dart | 74 ++++++- 10 files changed, 261 insertions(+), 195 deletions(-) rename .ci/{Dockerfile-LinuxDesktop => Dockerfile-LegacyChrome} (62%) delete mode 100644 script/nnbd_plugins.sh diff --git a/.ci/Dockerfile b/.ci/Dockerfile index 13ac087498d1..14000e2032ed 100644 --- a/.ci/Dockerfile +++ b/.ci/Dockerfile @@ -6,7 +6,7 @@ RUN sudo apt-get install -y --no-install-recommends gnupg # Add repo for gcloud sdk and install it RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | \ - sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list + sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list RUN curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | \ sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - @@ -23,7 +23,21 @@ RUN yes | sdkmanager \ RUN yes | sdkmanager --licenses +# Install formatter. +RUN sudo apt-get install -y clang-format + +# Install xvfb to allow running headless +RUN sudo apt-get install -y xvfb libegl1-mesa +# Install Linux desktop build tool requirements. +RUN sudo apt-get install -y clang cmake ninja-build file pkg-config +# Install necessary libraries. +RUN sudo apt-get install -y libgtk-3-dev libblkid-dev liblzma-dev + # Add repo for Google Chrome and install it RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add - RUN echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | sudo tee /etc/apt/sources.list.d/google-chrome.list RUN sudo apt-get update && sudo apt-get install -y --no-install-recommends google-chrome-stable + +# Make Chrome the default so http: has a handler for url_launcher tests. +RUN sudo apt-get install -y xdg-utils +RUN xdg-settings set default-web-browser google-chrome.desktop diff --git a/.ci/Dockerfile-LinuxDesktop b/.ci/Dockerfile-LegacyChrome similarity index 62% rename from .ci/Dockerfile-LinuxDesktop rename to .ci/Dockerfile-LegacyChrome index 63e4516e26fc..13ac087498d1 100644 --- a/.ci/Dockerfile-LinuxDesktop +++ b/.ci/Dockerfile-LegacyChrome @@ -6,7 +6,7 @@ RUN sudo apt-get install -y --no-install-recommends gnupg # Add repo for gcloud sdk and install it RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | \ - sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list + sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list RUN curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | \ sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - @@ -15,17 +15,15 @@ RUN sudo apt-get update && sudo apt-get install -y google-cloud-sdk && \ gcloud config set core/disable_usage_reporting true && \ gcloud config set component_manager/disable_update_check true -# Install xvfb to allow running headless -RUN sudo apt-get install -y xvfb libegl1-mesa -# Install Linux desktop build tool requirements. -RUN sudo apt-get install -y clang cmake ninja-build file pkg-config -# Install necessary libraries. -RUN sudo apt-get install -y libgtk-3-dev +RUN yes | sdkmanager \ + "platforms;android-27" \ + "build-tools;27.0.3" \ + "extras;google;m2repository" \ + "extras;android;m2repository" -# Add repo for Google Chrome and install it, for url_launcher tests. +RUN yes | sdkmanager --licenses + +# Add repo for Google Chrome and install it RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add - RUN echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | sudo tee /etc/apt/sources.list.d/google-chrome.list RUN sudo apt-get update && sudo apt-get install -y --no-install-recommends google-chrome-stable -# Make it the default so http: has a handler. -RUN sudo apt-get install -y xdg-utils -RUN xdg-settings set default-web-browser google-chrome.desktop diff --git a/.cirrus.yml b/.cirrus.yml index 924cb63492a0..ea27c88b97e0 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,22 +1,23 @@ +# Light-workload tasks. +# These use default machines, with fewer CPUs, to reduce pressure on the +# concurrency limits. task: # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins only_if: $CIRRUS_TAG == '' use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_PR == '' container: dockerfile: .ci/Dockerfile - cpu: 8 - memory: 16G env: INTEGRATION_TEST_PATH: "./packages/integration_test" upgrade_script: - flutter channel stable - flutter upgrade - - flutter channel beta - - flutter upgrade - flutter channel master - flutter upgrade + - flutter config --enable-linux-desktop - git fetch origin master matrix: + ### Platform-agnostic tasks ### - name: plugin_tools_tests script: - cd script/tool @@ -27,48 +28,91 @@ task: - flutter channel master - ./script/check_publish.sh - name: format - install_script: - - wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - - - sudo apt-add-repository "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-7 main" - - sudo apt-get update - - sudo apt-get install -y --allow-unauthenticated clang-format-7 - format_script: ./script/incremental_build.sh format --travis --clang-format=clang-format-7 + format_script: ./script/incremental_build.sh format --fail-on-change - name: test env: matrix: CHANNEL: "master" - CHANNEL: "beta" CHANNEL: "stable" test_script: - # TODO(jackson): Allow web plugins once supported on stable - # https://github.com/flutter/flutter/issues/42864 - - if [[ "$CHANNEL" -eq "stable" ]]; then find . | grep _web$ | xargs rm -rf; fi - flutter channel $CHANNEL - ./script/incremental_build.sh test - name: analyze env: matrix: CHANNEL: "master" - CHANNEL: "beta" CHANNEL: "stable" - script: ./script/incremental_build.sh analyze + script: + - flutter channel $CHANNEL + - ./script/incremental_build.sh analyze + ### Android tasks ### - name: build_all_plugins_apk env: matrix: CHANNEL: "master" - CHANNEL: "beta" CHANNEL: "stable" script: - # TODO(jackson): Allow web plugins once supported on stable - # https://github.com/flutter/flutter/issues/42864 - - if [[ "$CHANNEL" -eq "stable" ]]; then find . | grep _web$ | xargs rm -rf; fi - flutter channel $CHANNEL - ./script/build_all_plugins_app.sh apk + ### Web tasks ### + - name: build_all_plugins_web + env: + matrix: + CHANNEL: "master" + CHANNEL: "stable" + script: + - flutter channel $CHANNEL + - ./script/build_all_plugins_app.sh web + - name: build-web-examples + env: + matrix: + CHANNEL: "master" + CHANNEL: "stable" + build_script: + - flutter channel $CHANNEL + - ./script/incremental_build.sh build-examples --web + # TODO: Add driving examples (and move to heavy-workload group). + ### Linux desktop tasks ### + - name: build_all_plugins_linux + env: + matrix: + CHANNEL: "master" + CHANNEL: "stable" + script: + - flutter channel $CHANNEL + - ./script/build_all_plugins_app.sh linux + +# Legacy Dockerfile configuration for web integration tests. +# https://github.com/flutter/web_installers doesn't yet support the current +# stable version of Chrome, so newly-generated Docker images don't work. +# TODO: Merge this task into the "Web tasks" section of the "Light-workload +# tasks" block above once web_installers has been updated to support Chrome 89 +# (which is what the current image generated from .ci/Dockerfile has). +task: + # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins + only_if: $CIRRUS_TAG == '' + use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_PR == '' + container: + dockerfile: .ci/Dockerfile-LegacyChrome + env: + INTEGRATION_TEST_PATH: "./packages/integration_test" + upgrade_script: + - flutter channel stable + - flutter upgrade + - flutter channel master + - flutter upgrade + - flutter config --enable-linux-desktop + - git fetch origin master + matrix: - name: integration_web_smoke_test + env: + matrix: + CHANNEL: "master" + CHANNEL: "stable" # Tests integration example test in web. only_if: "changesInclude('.cirrus.yml', 'packages/integration_test/**') || $CIRRUS_PR == ''" install_script: - - flutter config --enable-web + - flutter channel $CHANNEL - git clone https://github.com/flutter/web_installers.git - cd web_installers/packages/web_drivers/ - pub get @@ -77,6 +121,29 @@ task: test_script: - cd $INTEGRATION_TEST_PATH/example/ - flutter drive -v --driver=test_driver/integration_test.dart --target=integration_test/example_test.dart -d web-server --release --browser-name=chrome + +# Heavy-workload tasks. +# These use machines with more CPUs and memory, so will reduce parallelization +# for non-credit runs. +task: + # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins + only_if: $CIRRUS_TAG == '' + use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_PR == '' + container: + dockerfile: .ci/Dockerfile + cpu: 8 + memory: 16G + env: + INTEGRATION_TEST_PATH: "./packages/integration_test" + upgrade_script: + - flutter channel stable + - flutter upgrade + - flutter channel master + - flutter upgrade + - flutter config --enable-linux-desktop + - git fetch origin master + matrix: + ### Android tasks ### - name: build-apks+java-test+firebase-test-lab env: matrix: @@ -86,14 +153,10 @@ task: PLUGIN_SHARDING: "--shardIndex 3 --shardCount 4" matrix: CHANNEL: "master" - CHANNEL: "beta" CHANNEL: "stable" MAPS_API_KEY: ENCRYPTED[596a9f6bca436694625ac50851dc5da6b4d34cba8025f7db5bc9465142e8cd44e15f69e3507787753accebfc4910d550] GCLOUD_FIREBASE_TESTLAB_KEY: ENCRYPTED[07586610af1fdfc894e5969f70ef2458341b9b7e9c3b7c4225a663b4a48732b7208a4d91c3b7d45305a6b55fa2a37fc4] script: - # TODO(jackson): Allow web plugins once supported on stable - # https://github.com/flutter/flutter/issues/42864 - - if [[ "$CHANNEL" -eq "stable" ]]; then find . | grep _web$ | xargs rm -rf; fi - flutter channel $CHANNEL # Unsetting CIRRUS_CHANGE_MESSAGE and CIRRUS_COMMIT_MESSAGE as they # might include non-ASCII characters which makes Gradle crash. @@ -115,32 +178,14 @@ task: - fi - export CIRRUS_CHANGE_MESSAGE=`cat /tmp/cirrus_change_message.txt` - export CIRRUS_COMMIT_MESSAGE=`cat /tmp/cirrus_commit_message.txt` - -task: - # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins - only_if: $CIRRUS_TAG == '' - use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_PR == '' - container: - dockerfile: .ci/Dockerfile-LinuxDesktop - cpu: 8 - memory: 16G - env: - INTEGRATION_TEST_PATH: "./packages/integration_test" - upgrade_script: - - flutter channel stable - - flutter upgrade - - flutter channel beta - - flutter upgrade - - flutter channel master - - flutter upgrade - - git fetch origin master - matrix: + ### Linux desktop tasks ### - name: build-linux+drive-examples - install_script: - - flutter config --enable-linux-desktop + env: + matrix: + CHANNEL: "master" + CHANNEL: "stable" build_script: - # TODO(stuartmorgan): Include stable once Linux is supported on stable. - - flutter channel master + - flutter channel $CHANNEL - ./script/incremental_build.sh build-examples --linux - xvfb-run ./script/incremental_build.sh drive-examples --linux @@ -148,32 +193,40 @@ task: # Xcode 12 task # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins only_if: $CIRRUS_TAG == '' - use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' + use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_PR == '' osx_instance: image: big-sur-xcode-12.3 upgrade_script: - sudo gem install cocoapods - flutter channel stable - flutter upgrade - - flutter channel beta - - flutter upgrade - flutter channel master - flutter upgrade + - flutter config --enable-macos-desktop - git fetch origin master create_simulator_script: - xcrun simctl list - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-11 com.apple.CoreSimulator.SimRuntime.iOS-14-3 | xargs xcrun simctl boot matrix: + ### Platform-agnostic tasks ### + - name: lint_darwin_plugins + env: + matrix: + PLUGIN_SHARDING: "--shardIndex 0 --shardCount 2" + PLUGIN_SHARDING: "--shardIndex 1 --shardCount 2" + script: + # TODO(jmagman): Lint macOS podspecs but skip any that fail library validation. + - find . -name "*.podspec" | xargs grep -l "osx" | xargs rm + # Skip the dummy podspecs used to placate the tool. + - find . -name "*_web*.podspec" -o -name "*_mac*.podspec" | xargs rm + - ./script/incremental_build.sh podspecs + ### iOS tasks ### - name: build_all_plugins_ipa env: matrix: CHANNEL: "master" - CHANNEL: "beta" CHANNEL: "stable" script: - # TODO(jackson): Allow web plugins once supported on stable - # https://github.com/flutter/flutter/issues/42864 - - if [[ "$CHANNEL" -eq "stable" ]]; then find . | grep _web$ | xargs rm -rf; fi - flutter channel $CHANNEL - ./script/build_all_plugins_app.sh ios --no-codesign - name: build-ipas+drive-examples @@ -187,55 +240,32 @@ task: PLUGIN_SHARDING: "--shardIndex 3 --shardCount 4" matrix: CHANNEL: "master" - CHANNEL: "beta" CHANNEL: "stable" SIMCTL_CHILD_MAPS_API_KEY: ENCRYPTED[596a9f6bca436694625ac50851dc5da6b4d34cba8025f7db5bc9465142e8cd44e15f69e3507787753accebfc4910d550] build_script: - # TODO(jackson): Allow web plugins once supported on stable - # https://github.com/flutter/flutter/issues/42864 - - if [[ "$CHANNEL" -eq "stable" ]]; then find . | grep _web$ | xargs rm -rf; fi - flutter channel $CHANNEL - - flutter upgrade - ./script/incremental_build.sh build-examples --ipa - ./script/incremental_build.sh xctest --skip $PLUGINS_TO_SKIP_XCTESTS --ios-destination "platform=iOS Simulator,name=iPhone 11,OS=latest" # `drive-examples` contains integration tests, which changes the UI of the application. # This UI change sometimes affects `xctest`. # So we run `drive-examples` after `xctest`, changing the order will result ci failure. - ./script/incremental_build.sh drive-examples --ios - - name: lint_darwin_plugins + ### macOS desktop tasks ### + - name: build_all_plugins_macos env: matrix: - PLUGIN_SHARDING: "--shardIndex 0 --shardCount 2" - PLUGIN_SHARDING: "--shardIndex 1 --shardCount 2" - script: - # TODO(jmagman): Lint macOS podspecs but skip any that fail library validation. - - find . -name "*.podspec" | xargs grep -l "osx" | xargs rm - # Skip the dummy podspecs used to placate the tool. - - find . -name "*_web*.podspec" -o -name "*_mac*.podspec" | xargs rm - - ./script/incremental_build.sh podspecs - -task: - # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins - only_if: $CIRRUS_TAG == '' - use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' - osx_instance: - image: big-sur-xcode-12.3 - setup_script: - - flutter config --enable-macos-desktop - upgrade_script: - - sudo gem install cocoapods - - flutter channel master - - flutter upgrade - - git fetch origin master - matrix: - - name: build_all_plugins_app + CHANNEL: "master" + CHANNEL: "stable" script: - - flutter channel master + - flutter channel $CHANNEL - ./script/build_all_plugins_app.sh macos - - name: build-apps+drive-examples + - name: build-macos+drive-examples env: + matrix: + CHANNEL: "master" + CHANNEL: "stable" PATH: $PATH:/usr/local/bin build_script: - - flutter channel master + - flutter channel $CHANNEL - ./script/incremental_build.sh build-examples --macos --no-ipa - ./script/incremental_build.sh drive-examples --macos diff --git a/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.m b/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.m index 3abdbeef5744..f0811dd92ef6 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.m +++ b/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.m @@ -119,7 +119,9 @@ - (NSString*)convertCLAuthorizationStatusToString:(CLAuthorizationStatus)status case kCLAuthorizationStatusAuthorizedWhenInUse: { return @"authorizedWhenInUse"; } - default: { return @"unknown"; } + default: { + return @"unknown"; + } } } diff --git a/script/build_all_plugins_app.sh b/script/build_all_plugins_app.sh index 0cd6f4888e79..f6b1c166069f 100755 --- a/script/build_all_plugins_app.sh +++ b/script/build_all_plugins_app.sh @@ -14,7 +14,6 @@ readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" > /dev/null && pwd)" readonly REPO_DIR="$(dirname "$SCRIPT_DIR")" source "$SCRIPT_DIR/common.sh" -source "$SCRIPT_DIR/nnbd_plugins.sh" check_changed_packages > /dev/null @@ -26,22 +25,14 @@ check_changed_packages > /dev/null # updating multiple plugins for a breaking change in a common dependency in # cases where using a relaxed version constraint isn't possible. readonly EXCLUDED_PLUGINS_LIST=( - # "file_selector" # currently out of sync with camera - # "flutter_plugin_android_lifecycle" - # "image_picker" - # "local_auth" # flutter_plugin_android_lifecycle conflict "plugin_platform_interface" # This should never be a direct app dependency. + "extension_google_sign_in_as_googleapis_auth" # Transitive dependency issues + # with integration_test. ) # Comma-separated string of the list above readonly EXCLUDED=$(IFS=, ; echo "${EXCLUDED_PLUGINS_LIST[*]}") ALL_EXCLUDED=($EXCLUDED) -# Exclude nnbd plugins from stable, and conflicting plugins otherwise. -if [ "$CHANNEL" == "stable" ]; then - ALL_EXCLUDED=("$EXCLUDED,$EXCLUDED_PLUGINS_FROM_STABLE") -else - ALL_EXCLUDED=("$EXCLUDED,$EXCLUDED_PLUGINS_FOR_NNBD") -fi echo "Excluding the following plugins: $ALL_EXCLUDED" @@ -53,7 +44,14 @@ function error() { failures=0 -for version in "debug" "release"; do +BUILD_MODES=("debug" "release") +# Web doesn't support --debug for builds. +if [[ "$1" == "web" ]]; then + BUILD_MODES=("release") +fi + +for version in "${BUILD_MODES[@]}"; do + echo "Building $version..." (cd $REPO_DIR/all_plugins && flutter build $@ --$version) if [ $? -eq 0 ]; then diff --git a/script/incremental_build.sh b/script/incremental_build.sh index bc41ebd3c70d..826229bced60 100755 --- a/script/incremental_build.sh +++ b/script/incremental_build.sh @@ -5,15 +5,9 @@ readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" readonly REPO_DIR="$(dirname "$SCRIPT_DIR")" source "$SCRIPT_DIR/common.sh" -source "$SCRIPT_DIR/nnbd_plugins.sh" # Plugins that are excluded from this task. ALL_EXCLUDED=("") -# Exclude nnbd plugins from stable. -if [ "$CHANNEL" == "stable" ]; then - ALL_EXCLUDED=($EXCLUDED_PLUGINS_FROM_STABLE) - echo "Excluding the following plugins because stable does not yet support NNBD: $ALL_EXCLUDED" -fi # Plugins that deliberately use their own analysis_options.yaml. # diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh deleted file mode 100644 index 5681775cdb3f..000000000000 --- a/script/nnbd_plugins.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -# This script contains the list of plugins migrated to nnbd -# that should be excluded from testing on Flutter stable until -# null-safe is available on stable. - -readonly NNBD_PLUGINS_LIST=( - "android_alarm_manager" - "android_intent" - "battery" - "camera" - "camera_platform_interface" - "connectivity" - "cross_file" - "device_info" - "espresso" - "file_selector" - "flutter_plugin_android_lifecycle" - "flutter_webview" - "google_maps_flutter" - "google_sign_in" - "image_picker" - "ios_platform_images" - "local_auth" - "path_provider" - "package_info" - "plugin_platform_interface" - "quick_actions" - "sensors" - "share" - "shared_preferences" - "url_launcher" - "video_player" - "webview_flutter" - "wifi_info_flutter" - "in_app_purchase" - "google_maps_flutter_web" # Not yet migrated, but compatible with others -) - -# This list contains the list of plugins that have *not* been -# migrated to nnbd, and conflict with those that have when -# building the all plugins app. This list should be kept empty. - -readonly NON_NNBD_PLUGINS_LIST=( - "extension_google_sign_in_as_googleapis_auth" # Some deps are still clashing -) - -export EXCLUDED_PLUGINS_FROM_STABLE=$(IFS=, ; echo "${NNBD_PLUGINS_LIST[*]}") -export EXCLUDED_PLUGINS_FOR_NNBD=$(IFS=, ; echo "${NON_NNBD_PLUGINS_LIST[*]}") diff --git a/script/tool/lib/src/build_examples_command.dart b/script/tool/lib/src/build_examples_command.dart index 53da9086abaa..bb140bd429c6 100644 --- a/script/tool/lib/src/build_examples_command.dart +++ b/script/tool/lib/src/build_examples_command.dart @@ -19,6 +19,7 @@ class BuildExamplesCommand extends PluginCommand { }) : super(packagesDir, fileSystem, processRunner: processRunner) { argParser.addFlag(kLinux, defaultsTo: false); argParser.addFlag(kMacos, defaultsTo: false); + argParser.addFlag(kWeb, defaultsTo: false); argParser.addFlag(kWindows, defaultsTo: false); argParser.addFlag(kIpa, defaultsTo: io.Platform.isMacOS); argParser.addFlag(kApk); @@ -43,10 +44,10 @@ class BuildExamplesCommand extends PluginCommand { !argResults[kApk] && !argResults[kLinux] && !argResults[kMacos] && + !argResults[kWeb] && !argResults[kWindows]) { - print( - 'None of --linux, --macos, --windows, --apk nor --ipa were specified, ' - 'so not building anything.'); + print('None of --linux, --macos, --web, --windows, --apk, or --ipa were ' + 'specified, so not building anything.'); return; } final String flutterCommand = @@ -84,33 +85,43 @@ class BuildExamplesCommand extends PluginCommand { if (argResults[kMacos]) { print('\nBUILDING macOS for $packageName'); if (isMacOsPlugin(plugin, fileSystem)) { - // TODO(https://github.com/flutter/flutter/issues/46236): - // Builing macos without running flutter pub get first results - // in an error. int exitCode = await processRunner.runAndStream( - flutterCommand, ['pub', 'get'], + flutterCommand, + [ + 'build', + kMacos, + if (enableExperiment.isNotEmpty) + '--enable-experiment=$enableExperiment', + ], workingDir: example); if (exitCode != 0) { failingPackages.add('$packageName (macos)'); - } else { - exitCode = await processRunner.runAndStream( - flutterCommand, - [ - 'build', - kMacos, - if (enableExperiment.isNotEmpty) - '--enable-experiment=$enableExperiment', - ], - workingDir: example); - if (exitCode != 0) { - failingPackages.add('$packageName (macos)'); - } } } else { print('macOS is not supported by this plugin'); } } + if (argResults[kWeb]) { + print('\nBUILDING web for $packageName'); + if (isWebPlugin(plugin, fileSystem)) { + int buildExitCode = await processRunner.runAndStream( + flutterCommand, + [ + 'build', + kWeb, + if (enableExperiment.isNotEmpty) + '--enable-experiment=$enableExperiment', + ], + workingDir: example); + if (buildExitCode != 0) { + failingPackages.add('$packageName (web)'); + } + } else { + print('Web is not supported by this plugin'); + } + } + if (argResults[kWindows]) { print('\nBUILDING Windows for $packageName'); if (isWindowsPlugin(plugin, fileSystem)) { diff --git a/script/tool/lib/src/format_command.dart b/script/tool/lib/src/format_command.dart index ec326b96c1f9..e1c14e04cfec 100644 --- a/script/tool/lib/src/format_command.dart +++ b/script/tool/lib/src/format_command.dart @@ -22,10 +22,10 @@ class FormatCommand extends PluginCommand { FileSystem fileSystem, { ProcessRunner processRunner = const ProcessRunner(), }) : super(packagesDir, fileSystem, processRunner: processRunner) { - argParser.addFlag('travis', hide: true); + argParser.addFlag('fail-on-change', hide: true); argParser.addOption('clang-format', defaultsTo: 'clang-format', - help: 'Path to executable of clang-format v5.'); + help: 'Path to executable of clang-format.'); } @override @@ -46,7 +46,7 @@ class FormatCommand extends PluginCommand { await _formatJava(googleFormatterPath); await _formatCppAndObjectiveC(); - if (argResults['travis']) { + if (argResults['fail-on-change']) { final bool modified = await _didModifyAnything(); if (modified) { throw ToolExit(1); diff --git a/script/tool/test/build_examples_command_test.dart b/script/tool/test/build_examples_command_test.dart index eaf5049dcc02..65417525d710 100644 --- a/script/tool/test/build_examples_command_test.dart +++ b/script/tool/test/build_examples_command_test.dart @@ -201,7 +201,7 @@ void main() { output, orderedEquals([ '\nBUILDING macOS for $packageName', - '\macOS is not supported by this plugin', + 'macOS is not supported by this plugin', '\n\n', 'All builds successful!', ]), @@ -213,6 +213,7 @@ void main() { expect(processRunner.recordedCalls, orderedEquals([])); cleanupPackages(); }); + test('building for macos', () async { createFakePlugin('plugin', withExtraFiles: >[ @@ -244,14 +245,81 @@ void main() { expect( processRunner.recordedCalls, orderedEquals([ - ProcessCall(flutterCommand, ['pub', 'get'], - pluginExampleDirectory.path), ProcessCall(flutterCommand, ['build', 'macos'], pluginExampleDirectory.path), ])); cleanupPackages(); }); + test('building for web with no implementation results in no-op', () async { + createFakePlugin('plugin', withExtraFiles: >[ + ['example', 'test'], + ]); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint( + runner, ['build-examples', '--no-ipa', '--web']); + final String packageName = + p.relative(pluginExampleDirectory.path, from: mockPackagesDir.path); + + expect( + output, + orderedEquals([ + '\nBUILDING web for $packageName', + 'Web is not supported by this plugin', + '\n\n', + 'All builds successful!', + ]), + ); + + print(processRunner.recordedCalls); + // Output should be empty since running build-examples --macos with no macos + // implementation is a no-op. + expect(processRunner.recordedCalls, orderedEquals([])); + cleanupPackages(); + }); + + test('building for web', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test'], + ['example', 'web', 'index.html'], + ], + isWebPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint( + runner, ['build-examples', '--no-ipa', '--web']); + final String packageName = + p.relative(pluginExampleDirectory.path, from: mockPackagesDir.path); + + expect( + output, + orderedEquals([ + '\nBUILDING web for $packageName', + '\n\n', + 'All builds successful!', + ]), + ); + + print(processRunner.recordedCalls); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall(flutterCommand, ['build', 'web'], + pluginExampleDirectory.path), + ])); + cleanupPackages(); + }); + test( 'building for Windows when plugin is not set up for Windows results in no-op', () async { From eb86dfcf69a3f75b8ca7c9a13684d06c98179a01 Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Thu, 4 Mar 2021 18:25:46 -0800 Subject: [PATCH 0250/1565] [google_maps_flutter_web] Downgrade mockito in example app. (#3679) --- .../google_maps_flutter_web/example/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml index 96da8ab90d82..9f942d654caa 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: dev_dependencies: google_maps: ^3.4.4 http: ^0.13.0 - mockito: ^5.0.0 + mockito: ^4.1.4 # Update to ^5.0.0 as soon as this migrates to null-safety flutter_driver: sdk: flutter flutter_test: From b709f7e4994aa48d2be815d07a1da0d66180c86e Mon Sep 17 00:00:00 2001 From: Anton Borries Date: Fri, 5 Mar 2021 03:39:05 +0100 Subject: [PATCH 0251/1565] [in_app_purchase] presentCodeRedemptionSheet (#3274) --- packages/in_app_purchase/CHANGELOG.md | 4 ++++ .../ios/Classes/FIAPaymentQueueHandler.h | 1 + .../ios/Classes/FIAPaymentQueueHandler.m | 8 ++++++++ .../ios/Classes/InAppPurchasePlugin.m | 8 ++++++++ .../ios/Tests/InAppPurchasePluginTest.m | 16 ++++++++++++++++ .../in_app_purchase/app_store_connection.dart | 5 +++++ .../in_app_purchase/google_play_connection.dart | 6 ++++++ .../in_app_purchase_connection.dart | 6 ++++++ .../sk_payment_queue_wrapper.dart | 11 +++++++++++ packages/in_app_purchase/pubspec.yaml | 2 +- .../app_store_connection_test.dart | 7 +++++++ .../google_play_connection_test.dart | 7 +++++++ .../sk_methodchannel_apis_test.dart | 15 +++++++++++++++ 13 files changed, 95 insertions(+), 1 deletion(-) diff --git a/packages/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/CHANGELOG.md index 535295a2f8af..84a65f4159f3 100644 --- a/packages/in_app_purchase/CHANGELOG.md +++ b/packages/in_app_purchase/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.1 + +* [iOS] Introduce `SKPaymentQueueWrapper.presentCodeRedemptionSheet` + ## 0.5.0 * Migrate to Google Billing Library 3.0 diff --git a/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.h b/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.h index 54898d170304..a27855230adb 100644 --- a/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.h +++ b/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.h @@ -29,6 +29,7 @@ typedef void (^UpdatedDownloads)(NSArray *downloads); // Can throw exceptions if the transaction type is purchasing, should always used in a @try block. - (void)finishTransaction:(nonnull SKPaymentTransaction *)transaction; - (void)restoreTransactions:(nullable NSString *)applicationName; +- (void)presentCodeRedemptionSheet; - (NSArray *)getUnfinishedTransactions; // This method needs to be called before any other methods. diff --git a/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.m b/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.m index ecbd237c90ce..8d179aee7ba8 100644 --- a/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.m +++ b/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.m @@ -66,6 +66,14 @@ - (void)restoreTransactions:(nullable NSString *)applicationName { } } +- (void)presentCodeRedemptionSheet { + if (@available(iOS 14, *)) { + [self.queue presentCodeRedemptionSheet]; + } else { + NSLog(@"presentCodeRedemptionSheet is only available on iOS 14 or newer"); + } +} + #pragma mark - observing // Sent when the transaction array has changed (additions or state changes). Client should check diff --git a/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m b/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m index 9b44ad766a98..e9b6bb9b8490 100644 --- a/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m +++ b/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m @@ -93,6 +93,9 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result [self finishTransaction:call result:result]; } else if ([@"-[InAppPurchasePlugin restoreTransactions:result:]" isEqualToString:call.method]) { [self restoreTransactions:call result:result]; + } else if ([@"-[InAppPurchasePlugin presentCodeRedemptionSheet:result:]" + isEqualToString:call.method]) { + [self presentCodeRedemptionSheet:call result:result]; } else if ([@"-[InAppPurchasePlugin retrieveReceiptData:result:]" isEqualToString:call.method]) { [self retrieveReceiptData:call result:result]; } else if ([@"-[InAppPurchasePlugin refreshReceipt:result:]" isEqualToString:call.method]) { @@ -246,6 +249,11 @@ - (void)restoreTransactions:(FlutterMethodCall *)call result:(FlutterResult)resu result(nil); } +- (void)presentCodeRedemptionSheet:(FlutterMethodCall *)call result:(FlutterResult)result { + [self.paymentQueueHandler presentCodeRedemptionSheet]; + result(nil); +} + - (void)retrieveReceiptData:(FlutterMethodCall *)call result:(FlutterResult)result { FlutterError *error = nil; NSString *receiptData = [self.receiptManager retrieveReceiptWithError:&error]; diff --git a/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m b/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m index 4025e9270fa9..31e0f255034d 100644 --- a/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m +++ b/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m @@ -250,6 +250,22 @@ - (void)testRefreshReceiptRequest { XCTAssertTrue(result); } +- (void)testPresentCodeRedemptionSheet { + XCTestExpectation* expectation = + [self expectationWithDescription:@"expect successfully present Code Redemption Sheet"]; + FlutterMethodCall* call = [FlutterMethodCall + methodCallWithMethodName:@"-[InAppPurchasePlugin presentCodeRedemptionSheet:result:]" + arguments:nil]; + __block BOOL callbackInvoked = NO; + [self.plugin handleMethodCall:call + result:^(id r) { + callbackInvoked = YES; + [expectation fulfill]; + }]; + [self waitForExpectations:@[ expectation ] timeout:5]; + XCTAssertTrue(callbackInvoked); +} + - (void)testGetPendingTransactions { XCTestExpectation* expectation = [self expectationWithDescription:@"expect success"]; FlutterMethodCall* call = diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart b/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart index 79a4a61fb328..e437e7f99cfc 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart @@ -201,6 +201,11 @@ class AppStoreConnection implements InAppPurchaseConnection { ); return productDetailsResponse; } + + @override + Future presentCodeRedemptionSheet() { + return _skPaymentQueueWrapper.presentCodeRedemptionSheet(); + } } class _TransactionObserver implements SKTransactionObserverWrapper { diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart b/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart index c45512ed353f..83435d23d395 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart @@ -179,6 +179,12 @@ class GooglePlayConnection 'The method only works on iOS.'); } + @override + Future presentCodeRedemptionSheet() async { + throw UnsupportedError( + 'The method only works on iOS.'); + } + /// Resets the connection instance. /// /// The next call to [instance] will create a new instance. Should only be diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart b/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart index aac5eae93e55..751bab62803c 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart @@ -239,6 +239,12 @@ abstract class InAppPurchaseConnection { /// Throws an [UnsupportedError] on Android. Future refreshPurchaseVerificationData(); + /// (App Store only) present Code Redemption Sheet. + /// Available on devices running iOS 14 and iPadOS 14 and later. + /// + /// Throws an [UnsupportedError] on Android. + Future presentCodeRedemptionSheet(); + /// The [InAppPurchaseConnection] implemented for this platform. /// /// Throws an [UnsupportedError] when accessed on a platform other than diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart index d56fbd00c6fe..f17166fbc969 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart @@ -137,6 +137,17 @@ class SKPaymentQueueWrapper { applicationUserName); } + /// Present Code Redemption Sheet + /// + /// Use this to allow Users to enter and redeem Codes + /// + /// This method triggers [`-[SKPayment + /// presentCodeRedemptionSheet]`](https://developer.apple.com/documentation/storekit/skpaymentqueue/3566726-presentcoderedemptionsheet?language=objc) + Future presentCodeRedemptionSheet() async { + await channel.invokeMethod( + '-[InAppPurchasePlugin presentCodeRedemptionSheet:result:]'); + } + // Triage a method channel call from the platform and triggers the correct observer method. Future _handleObserverCallbacks(MethodCall call) async { assert(_observer != null, diff --git a/packages/in_app_purchase/pubspec.yaml b/packages/in_app_purchase/pubspec.yaml index 3d121fd51e5e..c7582f91d8c2 100644 --- a/packages/in_app_purchase/pubspec.yaml +++ b/packages/in_app_purchase/pubspec.yaml @@ -1,7 +1,7 @@ name: in_app_purchase description: A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases through the App Store and Google Play. homepage: https://github.com/flutter/plugins/tree/master/packages/in_app_purchase -version: 0.5.0 +version: 0.5.1 dependencies: flutter: diff --git a/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart b/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart index bfcab085e26a..a6f9b07a59b3 100644 --- a/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart +++ b/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart @@ -300,6 +300,13 @@ void main() { throwsUnsupportedError); }); }); + + group('present code redemption sheet', () { + test('null', () async { + expect( + await AppStoreConnection.instance.presentCodeRedemptionSheet(), null); + }); + }); } class FakeIOSPlatform { diff --git a/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart b/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart index 5a265b8de907..6630b4e1734a 100644 --- a/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart +++ b/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart @@ -238,6 +238,13 @@ void main() { }); }); + group('present code redemption sheet', () { + test('should throw on android', () { + expect(GooglePlayConnection.instance.presentCodeRedemptionSheet(), + throwsUnsupportedError); + }); + }); + group('make payment', () { final String launchMethodName = 'BillingClient#launchBillingFlow(Activity, BillingFlowParams)'; diff --git a/packages/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart b/packages/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart index d41a1269d6c9..8df380bc223b 100644 --- a/packages/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart +++ b/packages/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart @@ -133,6 +133,15 @@ void main() { expect(fakeIOSPlatform.applicationNameHasTransactionRestored, 'aUserID'); }); }); + + group('Code Redemption Sheet', () { + test('presentCodeRedemptionSheet should not throw', () async { + expect(fakeIOSPlatform.presentCodeRedemption, false); + await SKPaymentQueueWrapper().presentCodeRedemptionSheet(); + expect(fakeIOSPlatform.presentCodeRedemption, true); + fakeIOSPlatform.presentCodeRedemption = false; + }); + }); } class FakeIOSPlatform { @@ -153,6 +162,9 @@ class FakeIOSPlatform { List> transactionsFinished = []; String applicationNameHasTransactionRestored = ''; + // present Code Redemption + bool presentCodeRedemption = false; + Future onMethodCall(MethodCall call) { switch (call.method) { // request makers @@ -193,6 +205,9 @@ class FakeIOSPlatform { case '-[InAppPurchasePlugin restoreTransactions:result:]': applicationNameHasTransactionRestored = call.arguments; return Future.sync(() {}); + case '-[InAppPurchasePlugin presentCodeRedemptionSheet:result:]': + presentCodeRedemption = true; + return Future.sync(() {}); } return Future.sync(() {}); } From fc1b17ea3728768c590272a28f1d23691562505e Mon Sep 17 00:00:00 2001 From: Emmanuel Garcia Date: Fri, 5 Mar 2021 15:26:44 -0800 Subject: [PATCH 0252/1565] Bring HTML inputs into view automatically (#3655) --- packages/webview_flutter/CHANGELOG.md | 5 + .../webviewflutter/FlutterWebView.java | 30 ++++- .../webview_flutter_test.dart | 124 +++++++++++++++++- .../lib/src/webview_method_channel.dart | 5 +- .../webview_flutter/lib/webview_flutter.dart | 3 + packages/webview_flutter/pubspec.yaml | 2 +- 6 files changed, 153 insertions(+), 16 deletions(-) diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index 139f120f12b2..6d2b4bb26815 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.0.2 + +* Fixes bug where text fields are hidden behind the keyboard +when hybrid composition is used [flutter/issues/75667](https://github.com/flutter/flutter/issues/75667). + ## 2.0.1 * Run CocoaPods iOS tests in RunnerUITests target diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index 4578c7e0d1fe..022f1c3597e7 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -29,7 +29,7 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { private static final String JS_CHANNEL_NAMES_FIELD = "javascriptChannelNames"; - private final InputAwareWebView webView; + private final WebView webView; private final MethodChannel methodChannel; private final FlutterWebViewClient flutterWebViewClient; private final Handler platformThreadHandler; @@ -92,7 +92,13 @@ public void onProgressChanged(WebView view, int progress) { DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); displayListenerProxy.onPreWebViewInitialization(displayManager); - webView = new InputAwareWebView(context, containerView); + + Boolean usesHybridComposition = (Boolean) params.get("usesHybridComposition"); + webView = + (usesHybridComposition) + ? new WebView(context) + : new InputAwareWebView(context, containerView); + displayListenerProxy.onPostWebViewInitialization(displayManager); platformThreadHandler = new Handler(context.getMainLooper()); @@ -140,7 +146,9 @@ public View getView() { // of Flutter but used as an override anyway wherever it's actually defined. // TODO(mklim): Add the @Override annotation once flutter/engine#9727 rolls to stable. public void onInputConnectionUnlocked() { - webView.unlockInputConnection(); + if (webView instanceof InputAwareWebView) { + ((InputAwareWebView) webView).unlockInputConnection(); + } } // @Override @@ -150,7 +158,9 @@ public void onInputConnectionUnlocked() { // of Flutter but used as an override anyway wherever it's actually defined. // TODO(mklim): Add the @Override annotation once flutter/engine#9727 rolls to stable. public void onInputConnectionLocked() { - webView.lockInputConnection(); + if (webView instanceof InputAwareWebView) { + ((InputAwareWebView) webView).lockInputConnection(); + } } // @Override @@ -160,7 +170,9 @@ public void onInputConnectionLocked() { // of Flutter but used as an override anyway wherever it's actually defined. // TODO(mklim): Add the @Override annotation once stable passes v1.10.9. public void onFlutterViewAttached(View flutterView) { - webView.setContainerView(flutterView); + if (webView instanceof InputAwareWebView) { + ((InputAwareWebView) webView).setContainerView(flutterView); + } } // @Override @@ -170,7 +182,9 @@ public void onFlutterViewAttached(View flutterView) { // of Flutter but used as an override anyway wherever it's actually defined. // TODO(mklim): Add the @Override annotation once stable passes v1.10.9. public void onFlutterViewDetached() { - webView.setContainerView(null); + if (webView instanceof InputAwareWebView) { + ((InputAwareWebView) webView).setContainerView(null); + } } @Override @@ -425,7 +439,9 @@ private void updateUserAgent(String userAgent) { @Override public void dispose() { methodChannel.setMethodCallHandler(null); - webView.dispose(); + if (webView instanceof InputAwareWebView) { + ((InputAwareWebView) webView).dispose(); + } webView.destroy(); } } 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 50af77fe6c6e..d91ccc53b231 100644 --- a/packages/webview_flutter/example/integration_test/webview_flutter_test.dart +++ b/packages/webview_flutter/example/integration_test/webview_flutter_test.dart @@ -823,7 +823,7 @@ void main() { }); }); - group('$SurfaceAndroidWebView', () { + group('SurfaceAndroidWebView', () { setUpAll(() { WebView.platform = SurfaceAndroidWebView(); }); @@ -898,8 +898,113 @@ void main() { scrollPosY = await controller.getScrollY(); expect(X_SCROLL * 2, scrollPosX); expect(Y_SCROLL * 2, scrollPosY); - }); - }, skip: !Platform.isAndroid); + }, skip: !Platform.isAndroid); + + testWidgets('inputs are scrolled into view when focused', + (WidgetTester tester) async { + final String scrollTestPage = ''' + + + + + + +
+ + + + '''; + + final String scrollTestPageBase64 = + base64Encode(const Utf8Encoder().convert(scrollTestPage)); + + final Completer pageLoaded = Completer(); + final Completer controllerCompleter = + Completer(); + + await tester.runAsync(() async { + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: SizedBox( + width: 200, + height: 200, + child: WebView( + initialUrl: + 'data:text/html;charset=utf-8;base64,$scrollTestPageBase64', + onWebViewCreated: (WebViewController controller) { + controllerCompleter.complete(controller); + }, + onPageFinished: (String url) { + pageLoaded.complete(null); + }, + javascriptMode: JavascriptMode.unrestricted, + ), + ), + ), + ); + await Future.delayed(Duration(milliseconds: 20)); + await tester.pump(); + }); + + final WebViewController controller = await controllerCompleter.future; + await pageLoaded.future; + final String viewportRectJSON = await _evaluateJavascript( + controller, 'JSON.stringify(viewport.getBoundingClientRect())'); + final Map viewportRectRelativeToViewport = + jsonDecode(viewportRectJSON); + + // Check that the input is originally outside of the viewport. + + final String initialInputClientRectJSON = await _evaluateJavascript( + controller, 'JSON.stringify(inputEl.getBoundingClientRect())'); + final Map initialInputClientRectRelativeToViewport = + jsonDecode(initialInputClientRectJSON); + + expect( + initialInputClientRectRelativeToViewport['bottom'] <= + viewportRectRelativeToViewport['bottom'], + isFalse); + + await controller.evaluateJavascript('inputEl.focus()'); + + // Check that focusing the input brought it into view. + + final String lastInputClientRectJSON = await _evaluateJavascript( + controller, 'JSON.stringify(inputEl.getBoundingClientRect())'); + final Map lastInputClientRectRelativeToViewport = + jsonDecode(lastInputClientRectJSON); + + expect( + lastInputClientRectRelativeToViewport['top'] >= + viewportRectRelativeToViewport['top'], + isTrue); + expect( + lastInputClientRectRelativeToViewport['bottom'] <= + viewportRectRelativeToViewport['bottom'], + isTrue); + + expect( + lastInputClientRectRelativeToViewport['left'] >= + viewportRectRelativeToViewport['left'], + isTrue); + expect( + lastInputClientRectRelativeToViewport['right'] <= + viewportRectRelativeToViewport['right'], + isTrue); + }, skip: !Platform.isAndroid); + }); group('NavigationDelegate', () { final String blankPage = ""; @@ -966,7 +1071,8 @@ void main() { expect(error.failingUrl, isNull); } else if (Platform.isAndroid) { expect(error.errorType, isNotNull); - expect(error.failingUrl, 'https://www.notawebsite..com'); + expect(error.failingUrl.startsWith('https://www.notawebsite..com'), + isTrue); } }); @@ -1236,9 +1342,13 @@ String _webviewBool(bool value) { /// Returns the value used for the HTTP User-Agent: request header in subsequent HTTP requests. Future _getUserAgent(WebViewController controller) async { + return _evaluateJavascript(controller, 'navigator.userAgent;'); +} + +Future _evaluateJavascript( + WebViewController controller, String js) async { if (defaultTargetPlatform == TargetPlatform.iOS) { - return await controller.evaluateJavascript('navigator.userAgent;'); + return await controller.evaluateJavascript(js); } - return jsonDecode( - await controller.evaluateJavascript('navigator.userAgent;')); + return jsonDecode(await controller.evaluateJavascript(js)); } diff --git a/packages/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/lib/src/webview_method_channel.dart index ef1ed51835b8..e26604f74628 100644 --- a/packages/webview_flutter/lib/src/webview_method_channel.dart +++ b/packages/webview_flutter/lib/src/webview_method_channel.dart @@ -201,13 +201,16 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { /// This is used for the `creationParams` argument of the platform views created by /// [AndroidWebViewBuilder] and [CupertinoWebViewBuilder]. static Map creationParamsToMap( - CreationParams creationParams) { + CreationParams creationParams, { + bool usesHybridComposition = false, + }) { return { 'initialUrl': creationParams.initialUrl, 'settings': _webSettingsToMap(creationParams.webSettings), 'javascriptChannelNames': creationParams.javascriptChannelNames.toList(), 'userAgent': creationParams.userAgent, 'autoMediaPlaybackPolicy': creationParams.autoMediaPlaybackPolicy.index, + 'usesHybridComposition': usesHybridComposition, }; } } diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart index 7e4f3d6ac079..56315b6692a5 100644 --- a/packages/webview_flutter/lib/webview_flutter.dart +++ b/packages/webview_flutter/lib/webview_flutter.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; @@ -85,6 +86,7 @@ class SurfaceAndroidWebView extends AndroidWebView { Set>? gestureRecognizers, required WebViewPlatformCallbacksHandler webViewPlatformCallbacksHandler, }) { + assert(Platform.isAndroid); assert(webViewPlatformCallbacksHandler != null); return PlatformViewLink( viewType: 'plugins.flutter.io/webview', @@ -109,6 +111,7 @@ class SurfaceAndroidWebView extends AndroidWebView { layoutDirection: TextDirection.rtl, creationParams: MethodChannelWebViewPlatform.creationParamsToMap( creationParams, + usesHybridComposition: true, ), creationParamsCodec: const StandardMessageCodec(), ) diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml index 0640386c517d..6ee9e119bd3a 100644 --- a/packages/webview_flutter/pubspec.yaml +++ b/packages/webview_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: webview_flutter description: A Flutter plugin that provides a WebView widget on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter -version: 2.0.1 +version: 2.0.2 environment: sdk: ">=2.12.0-259.9.beta <3.0.0" From b3f750827bd22cad544667233dd1039770674439 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Fri, 5 Mar 2021 16:54:57 -0800 Subject: [PATCH 0253/1565] [ci] Disable analyze on stable for web plugins that contains null safety integration tests. (#3681) --- .cirrus.yml | 12 ++++++++++-- .../example/test_driver/test/integration_test.dart | 1 + .../example/pubspec.yaml | 4 ---- .../example/test_driver/test/integration_test.dart | 1 + 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index ea27c88b97e0..eac32d114269 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -37,13 +37,22 @@ task: test_script: - flutter channel $CHANNEL - ./script/incremental_build.sh test - - name: analyze + - name: analyze_master env: matrix: CHANNEL: "master" + script: + - flutter channel $CHANNEL + - ./script/incremental_build.sh analyze + ## TODO(cyanglaz): + ## Combing stable and master analyze jobs when integration test null safety is ready on flutter stable. + - name: analyze_stable + env: + matrix: CHANNEL: "stable" script: - flutter channel $CHANNEL + - find . -depth -type d -wholename '*_web/example' -exec rm -rf {} \; - ./script/incremental_build.sh analyze ### Android tasks ### - name: build_all_plugins_apk @@ -67,7 +76,6 @@ task: env: matrix: CHANNEL: "master" - CHANNEL: "stable" build_script: - flutter channel $CHANNEL - ./script/incremental_build.sh build-examples --web diff --git a/packages/connectivity/connectivity_macos/example/test_driver/test/integration_test.dart b/packages/connectivity/connectivity_macos/example/test_driver/test/integration_test.dart index c0cbdcab2fb6..425dac924e7c 100644 --- a/packages/connectivity/connectivity_macos/example/test_driver/test/integration_test.dart +++ b/packages/connectivity/connectivity_macos/example/test_driver/test/integration_test.dart @@ -2,6 +2,7 @@ // 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:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml index d3b428d190c9..c96ca065f081 100755 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml +++ b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml @@ -16,10 +16,6 @@ dependencies: dev_dependencies: pedantic: ^1.10.0 - integration_test: - path: ../../../integration_test - flutter_driver: - sdk: flutter flutter: uses-material-design: true diff --git a/packages/image_picker/image_picker/example/test_driver/test/integration_test.dart b/packages/image_picker/image_picker/example/test_driver/test/integration_test.dart index 7a2c21338786..0352d4aaeb2d 100644 --- a/packages/image_picker/image_picker/example/test_driver/test/integration_test.dart +++ b/packages/image_picker/image_picker/example/test_driver/test/integration_test.dart @@ -2,6 +2,7 @@ // 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'; From 26879dbd2f75f8f4f67ac8183aeefc394e6a1efa Mon Sep 17 00:00:00 2001 From: Ian Hickson Date: Fri, 5 Mar 2021 17:54:03 -0800 Subject: [PATCH 0254/1565] Import flutter_test for future compatibility (#3665) --- packages/camera/camera/test/utils/method_channel_mock.dart | 1 + .../test/utils/method_channel_mock.dart | 1 + .../app_store_connection_test.dart | 5 ++--- .../google_play_connection_test.dart | 3 +-- packages/sensors/test/sensors_test.dart | 3 +-- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/camera/camera/test/utils/method_channel_mock.dart b/packages/camera/camera/test/utils/method_channel_mock.dart index fdbd9a18f29c..c667bed76e89 100644 --- a/packages/camera/camera/test/utils/method_channel_mock.dart +++ b/packages/camera/camera/test/utils/method_channel_mock.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; class MethodChannelMock { final Duration? delay; diff --git a/packages/camera/camera_platform_interface/test/utils/method_channel_mock.dart b/packages/camera/camera_platform_interface/test/utils/method_channel_mock.dart index fdbd9a18f29c..c667bed76e89 100644 --- a/packages/camera/camera_platform_interface/test/utils/method_channel_mock.dart +++ b/packages/camera/camera_platform_interface/test/utils/method_channel_mock.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; class MethodChannelMock { final Duration? delay; diff --git a/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart b/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart index a6f9b07a59b3..14383b96774d 100644 --- a/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart +++ b/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart @@ -6,9 +6,8 @@ import 'dart:async'; import 'dart:io'; import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart' show TestWidgetsFlutterBinding; +import 'package:flutter_test/flutter_test.dart'; import 'package:in_app_purchase/src/in_app_purchase/purchase_details.dart'; -import 'package:test/test.dart'; import 'package:in_app_purchase/src/channel.dart'; import 'package:in_app_purchase/src/in_app_purchase/app_store_connection.dart'; @@ -227,7 +226,7 @@ void main() { expect( () => AppStoreConnection.instance .buyConsumable(purchaseParam: purchaseParam, autoConsume: false), - throwsA(TypeMatcher())); + throwsA(isInstanceOf())); }); test('should get failed purchase status', () async { diff --git a/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart b/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart index 6630b4e1734a..13582736f86f 100644 --- a/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart +++ b/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart @@ -5,9 +5,8 @@ import 'dart:async'; import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart' show TestWidgetsFlutterBinding; +import 'package:flutter_test/flutter_test.dart'; import 'package:in_app_purchase/src/in_app_purchase/purchase_details.dart'; -import 'package:test/test.dart'; import 'package:flutter/widgets.dart' as widgets; import 'package:in_app_purchase/billing_client_wrappers.dart'; diff --git a/packages/sensors/test/sensors_test.dart b/packages/sensors/test/sensors_test.dart index 93e0959befed..fe56c7e5a36f 100644 --- a/packages/sensors/test/sensors_test.dart +++ b/packages/sensors/test/sensors_test.dart @@ -5,9 +5,8 @@ import 'dart:typed_data'; import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart' show TestWidgetsFlutterBinding; +import 'package:flutter_test/flutter_test.dart'; import 'package:sensors/sensors.dart'; -import 'package:test/test.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); From e6156827a2b926cbe117f386524ded214625fa80 Mon Sep 17 00:00:00 2001 From: Guilherme Girotto Date: Sat, 6 Mar 2021 14:39:52 -0300 Subject: [PATCH 0255/1565] [google_sign_in] Updates google_sign_in_platform_interfaces adding parametrized `clientId` (#3686) --- .../google_sign_in_platform_interface/CHANGELOG.md | 4 ++++ .../lib/src/method_channel_google_sign_in.dart | 1 + .../google_sign_in_platform_interface/pubspec.yaml | 2 +- .../test/method_channel_google_sign_in_test.dart | 3 ++- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md b/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md index dd6c22fbef29..ee43db685339 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +* Updates `init` function in `MethodChannelGoogleSignIn` to parametrize `clientId` property. + ## 2.0.0 * Migrate to null-safety. diff --git a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart index b36676e2376d..ea2426159e21 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart @@ -30,6 +30,7 @@ class MethodChannelGoogleSignIn extends GoogleSignInPlatform { 'signInOption': signInOption.toString(), 'scopes': scopes, 'hostedDomain': hostedDomain, + 'clientId': clientId, }); } diff --git a/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml b/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml index 56b4033dcb88..195bff28d992 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the google_sign_in plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0 +version: 2.0.1 dependencies: flutter: diff --git a/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart b/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart index 325f0c10a6ab..9447cd0edfc4 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart @@ -100,11 +100,12 @@ void main() { hostedDomain: 'example.com', scopes: ['two', 'scopes'], signInOption: SignInOption.games, - clientId: 'UNUSED!'); + clientId: 'fakeClientId'); }: isMethodCall('init', arguments: { 'hostedDomain': 'example.com', 'scopes': ['two', 'scopes'], 'signInOption': 'SignInOption.games', + 'clientId': 'fakeClientId', }), () { googleSignIn.getTokens( From 3acc0cf03051a2888b06753ebe7c4cc22ced191a Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Mon, 8 Mar 2021 10:20:38 -0800 Subject: [PATCH 0256/1565] [extension_google_sign_in_as_googleapis_auth] Update import (#3689) Replaces deprecated import with current version. --- .../lib/extension_google_sign_in_as_googleapis_auth.dart | 2 +- .../test/extension_google_sign_in_as_googleapis_auth_test.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/lib/extension_google_sign_in_as_googleapis_auth.dart b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/lib/extension_google_sign_in_as_googleapis_auth.dart index 8c8ede5eee1a..b88be661fde4 100644 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/lib/extension_google_sign_in_as_googleapis_auth.dart +++ b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/lib/extension_google_sign_in_as_googleapis_auth.dart @@ -6,7 +6,7 @@ import 'package:meta/meta.dart'; import 'package:google_sign_in/google_sign_in.dart'; -import 'package:googleapis_auth/auth.dart' as googleapis_auth; +import 'package:googleapis_auth/googleapis_auth.dart' as googleapis_auth; import 'package:http/http.dart' as http; /// Extension on [GoogleSignIn] that adds an `authenticatedClient` method. diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/test/extension_google_sign_in_as_googleapis_auth_test.dart b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/test/extension_google_sign_in_as_googleapis_auth_test.dart index 508f366eacde..d747b3d19c63 100644 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/test/extension_google_sign_in_as_googleapis_auth_test.dart +++ b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/test/extension_google_sign_in_as_googleapis_auth_test.dart @@ -5,7 +5,7 @@ // https://developers.google.com/open-source/licenses/bsd import 'package:google_sign_in/google_sign_in.dart'; -import 'package:googleapis_auth/auth.dart' as auth; +import 'package:googleapis_auth/googleapis_auth.dart' as auth; import 'package:extension_google_sign_in_as_googleapis_auth/extension_google_sign_in_as_googleapis_auth.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:test/fake.dart'; From a2c855def90032cafbc67a007813a22053e53aa3 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 8 Mar 2021 12:17:52 -0800 Subject: [PATCH 0257/1565] [google_sign_in] fix test(#3690) --- .../test/google_sign_in_test.dart | 99 +++++-------------- 1 file changed, 24 insertions(+), 75 deletions(-) diff --git a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart index 2a8d65e32ffd..79fa74ad1be1 100755 --- a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart +++ b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart @@ -64,11 +64,7 @@ void main() { expect( log, [ - isMethodCall('init', arguments: { - 'signInOption': 'SignInOption.standard', - 'scopes': [], - 'hostedDomain': null, - }), + _isSignInMethodCall(), isMethodCall('signInSilently', arguments: null), ], ); @@ -80,11 +76,7 @@ void main() { expect( log, [ - isMethodCall('init', arguments: { - 'signInOption': 'SignInOption.standard', - 'scopes': [], - 'hostedDomain': null, - }), + _isSignInMethodCall(), isMethodCall('signIn', arguments: null), ], ); @@ -94,11 +86,7 @@ void main() { await googleSignIn.signOut(); expect(googleSignIn.currentUser, isNull); expect(log, [ - isMethodCall('init', arguments: { - 'signInOption': 'SignInOption.standard', - 'scopes': [], - 'hostedDomain': null, - }), + _isSignInMethodCall(), isMethodCall('signOut', arguments: null), ]); }); @@ -109,11 +97,7 @@ void main() { expect( log, [ - isMethodCall('init', arguments: { - 'signInOption': 'SignInOption.standard', - 'scopes': [], - 'hostedDomain': null, - }), + _isSignInMethodCall(), isMethodCall('disconnect', arguments: null), ], ); @@ -126,11 +110,7 @@ void main() { expect( log, [ - isMethodCall('init', arguments: { - 'signInOption': 'SignInOption.standard', - 'scopes': [], - 'hostedDomain': null, - }), + _isSignInMethodCall(), isMethodCall('disconnect', arguments: null), ], ); @@ -140,11 +120,7 @@ void main() { final bool result = await googleSignIn.isSignedIn(); expect(result, isTrue); expect(log, [ - isMethodCall('init', arguments: { - 'signInOption': 'SignInOption.standard', - 'scopes': [], - 'hostedDomain': null, - }), + _isSignInMethodCall(), isMethodCall('isSignedIn', arguments: null), ]); }); @@ -159,11 +135,7 @@ void main() { expect( log, [ - isMethodCall('init', arguments: { - 'signInOption': 'SignInOption.standard', - 'scopes': [], - 'hostedDomain': null, - }), + _isSignInMethodCall(), isMethodCall('signInSilently', arguments: null), isMethodCall('signIn', arguments: null), ], @@ -187,11 +159,7 @@ void main() { expect( log, [ - isMethodCall('init', arguments: { - 'signInOption': 'SignInOption.standard', - 'scopes': [], - 'hostedDomain': null, - }), + _isSignInMethodCall(), isMethodCall('signInSilently', arguments: null), ], ); @@ -204,11 +172,7 @@ void main() { expect( log, [ - isMethodCall('init', arguments: { - 'signInOption': 'SignInOption.standard', - 'scopes': [], - 'hostedDomain': null, - }), + _isSignInMethodCall(), isMethodCall('signInSilently', arguments: null), isMethodCall('signIn', arguments: null), ], @@ -226,11 +190,7 @@ void main() { expect( log, [ - isMethodCall('init', arguments: { - 'signInOption': 'SignInOption.standard', - 'scopes': [], - 'hostedDomain': null, - }), + _isSignInMethodCall(), isMethodCall('signInSilently', arguments: null), ], ); @@ -257,11 +217,7 @@ void main() { expect( log, [ - isMethodCall('init', arguments: { - 'signInOption': 'SignInOption.standard', - 'scopes': [], - 'hostedDomain': null, - }), + _isSignInMethodCall(), isMethodCall('signOut', arguments: null), isMethodCall('signOut', arguments: null), isMethodCall('disconnect', arguments: null), @@ -282,11 +238,7 @@ void main() { expect( log, [ - isMethodCall('init', arguments: { - 'signInOption': 'SignInOption.standard', - 'scopes': [], - 'hostedDomain': null, - }), + _isSignInMethodCall(), isMethodCall('signInSilently', arguments: null), isMethodCall('signOut', arguments: null), isMethodCall('signIn', arguments: null), @@ -333,11 +285,7 @@ void main() { expect( log, [ - isMethodCall('init', arguments: { - 'signInOption': 'SignInOption.standard', - 'scopes': [], - 'hostedDomain': null, - }), + _isSignInMethodCall(), isMethodCall('signInSilently', arguments: null), ], ); @@ -352,11 +300,7 @@ void main() { expect( log, [ - isMethodCall('init', arguments: { - 'signInOption': 'SignInOption.games', - 'scopes': [], - 'hostedDomain': null, - }), + _isSignInMethodCall(signInOption: 'SignInOption.games'), isMethodCall('signInSilently', arguments: null), ], ); @@ -391,11 +335,7 @@ void main() { expect( log, [ - isMethodCall('init', arguments: { - 'signInOption': 'SignInOption.standard', - 'scopes': [], - 'hostedDomain': null, - }), + _isSignInMethodCall(), isMethodCall('signIn', arguments: null), isMethodCall('requestScopes', arguments: { 'scopes': ['testScope'], @@ -447,3 +387,12 @@ void main() { }); }); } + +Matcher _isSignInMethodCall({String signInOption = 'SignInOption.standard'}) { + return isMethodCall('init', arguments: { + 'signInOption': signInOption, + 'scopes': [], + 'hostedDomain': null, + 'clientId': null, + }); +} From 728129a8ab7f132aa5dc298057fe98371e792714 Mon Sep 17 00:00:00 2001 From: zhenqiu1101 Date: Mon, 8 Mar 2021 12:29:04 -0800 Subject: [PATCH 0258/1565] [Video_Player] Remove the deprecated API reference. (#3669) --- packages/video_player/video_player/CHANGELOG.md | 4 ++++ .../java/io/flutter/plugins/videoplayer/VideoPlayer.java | 9 ++------- packages/video_player/video_player/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index 57ba54e0a7bc..e5c30a0389e4 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +* Remove the deprecated API "exoPlayer.setAudioAttributes". + ## 2.0.0 * Migrate to null safety. diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java index 65657509b49f..c3a31432e896 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java @@ -5,7 +5,6 @@ import android.content.Context; import android.net.Uri; -import android.os.Build; import android.view.Surface; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.ExoPlaybackException; @@ -222,12 +221,8 @@ void sendBufferingUpdate() { @SuppressWarnings("deprecation") private static void setAudioAttributes(SimpleExoPlayer exoPlayer, boolean isMixMode) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - exoPlayer.setAudioAttributes( - new AudioAttributes.Builder().setContentType(C.CONTENT_TYPE_MOVIE).build(), !isMixMode); - } else { - exoPlayer.setAudioStreamType(C.STREAM_TYPE_MUSIC); - } + exoPlayer.setAudioAttributes( + new AudioAttributes.Builder().setContentType(C.CONTENT_TYPE_MOVIE).build(), !isMixMode); } void play() { diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index fedc46c721b1..3c6a34c7f78c 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -1,7 +1,7 @@ name: video_player description: Flutter plugin for displaying inline video with other Flutter widgets on Android, iOS, and web. -version: 2.0.0 +version: 2.0.1 homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player flutter: From d44d155fa501c6bd5ea5c6d79e13cdeaa4274c70 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Mon, 8 Mar 2021 18:05:00 -0800 Subject: [PATCH 0259/1565] Skip pod lint tests (#3692) --- script/tool/lib/src/lint_podspecs_command.dart | 1 + script/tool/test/lint_podspecs_command_test.dart | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/script/tool/lib/src/lint_podspecs_command.dart b/script/tool/lib/src/lint_podspecs_command.dart index 749d67ee5f16..13de64415e9e 100644 --- a/script/tool/lib/src/lint_podspecs_command.dart +++ b/script/tool/lib/src/lint_podspecs_command.dart @@ -123,6 +123,7 @@ class LintPodspecsCommand extends PluginCommand { 'lint', podspecPath, '--configuration=Debug', // Release targets unsupported arm64 simulators. Use Debug to only build against targeted x86_64 simulator devices. + '--skip-tests', if (allowWarnings) '--allow-warnings', if (libraryLint) '--use-libraries' ]; diff --git a/script/tool/test/lint_podspecs_command_test.dart b/script/tool/test/lint_podspecs_command_test.dart index e0411d5cffd1..1c59d2d7e55a 100644 --- a/script/tool/test/lint_podspecs_command_test.dart +++ b/script/tool/test/lint_podspecs_command_test.dart @@ -82,6 +82,7 @@ void main() { 'lint', p.join(plugin1Dir.path, 'ios', 'plugin1.podspec'), '--configuration=Debug', + '--skip-tests', '--use-libraries' ], mockPackagesDir.path), @@ -92,6 +93,7 @@ void main() { 'lint', p.join(plugin1Dir.path, 'ios', 'plugin1.podspec'), '--configuration=Debug', + '--skip-tests', ], mockPackagesDir.path), ]), @@ -141,6 +143,7 @@ void main() { 'lint', p.join(plugin1Dir.path, 'plugin1.podspec'), '--configuration=Debug', + '--skip-tests', '--allow-warnings', '--use-libraries' ], @@ -152,6 +155,7 @@ void main() { 'lint', p.join(plugin1Dir.path, 'plugin1.podspec'), '--configuration=Debug', + '--skip-tests', '--allow-warnings', ], mockPackagesDir.path), From 8f6d3d161e061d8e295056a592b194f5a1a2bae5 Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Tue, 9 Mar 2021 17:45:01 -0800 Subject: [PATCH 0260/1565] [extension_google_sign_in_as_googleapis_auth] Deleted. (#3694) The package now lives in flutter/packages. --- .../.gitignore | 75 --- .../.metadata | 10 - .../CHANGELOG.md | 24 - .../LICENSE | 25 - .../README.md | 46 -- .../example/README.md | 8 - .../example/android/app/build.gradle | 64 --- .../example/android/app/google-services.json | 246 --------- .../gradle/wrapper/gradle-wrapper.properties | 5 - .../android/app/src/main/AndroidManifest.xml | 25 - .../main/java/io/flutter/plugins/.gitignore | 1 - .../EmbeddingV1Activity.java | 19 - .../EmbeddingV1ActivityTest.java | 18 - .../FlutterActivityTest.java | 17 - .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 544 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 442 -> 0 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 721 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 1031 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 1443 -> 0 bytes .../app/src/main/res/values/strings.xml | 4 - .../example/android/build.gradle | 29 - .../example/android/gradle.properties | 4 - .../gradle/wrapper/gradle-wrapper.properties | 5 - .../example/android/settings.gradle | 15 - .../ios/Flutter/AppFrameworkInfo.plist | 30 -- .../example/ios/Flutter/Debug.xcconfig | 2 - .../example/ios/Flutter/Release.xcconfig | 2 - .../ios/GoogleSignInPluginTest/Info.plist | 22 - .../ios/Runner.xcodeproj/project.pbxproj | 502 ------------------ .../contents.xcworkspacedata | 10 - .../xcshareddata/xcschemes/Runner.xcscheme | 87 --- .../contents.xcworkspacedata | 10 - .../example/ios/Runner/AppDelegate.h | 10 - .../example/ios/Runner/AppDelegate.m | 17 - .../AppIcon.appiconset/Contents.json | 116 ---- .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 564 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 1588 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 1025 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 1716 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 1920 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 1895 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 3831 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 1888 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 3294 -> 0 bytes .../Icon-App-83.5x83.5@2x.png | Bin 3612 -> 0 bytes .../Runner/Base.lproj/LaunchScreen.storyboard | 27 - .../ios/Runner/Base.lproj/Main.storyboard | 26 - .../ios/Runner/GoogleService-Info.plist | 44 -- .../example/ios/Runner/Info.plist | 62 --- .../example/ios/Runner/main.m | 13 - .../example/lib/main.dart | 150 ------ .../example/pubspec.yaml | 25 - .../example/web/index.html | 11 - ...ion_google_sign_in_as_googleapis_auth.dart | 41 -- .../pubspec.yaml | 28 - ...oogle_sign_in_as_googleapis_auth_test.dart | 54 -- script/build_all_plugins_app.sh | 2 - 61 files changed, 1931 deletions(-) delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/.gitignore delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/.metadata delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/LICENSE delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/README.md delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/README.md delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/build.gradle delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/google-services.json delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/AndroidManifest.xml delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/.gitignore delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1Activity.java delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/res/values/strings.xml delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/build.gradle delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/gradle.properties delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/gradle/wrapper/gradle-wrapper.properties delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/settings.gradle delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Flutter/AppFrameworkInfo.plist delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Flutter/Debug.xcconfig delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Flutter/Release.xcconfig delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/GoogleSignInPluginTest/Info.plist delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner.xcodeproj/project.pbxproj delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner.xcworkspace/contents.xcworkspacedata delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/AppDelegate.h delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/AppDelegate.m delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Base.lproj/LaunchScreen.storyboard delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Base.lproj/Main.storyboard delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/GoogleService-Info.plist delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Info.plist delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/main.m delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/lib/main.dart delete mode 100755 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/web/index.html delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/lib/extension_google_sign_in_as_googleapis_auth.dart delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/pubspec.yaml delete mode 100644 packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/test/extension_google_sign_in_as_googleapis_auth_test.dart diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/.gitignore b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/.gitignore deleted file mode 100644 index bb431f0d5b47..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/.gitignore +++ /dev/null @@ -1,75 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.flutter-plugins-dependencies -.packages -.pub-cache/ -.pub/ -build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Flutter.podspec -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/Flutter/flutter_export_environment.sh -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/.metadata b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/.metadata deleted file mode 100644 index 2c91cc0fc35a..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/.metadata +++ /dev/null @@ -1,10 +0,0 @@ -# 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: 5e3e5a2a1a977c34b22f3709109fd237b5cab9c6 - channel: master - -project_type: package diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md deleted file mode 100644 index 5e29f340599b..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/CHANGELOG.md +++ /dev/null @@ -1,24 +0,0 @@ -## 2.0.0 - -* Migrate to null safety. -* Fixes the requested scopes to use the `GoogleSignIn` instance's `scopes`. - -## 1.0.4 - -* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. - -## 1.0.3 - -* Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) - -## 1.0.2 - -* Update Flutter SDK constraint. - -## 1.0.1 - -* Update android compileSdkVersion to 29. - -## 1.0.0 - -* First published version. diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/LICENSE b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/LICENSE deleted file mode 100644 index b707cc8221fb..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/LICENSE +++ /dev/null @@ -1,25 +0,0 @@ -Copyright 2020 The Flutter Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of Google LLC nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/README.md b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/README.md deleted file mode 100644 index 78ddb4bdc91b..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# extension_google_sign_in_as_googleapis_auth - -A bridge package between Flutter's [`google_sign_in` plugin](https://pub.dev/packages/google_sign_in) and Dart's [`googleapis` package](https://pub.dev/packages/googleapis), that is able to create [`googleapis_auth`-like `AuthClient` instances](https://pub.dev/documentation/googleapis_auth/latest/googleapis_auth.auth/AuthClient-class.html) directly from the `GoogleSignIn` plugin. - -## Usage - -This package is implemented as an [extension method](https://dart.dev/guides/language/extension-methods) on top of the `GoogleSignIn` plugin. - -In order to use it, you need to add a `dependency` to your `pubspec.yaml`. Then, wherever you're importing `package:google_sign_in/google_sign_in.dart`, add the following: - -```dart -... -import 'package:extension_google_sign_in_as_googleapis_auth/extension_google_sign_in_as_googleapis_auth.dart'; -... -``` - -From that moment on, your `GoogleSignIn` instance will have an additional `Future authenticatedClient()` method that you can call once your sign in is successful to retrieve an `AuthClient`. - -That object can then be used to create instances of `googleapis` API clients: - -```dart -... -final peopleApi = PeopleApi(await _googleSignIn.authenticatedClient()); -final response = await peopleApi.people.connections.list( - 'people/me', - personFields: 'names', -); -... -``` - -## Example - -This package contains a modified version of Flutter's Google Sign In example app that uses `package:googleapis`' API clients, instead of raw http requests. - -See it [here](https://github.com/flutter/plugins/blob/master/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/lib/main.dart). - -The original code (and its license) can be seen [here](https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in/example/lib/main.dart). - -## Testing - -Run tests with `flutter test`. - -## Issues and feedback - -Please file [issues](https://github.com/flutter/flutter/issues/new) -to send feedback or report a bug. Thank you! diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/README.md b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/README.md deleted file mode 100755 index a7ad235b71d5..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# extension_google_sign_in_example - -Demonstrates how to use the google_sign_in plugin with the `googleapis` package. - -## Getting Started - -For help getting started with Flutter, view our online -[documentation](https://flutter.dev/). diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/build.gradle b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/build.gradle deleted file mode 100755 index 2952c3b9c463..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/build.gradle +++ /dev/null @@ -1,64 +0,0 @@ -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} - -apply plugin: 'com.android.application' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - -android { - compileSdkVersion 29 - - lintOptions { - disable 'InvalidPackage' - } - - defaultConfig { - applicationId "io.flutter.plugins.googlesigninexample" - minSdkVersion 16 - targetSdkVersion 28 - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - } - - buildTypes { - release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig signingConfigs.debug - } - } - - testOptions { - unitTests.returnDefaultValues = true - } -} - -flutter { - source '../..' -} - -dependencies { - implementation 'com.google.android.gms:play-services-auth:16.0.1' - testImplementation'junit:junit:4.12' - testImplementation 'org.mockito:mockito-core:2.17.0' -} diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/google-services.json b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/google-services.json deleted file mode 100644 index efa524535553..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/google-services.json +++ /dev/null @@ -1,246 +0,0 @@ -{ - "project_info": { - "project_number": "479882132969", - "firebase_url": "https://my-flutter-proj.firebaseio.com", - "project_id": "my-flutter-proj", - "storage_bucket": "my-flutter-proj.appspot.com" - }, - "client": [ - { - "client_info": { - "mobilesdk_app_id": "1:479882132969:android:c73fd19ff7e2c0be", - "android_client_info": { - "package_name": "io.flutter.plugins.cameraexample" - } - }, - "oauth_client": [ - { - "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyCrZz9T0Pg0rDnpxfNuPBrOxGhXskfebXs" - } - ], - "services": { - "analytics_service": { - "status": 1 - }, - "appinvite_service": { - "status": 1, - "other_platform_oauth_client": [] - }, - "ads_service": { - "status": 2 - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:479882132969:android:632cdf3fc0a17139", - "android_client_info": { - "package_name": "io.flutter.plugins.firebasedynamiclinksexample" - } - }, - "oauth_client": [ - { - "client_id": "479882132969-32qusitiag53931ck80h121ajhlc5a7e.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "io.flutter.plugins.firebasedynamiclinksexample", - "certificate_hash": "e733b7a303250b63e06de6f7c9767c517d69cfa0" - } - }, - { - "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyCrZz9T0Pg0rDnpxfNuPBrOxGhXskfebXs" - } - ], - "services": { - "analytics_service": { - "status": 1 - }, - "appinvite_service": { - "status": 2, - "other_platform_oauth_client": [ - { - "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", - "client_type": 3 - }, - { - "client_id": "479882132969-gjp4e63ogu2h6guttj2ie6t3f10ic7i8.apps.googleusercontent.com", - "client_type": 2, - "ios_info": { - "bundle_id": "io.flutter.plugins.firebaseMlVisionExample" - } - } - ] - }, - "ads_service": { - "status": 2 - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:479882132969:android:ae50362b4bc06086", - "android_client_info": { - "package_name": "io.flutter.plugins.firebasemlvisionexample" - } - }, - "oauth_client": [ - { - "client_id": "479882132969-9pp74fkgmtvt47t9rikc1p861v7n85tn.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "io.flutter.plugins.firebasemlvisionexample", - "certificate_hash": "e733b7a303250b63e06de6f7c9767c517d69cfa0" - } - }, - { - "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyCrZz9T0Pg0rDnpxfNuPBrOxGhXskfebXs" - } - ], - "services": { - "analytics_service": { - "status": 1 - }, - "appinvite_service": { - "status": 2, - "other_platform_oauth_client": [ - { - "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", - "client_type": 3 - }, - { - "client_id": "479882132969-gjp4e63ogu2h6guttj2ie6t3f10ic7i8.apps.googleusercontent.com", - "client_type": 2, - "ios_info": { - "bundle_id": "io.flutter.plugins.firebaseMlVisionExample" - } - } - ] - }, - "ads_service": { - "status": 2 - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:479882132969:android:215a22700e1b466b", - "android_client_info": { - "package_name": "io.flutter.plugins.firebaseperformanceexample" - } - }, - "oauth_client": [ - { - "client_id": "479882132969-8h4kiv8m7ho4tvn6uuujsfcrf69unuf7.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "io.flutter.plugins.firebaseperformanceexample", - "certificate_hash": "e733b7a303250b63e06de6f7c9767c517d69cfa0" - } - }, - { - "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyCrZz9T0Pg0rDnpxfNuPBrOxGhXskfebXs" - } - ], - "services": { - "analytics_service": { - "status": 1 - }, - "appinvite_service": { - "status": 2, - "other_platform_oauth_client": [ - { - "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", - "client_type": 3 - }, - { - "client_id": "479882132969-gjp4e63ogu2h6guttj2ie6t3f10ic7i8.apps.googleusercontent.com", - "client_type": 2, - "ios_info": { - "bundle_id": "io.flutter.plugins.firebaseMlVisionExample" - } - } - ] - }, - "ads_service": { - "status": 2 - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:479882132969:android:5e9f1f89e134dc86", - "android_client_info": { - "package_name": "io.flutter.plugins.googlesigninexample" - } - }, - "oauth_client": [ - { - "client_id": "479882132969-90ml692hkonp587sl0v0rurmnvkekgrg.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "io.flutter.plugins.googlesigninexample", - "certificate_hash": "e733b7a303250b63e06de6f7c9767c517d69cfa0" - } - }, - { - "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyCrZz9T0Pg0rDnpxfNuPBrOxGhXskfebXs" - } - ], - "services": { - "analytics_service": { - "status": 1 - }, - "appinvite_service": { - "status": 2, - "other_platform_oauth_client": [ - { - "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", - "client_type": 3 - }, - { - "client_id": "479882132969-gjp4e63ogu2h6guttj2ie6t3f10ic7i8.apps.googleusercontent.com", - "client_type": 2, - "ios_info": { - "bundle_id": "io.flutter.plugins.firebaseMlVisionExample" - } - } - ] - }, - "ads_service": { - "status": 2 - } - } - } - ], - "configuration_version": "1" -} \ No newline at end of file diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 9a4163a4f5ee..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/AndroidManifest.xml b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/AndroidManifest.xml deleted file mode 100755 index df80f829c1e7..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/.gitignore b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/.gitignore deleted file mode 100755 index 9eb4563d2ae1..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/.gitignore +++ /dev/null @@ -1 +0,0 @@ -GeneratedPluginRegistrant.java diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1Activity.java b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1Activity.java deleted file mode 100644 index 5ec19822734c..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1Activity.java +++ /dev/null @@ -1,19 +0,0 @@ -// 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. - -package io.flutter.plugins.googlesigninexample; - -import android.os.Bundle; -import io.flutter.plugins.googlesignin.GoogleSignInPlugin; -import io.flutter.view.FlutterMain; - -@SuppressWarnings("deprecation") -public class EmbeddingV1Activity extends io.flutter.app.FlutterActivity { - @Override - protected void onCreate(Bundle savedInstanceState) { - FlutterMain.startInitialization(this); - super.onCreate(savedInstanceState); - GoogleSignInPlugin.registerWith(registrarFor("io.flutter.plugins.googlesignin")); - } -} diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java deleted file mode 100644 index 3e7250cea0ee..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2020 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. - -package io.flutter.plugins.googlesigninexample; - -import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.integration_test.FlutterTestRunner; -import org.junit.Rule; -import org.junit.runner.RunWith; - -@RunWith(FlutterTestRunner.class) -@SuppressWarnings("deprecation") -public class EmbeddingV1ActivityTest { - @Rule - public ActivityTestRule rule = - new ActivityTestRule<>(EmbeddingV1Activity.class); -} diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java deleted file mode 100644 index f9aa77b30e5d..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2020 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. - -package io.flutter.plugins.googlesigninexample; - -import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.integration_test.FlutterTestRunner; -import io.flutter.embedding.android.FlutterActivity; -import org.junit.Rule; -import org.junit.runner.RunWith; - -@RunWith(FlutterTestRunner.class) -public class FlutterActivityTest { - @Rule - public ActivityTestRule rule = new ActivityTestRule<>(FlutterActivity.class); -} diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100755 index db77bb4b7b0906d62b1847e87f15cdcacf6a4f29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100755 index 17987b79bb8a35cc66c3c1fd44f5a5526c1b78be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xx&nMcT!A!W`0S9QKQy;}1Cl^CgaH=;G9cpY;r$Q>i*pfB zP2drbID<_#qf;rPZx^FqH)F_D#*k@@q03KywUtLX8Ua?`H+NMzkczFPK3lFz@i_kW%1NOn0|D2I9n9wzH8m|-tHjsw|9>@K=iMBhxvkv6m8Y-l zytQ?X=U+MF$@3 zt`~i=@j|6y)RWMK--}M|=T`o&^Ni>IoWKHEbBXz7?A@mgWoL>!*SXo`SZH-*HSdS+ yn*9;$7;m`l>wYBC5bq;=U}IMqLzqbYCidGC!)_gkIk_C@Uy!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100755 index d5f1c8d34e7a88e3f88bea192c3a370d44689c3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100755 index 4d6372eebdb28e45604e46eeda8dd24651419bc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/res/values/strings.xml b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/res/values/strings.xml deleted file mode 100644 index c7e28ffcedd1..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - YOUR_WEB_CLIENT_ID - diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/build.gradle b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/build.gradle deleted file mode 100755 index 541636cc492a..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/build.gradle +++ /dev/null @@ -1,29 +0,0 @@ -buildscript { - repositories { - google() - jcenter() - } - - dependencies { - classpath 'com.android.tools.build:gradle:3.3.0' - } -} - -allprojects { - repositories { - google() - jcenter() - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/gradle.properties b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/gradle.properties deleted file mode 100755 index 38c8d4544ff1..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -org.gradle.jvmargs=-Xmx1536M -android.enableR8=true -android.useAndroidX=true -android.enableJetifier=true diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 019065d1d650..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/settings.gradle b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/settings.gradle deleted file mode 100755 index 115da6cb4f4d..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/android/settings.gradle +++ /dev/null @@ -1,15 +0,0 @@ -include ':app' - -def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() - -def plugins = new Properties() -def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') -if (pluginsFile.exists()) { - pluginsFile.withInputStream { stream -> plugins.load(stream) } -} - -plugins.each { name, path -> - def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() - include ":$name" - project(":$name").projectDir = pluginDirectory -} diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Flutter/AppFrameworkInfo.plist b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100755 index 6c2de8086bcd..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - UIRequiredDeviceCapabilities - - arm64 - - MinimumOSVersion - 8.0 - - diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Flutter/Debug.xcconfig b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Flutter/Debug.xcconfig deleted file mode 100755 index 9803018ca79d..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Generated.xcconfig" -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Flutter/Release.xcconfig b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Flutter/Release.xcconfig deleted file mode 100755 index a4a8c604e13d..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Generated.xcconfig" -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/GoogleSignInPluginTest/Info.plist b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/GoogleSignInPluginTest/Info.plist deleted file mode 100644 index 64d65ca49577..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/GoogleSignInPluginTest/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner.xcodeproj/project.pbxproj b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index faaaa58070bd..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,502 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 5C6F5A6E1EC3B4CB008D64B5 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C6F5A6D1EC3B4CB008D64B5 /* GeneratedPluginRegistrant.m */; }; - 7A303C2E1E89D76400B1F19E /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7A303C2D1E89D76400B1F19E /* GoogleService-Info.plist */; }; - 7ACDFB0E1E8944C400BE2D00 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7ACDFB0D1E8944C400BE2D00 /* AppFrameworkInfo.plist */; }; - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; - 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - C2FB9CBA01DB0A2DE5F31E12 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0263E28FA425D1CE928BDE15 /* libPods-Runner.a */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 0263E28FA425D1CE928BDE15 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 5A76713E622F06379AEDEBFA /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 5C6F5A6C1EC3B4CB008D64B5 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - 5C6F5A6D1EC3B4CB008D64B5 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 7A303C2D1E89D76400B1F19E /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; - 7ACDFB0D1E8944C400BE2D00 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - F582639B44581540871D9BB0 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - C2FB9CBA01DB0A2DE5F31E12 /* libPods-Runner.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 840012C8B5EDBCF56B0E4AC1 /* Pods */ = { - isa = PBXGroup; - children = ( - 5A76713E622F06379AEDEBFA /* Pods-Runner.debug.xcconfig */, - F582639B44581540871D9BB0 /* Pods-Runner.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 7ACDFB0D1E8944C400BE2D00 /* AppFrameworkInfo.plist */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - 840012C8B5EDBCF56B0E4AC1 /* Pods */, - CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 5C6F5A6C1EC3B4CB008D64B5 /* GeneratedPluginRegistrant.h */, - 5C6F5A6D1EC3B4CB008D64B5 /* GeneratedPluginRegistrant.m */, - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 7A303C2D1E89D76400B1F19E /* GoogleService-Info.plist */, - 97C147021CF9000F007C117D /* Info.plist */, - 97C146F11CF9000F007C117D /* Supporting Files */, - ); - path = Runner; - sourceTree = ""; - }; - 97C146F11CF9000F007C117D /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 97C146F21CF9000F007C117D /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - CF3B75C9A7D2FA2A4C99F110 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 0263E28FA425D1CE928BDE15 /* libPods-Runner.a */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - AB1344B0443C71CD721E1BB7 /* [CP] Check Pods Manifest.lock */, - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 95BB15E9E1769C0D146AA592 /* [CP] Embed Pods Frameworks */, - 532EA9D341340B1DCD08293D /* [CP] Copy Pods Resources */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; - TargetAttributes = { - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 7A303C2E1E89D76400B1F19E /* GoogleService-Info.plist in Resources */, - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 7ACDFB0E1E8944C400BE2D00 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin\n"; - }; - 532EA9D341340B1DCD08293D /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh", - "${PODS_ROOT}/GoogleSignIn/Resources/GoogleSignIn.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleSignIn.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 95BB15E9E1769C0D146AA592 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", - "${PODS_ROOT}/../Flutter/Flutter.framework", - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; - AB1344B0443C71CD721E1BB7 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, - 97C146F31CF9000F007C117D /* main.m in Sources */, - 5C6F5A6E1EC3B4CB008D64B5 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.googleSignInExample; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.googleSignInExample; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100755 index 21a3cc14c74e..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100755 index 3bb3697ef41c..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100755 index 21a3cc14c74e..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/AppDelegate.h b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/AppDelegate.h deleted file mode 100644 index d9e18e990f2e..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/AppDelegate.h +++ /dev/null @@ -1,10 +0,0 @@ -// 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. - -#import -#import - -@interface AppDelegate : FlutterAppDelegate - -@end diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/AppDelegate.m b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/AppDelegate.m deleted file mode 100644 index f08675707182..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/AppDelegate.m +++ /dev/null @@ -1,17 +0,0 @@ -// 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. - -#include "AppDelegate.h" -#include "GeneratedPluginRegistrant.h" - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application - didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [GeneratedPluginRegistrant registerWithRegistry:self]; - // Override point for customization after application launch. - return [super application:application didFinishLaunchingWithOptions:launchOptions]; -} - -@end diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100755 index d22f10b2ab63..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100755 index 28c6bf03016f6c994b70f38d1b7346e5831b531f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 564 zcmV-40?Yl0P)Px$?ny*JR5%f>l)FnDQ543{x%ZCiu33$Wg!pQFfT_}?5Q|_VSlIbLC`dpoMXL}9 zHfd9&47Mo(7D231gb+kjFxZHS4-m~7WurTH&doVX2KI5sU4v(sJ1@T9eCIKPjsqSr z)C01LsCxk=72-vXmX}CQD#BD;Cthymh&~=f$Q8nn0J<}ZrusBy4PvRNE}+1ceuj8u z0mW5k8fmgeLnTbWHGwfKA3@PdZxhn|PypR&^p?weGftrtCbjF#+zk_5BJh7;0`#Wr zgDpM_;Ax{jO##IrT`Oz;MvfwGfV$zD#c2xckpcXC6oou4ML~ezCc2EtnsQTB4tWNg z?4bkf;hG7IMfhgNI(FV5Gs4|*GyMTIY0$B=_*mso9Ityq$m^S>15>-?0(zQ<8Qy<_TjHE33(?_M8oaM zyc;NxzRVK@DL6RJnX%U^xW0Gpg(lXp(!uK1v0YgHjs^ZXSQ|m#lV7ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100755 index f091b6b0bca859a3f474b03065bef75ba58a9e4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100755 index d0ef06e7edb86cdfe0d15b4b0d98334a86163658..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1716 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 diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100755 index c8f9ed8f5cee1c98386d13b17e89f719e83555b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100755 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100755 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100755 index 75b2d164a5a98e212cca15ea7bf2ab5de5108680..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3831 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 diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100755 index c4df70d39da7941ef3f6dcb7f06a192d8dcb308d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 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 iW8 - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Base.lproj/Main.storyboard b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100755 index f3c28516fb38..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/GoogleService-Info.plist b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/GoogleService-Info.plist deleted file mode 100644 index 6042aab908af..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/GoogleService-Info.plist +++ /dev/null @@ -1,44 +0,0 @@ - - - - - AD_UNIT_ID_FOR_BANNER_TEST - ca-app-pub-3940256099942544/2934735716 - AD_UNIT_ID_FOR_INTERSTITIAL_TEST - ca-app-pub-3940256099942544/4411468910 - CLIENT_ID - 479882132969-9i9aqik3jfjd7qhci1nqf0bm2g71rm1u.apps.googleusercontent.com - REVERSED_CLIENT_ID - com.googleusercontent.apps.479882132969-9i9aqik3jfjd7qhci1nqf0bm2g71rm1u - ANDROID_CLIENT_ID - 479882132969-jie8r1me6dsra60pal6ejaj8dgme3tg0.apps.googleusercontent.com - API_KEY - AIzaSyBECOwLTAN6PU4Aet1b2QLGIb3kRK8Xjew - GCM_SENDER_ID - 479882132969 - PLIST_VERSION - 1 - BUNDLE_ID - io.flutter.plugins.googleSignInExample - PROJECT_ID - my-flutter-proj - STORAGE_BUCKET - my-flutter-proj.appspot.com - IS_ADS_ENABLED - - IS_ANALYTICS_ENABLED - - IS_APPINVITE_ENABLED - - IS_GCM_ENABLED - - IS_SIGNIN_ENABLED - - GOOGLE_APP_ID - 1:479882132969:ios:2643f950e0a0da08 - DATABASE_URL - https://my-flutter-proj.firebaseio.com - SERVER_CLIENT_ID - YOUR_SERVER_CLIENT_ID - - \ No newline at end of file diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Info.plist b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Info.plist deleted file mode 100755 index e03ccfe55e37..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/Info.plist +++ /dev/null @@ -1,62 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - Google Sign-In Example - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - GoogleSignInExample - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleURLTypes - - - CFBundleTypeRole - Editor - CFBundleURLSchemes - - com.googleusercontent.apps.479882132969-9i9aqik3jfjd7qhci1nqf0bm2g71rm1u - - - - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - arm64 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - - diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/main.m b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/main.m deleted file mode 100644 index bec320c0bee0..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/ios/Runner/main.m +++ /dev/null @@ -1,13 +0,0 @@ -// 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. - -#import -#import -#import "AppDelegate.h" - -int main(int argc, char* argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/lib/main.dart b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/lib/main.dart deleted file mode 100755 index 0ec62a832648..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/lib/main.dart +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2019 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. - -// ignore_for_file: public_member_api_docs - -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:google_sign_in/google_sign_in.dart'; - -import 'package:extension_google_sign_in_as_googleapis_auth/extension_google_sign_in_as_googleapis_auth.dart'; -import 'package:googleapis/people/v1.dart'; - -GoogleSignIn _googleSignIn = GoogleSignIn( - scopes: [ - 'email', - 'https://www.googleapis.com/auth/contacts.readonly', - ], -); - -void main() { - runApp( - MaterialApp( - title: 'Google Sign In', - home: SignInDemo(), - ), - ); -} - -class SignInDemo extends StatefulWidget { - @override - State createState() => SignInDemoState(); -} - -class SignInDemoState extends State { - GoogleSignInAccount _currentUser; - String _contactText; - - @override - void initState() { - super.initState(); - _googleSignIn.onCurrentUserChanged.listen((GoogleSignInAccount account) { - setState(() { - _currentUser = account; - }); - if (_currentUser != null) { - _handleGetContact(); - } - }); - _googleSignIn.signInSilently(); - } - - Future _handleGetContact() async { - setState(() { - _contactText = 'Loading contact info...'; - }); - - final peopleApi = - PeopleServiceApi(await _googleSignIn.authenticatedClient()); - final response = await peopleApi.people.connections.list( - 'people/me', - personFields: 'names', - ); - - final firstNamedContactName = _pickFirstNamedContact(response.connections); - - setState(() { - if (firstNamedContactName != null) { - _contactText = 'I see you know $firstNamedContactName!'; - } else { - _contactText = 'No contacts to display.'; - } - }); - } - - String _pickFirstNamedContact(List connections) { - return connections - ?.firstWhere( - (person) => person.names != null, - orElse: () => null, - ) - ?.names - ?.firstWhere( - (name) => name.displayName != null, - orElse: () => null, - ) - ?.displayName; - } - - Future _handleSignIn() async { - try { - await _googleSignIn.signIn(); - } catch (error) { - print(error); - } - } - - Future _handleSignOut() => _googleSignIn.disconnect(); - - Widget _buildBody() { - if (_currentUser != null) { - return Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - ListTile( - leading: GoogleUserCircleAvatar( - identity: _currentUser, - ), - title: Text(_currentUser.displayName ?? ''), - subtitle: Text(_currentUser.email ?? ''), - ), - const Text('Signed in successfully.'), - Text(_contactText ?? ''), - ElevatedButton( - child: const Text('SIGN OUT'), - onPressed: _handleSignOut, - ), - ElevatedButton( - child: const Text('REFRESH'), - onPressed: _handleGetContact, - ), - ], - ); - } else { - return Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - const Text('You are not currently signed in.'), - ElevatedButton( - child: const Text('SIGN IN'), - onPressed: _handleSignIn, - ), - ], - ); - } - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Google Sign In'), - ), - body: ConstrainedBox( - constraints: const BoxConstraints.expand(), - child: _buildBody(), - )); - } -} diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml deleted file mode 100755 index c96ca065f081..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/pubspec.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: extension_google_sign_in_example -description: Example of Google Sign-In plugin and googleapis. - -dependencies: - flutter: - sdk: flutter - google_sign_in: ^5.0.0 - extension_google_sign_in_as_googleapis_auth: - # When depending on this package from a real application you should use: - # extension_google_sign_in_as_googleapis_auth: ^x.y.z - # See https://dart.dev/tools/pub/dependencies#version-constraints - # The example app is bundled with the plugin so we use a path dependency on - # the parent directory to use the current plugin's version. - path: ../ - googleapis: ^1.0.0 - -dev_dependencies: - pedantic: ^1.10.0 - -flutter: - uses-material-design: true - -environment: - sdk: ">=2.0.0-dev.28.0 <3.0.0" - flutter: ">=1.12.13+hotfix.4" diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/web/index.html b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/web/index.html deleted file mode 100644 index 42a7d93582ba..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/example/web/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - Google Sign-in Example - - - - - diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/lib/extension_google_sign_in_as_googleapis_auth.dart b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/lib/extension_google_sign_in_as_googleapis_auth.dart deleted file mode 100644 index b88be661fde4..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/lib/extension_google_sign_in_as_googleapis_auth.dart +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2020 The Flutter Authors -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file or at -// https://developers.google.com/open-source/licenses/bsd - -import 'package:meta/meta.dart'; -import 'package:google_sign_in/google_sign_in.dart'; -import 'package:googleapis_auth/googleapis_auth.dart' as googleapis_auth; -import 'package:http/http.dart' as http; - -/// Extension on [GoogleSignIn] that adds an `authenticatedClient` method. -/// -/// This method can be used to retrieve an authenticated [googleapis_auth.AuthClient] -/// client that can be used with the rest of the `googleapis` libraries. -extension GoogleApisGoogleSignInAuth on GoogleSignIn { - /// Retrieve a `googleapis` authenticated client. - Future authenticatedClient({ - @visibleForTesting GoogleSignInAuthentication? debugAuthentication, - @visibleForTesting List? debugScopes, - }) async { - final GoogleSignInAuthentication? auth = - debugAuthentication ?? await currentUser?.authentication; - final String? oathTokenString = auth?.accessToken; - if (oathTokenString == null) { - return null; - } - final credentials = googleapis_auth.AccessCredentials( - googleapis_auth.AccessToken( - 'Bearer', - oathTokenString, - // We don't know when the token expires, so we assume "never" - DateTime.now().toUtc().add(Duration(days: 365)), - ), - null, // We don't have a refreshToken - debugScopes ?? this.scopes, - ); - - return googleapis_auth.authenticatedClient(http.Client(), credentials); - } -} diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/pubspec.yaml b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/pubspec.yaml deleted file mode 100644 index 7d86b67196d0..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/pubspec.yaml +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2020 The Flutter Authors -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd - -name: extension_google_sign_in_as_googleapis_auth -description: A bridge package between google_sign_in and googleapis_auth, to create Authenticated Clients from google_sign_in user credentials. -version: 2.0.0 -homepage: https://github.com/flutter/plugins/google_sign_in/extension_google_sign_in_as_googleapis_auth - -dependencies: - flutter: - sdk: flutter - google_sign_in: ^5.0.0 - googleapis_auth: ^1.0.0 - meta: ^1.3.0 - http: ^0.13.0 - -dev_dependencies: - pedantic: ^1.10.0 - test: ^1.16.3 - flutter_test: - sdk: flutter - -environment: - sdk: ">=2.12.0-259.9.beta <3.0.0" - flutter: ">=1.12.13+hotfix.4" diff --git a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/test/extension_google_sign_in_as_googleapis_auth_test.dart b/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/test/extension_google_sign_in_as_googleapis_auth_test.dart deleted file mode 100644 index d747b3d19c63..000000000000 --- a/packages/google_sign_in/extension_google_sign_in_as_googleapis_auth/test/extension_google_sign_in_as_googleapis_auth_test.dart +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2020 The Flutter Authors -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file or at -// https://developers.google.com/open-source/licenses/bsd - -import 'package:google_sign_in/google_sign_in.dart'; -import 'package:googleapis_auth/googleapis_auth.dart' as auth; -import 'package:extension_google_sign_in_as_googleapis_auth/extension_google_sign_in_as_googleapis_auth.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:test/fake.dart'; - -const SOME_FAKE_ACCESS_TOKEN = 'this-is-something-not-null'; -const DEBUG_FAKE_SCOPES = ['some-scope', 'another-scope']; -const SIGN_IN_FAKE_SCOPES = ['some-scope', 'another-scope']; - -class FakeGoogleSignIn extends Fake implements GoogleSignIn { - final List scopes = SIGN_IN_FAKE_SCOPES; -} - -class FakeGoogleSignInAuthentication extends Fake - implements GoogleSignInAuthentication { - final String accessToken = SOME_FAKE_ACCESS_TOKEN; -} - -void main() { - GoogleSignIn signIn = FakeGoogleSignIn(); - final authMock = FakeGoogleSignInAuthentication(); - - test('authenticatedClient returns an authenticated client', () async { - final client = await signIn.authenticatedClient( - debugAuthentication: authMock, - ); - expect(client, isA()); - }); - - test('authenticatedClient uses GoogleSignIn scopes by default', () async { - final client = (await signIn.authenticatedClient( - debugAuthentication: authMock, - ))!; - expect(client.credentials.accessToken.data, equals(SOME_FAKE_ACCESS_TOKEN)); - expect(client.credentials.scopes, equals(SIGN_IN_FAKE_SCOPES)); - }); - - test('authenticatedClient returned client contains the passed-in credentials', - () async { - final client = (await signIn.authenticatedClient( - debugAuthentication: authMock, - debugScopes: DEBUG_FAKE_SCOPES, - ))!; - expect(client.credentials.accessToken.data, equals(SOME_FAKE_ACCESS_TOKEN)); - expect(client.credentials.scopes, equals(DEBUG_FAKE_SCOPES)); - }); -} diff --git a/script/build_all_plugins_app.sh b/script/build_all_plugins_app.sh index f6b1c166069f..27726bd53426 100755 --- a/script/build_all_plugins_app.sh +++ b/script/build_all_plugins_app.sh @@ -26,8 +26,6 @@ check_changed_packages > /dev/null # cases where using a relaxed version constraint isn't possible. readonly EXCLUDED_PLUGINS_LIST=( "plugin_platform_interface" # This should never be a direct app dependency. - "extension_google_sign_in_as_googleapis_auth" # Transitive dependency issues - # with integration_test. ) # Comma-separated string of the list above readonly EXCLUDED=$(IFS=, ; echo "${EXCLUDED_PLUGINS_LIST[*]}") From 4dea720e3aa4c9a444f457a3fed17fee410b7e8b Mon Sep 17 00:00:00 2001 From: Konstantin Touev Date: Wed, 10 Mar 2021 19:10:09 +0200 Subject: [PATCH 0261/1565] [shared_preferences] Fix concurrent modification of the shared preferences on Android (#3684) Uses an actual queue, rather than a one-element handoff "queue", for the single-thread background processing of commits. --- .../shared_preferences/CHANGELOG.md | 4 ++++ .../sharedpreferences/MethodCallHandlerImpl.java | 4 ++-- .../integration_test/shared_preferences_test.dart | 13 +++++++++++++ .../shared_preferences/pubspec.yaml | 2 +- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/shared_preferences/shared_preferences/CHANGELOG.md b/packages/shared_preferences/shared_preferences/CHANGELOG.md index 1516163b8807..b0899d57a3c5 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.4 + +* Fix a regression with simultaneous writes on Android. + ## 2.0.3 * Android: don't create additional Handler when method channel is called. diff --git a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java index 4f55d882005f..4486421e3959 100644 --- a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java +++ b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java @@ -23,7 +23,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; -import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -53,7 +53,7 @@ class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { MethodCallHandlerImpl(Context context) { preferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); executor = - new ThreadPoolExecutor(0, 1, 30L, TimeUnit.SECONDS, new SynchronousQueue()); + new ThreadPoolExecutor(0, 1, 30L, TimeUnit.SECONDS, new LinkedBlockingQueue()); handler = new Handler(Looper.getMainLooper()); } diff --git a/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart index 1caf695d9365..d36286a559b3 100644 --- a/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart @@ -91,5 +91,18 @@ void main() { expect(preferences.getDouble('double'), null); expect(preferences.getStringList('List'), null); }); + + testWidgets('simultaneous writes', (WidgetTester _) async { + final List> writes = >[]; + final int writeCount = 100; + for (int i = 1; i <= writeCount; i++) { + writes.add(preferences.setInt('int', i)); + } + List result = await Future.wait(writes, eagerError: true); + // All writes should succeed. + expect(result.where((element) => !element), isEmpty); + // The last write should win. + expect(preferences.getInt('int'), writeCount); + }); }); } diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index 899266a4d6f0..b53bbfd93a38 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -2,7 +2,7 @@ name: shared_preferences description: Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences -version: 2.0.3 +version: 2.0.4 flutter: plugin: From 735e1a5208e1f8048fb7544dc288730533eae9bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl?= <32639467+danielroek@users.noreply.github.com> Date: Wed, 10 Mar 2021 18:45:04 +0100 Subject: [PATCH 0262/1565] [image_picker] Implemented 2860 and added Unit Test to test functionality (#3685) --- packages/image_picker/image_picker/CHANGELOG.md | 4 ++++ .../io/flutter/plugins/imagepicker/FileUtils.java | 15 +++++++++++---- .../flutter/plugins/imagepicker/FileUtilTest.java | 9 +++++++++ packages/image_picker/image_picker/pubspec.yaml | 2 +- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md index 7be13a574a77..4f2a054f1520 100644 --- a/packages/image_picker/image_picker/CHANGELOG.md +++ b/packages/image_picker/image_picker/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.2+1 + +* Android: fixes an issue where videos could be wrongly picked with `.jpg` extension. + ## 0.7.2 * Run CocoaPods iOS tests in RunnerUITests target diff --git a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/FileUtils.java b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/FileUtils.java index 9ebf1fad826b..19e304ea9eee 100644 --- a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/FileUtils.java +++ b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/FileUtils.java @@ -23,8 +23,10 @@ package io.flutter.plugins.imagepicker; +import android.content.ContentResolver; import android.content.Context; import android.net.Uri; +import android.webkit.MimeTypeMap; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -39,7 +41,7 @@ String getPathFromUri(final Context context, final Uri uri) { OutputStream outputStream = null; boolean success = false; try { - String extension = getImageExtension(uri); + String extension = getImageExtension(context, uri); inputStream = context.getContentResolver().openInputStream(uri); file = File.createTempFile("image_picker", extension, context.getCacheDir()); file.deleteOnExit(); @@ -67,13 +69,18 @@ String getPathFromUri(final Context context, final Uri uri) { } /** @return extension of image with dot, or default .jpg if it none. */ - private static String getImageExtension(Uri uriImage) { + private static String getImageExtension(Context context, Uri uriImage) { String extension = null; try { String imagePath = uriImage.getPath(); - if (imagePath != null && imagePath.lastIndexOf(".") != -1) { - extension = imagePath.substring(imagePath.lastIndexOf(".") + 1); + if (uriImage.getScheme().equals(ContentResolver.SCHEME_CONTENT)) { + final MimeTypeMap mime = MimeTypeMap.getSingleton(); + extension = mime.getExtensionFromMimeType(context.getContentResolver().getType(uriImage)); + } else { + extension = + MimeTypeMap.getFileExtensionFromUrl( + Uri.fromFile(new File(uriImage.getPath())).toString()); } } catch (Exception e) { extension = null; diff --git a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/FileUtilTest.java b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/FileUtilTest.java index c9fa3381ebe5..bd705d2374e5 100644 --- a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/FileUtilTest.java +++ b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/FileUtilTest.java @@ -54,4 +54,13 @@ public void FileUtil_GetPathFromUri() throws IOException { String imageStream = new String(bytes, UTF_8); assertTrue(imageStream.equals("imageStream")); } + + @Test + public void FileUtil_getImageExtension() throws IOException { + Uri uri = Uri.parse("content://dummy/dummy.png"); + shadowContentResolver.registerInputStream( + uri, new ByteArrayInputStream("imageStream".getBytes(UTF_8))); + String path = fileUtils.getPathFromUri(context, uri); + assertTrue(path.endsWith(".jpg")); + } } diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index 562528466861..9ea8e5ddcbd4 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker description: Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker -version: 0.7.2 +version: 0.7.2+1 flutter: plugin: From d306f98fc13298bf2e0844a221bf699226700bd7 Mon Sep 17 00:00:00 2001 From: nt4f04uNd Date: Wed, 10 Mar 2021 22:45:02 +0300 Subject: [PATCH 0263/1565] [video_player] fixed misleading size and aspect ratio documentation (#3668) --- .../video_player/video_player/CHANGELOG.md | 4 ++++ .../lib/src/closed_caption_file.dart | 19 ++++++++++++------- .../video_player/lib/video_player.dart | 12 +++++++----- .../video_player/video_player/pubspec.yaml | 2 +- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index e5c30a0389e4..08a5e443149e 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.2 + +* Fix `VideoPlayerValue` size and aspect ratio documentation + ## 2.0.1 * Remove the deprecated API "exoPlayer.setAudioAttributes". diff --git a/packages/video_player/video_player/lib/src/closed_caption_file.dart b/packages/video_player/video_player/lib/src/closed_caption_file.dart index eae9bf5dfabf..64ab1f6ca651 100644 --- a/packages/video_player/video_player/lib/src/closed_caption_file.dart +++ b/packages/video_player/video_player/lib/src/closed_caption_file.dart @@ -31,11 +31,12 @@ class Caption { /// /// This is not recommended for direct use unless you are writing a parser for /// a new closed captioning file type. - const Caption( - {required this.number, - required this.start, - required this.end, - required this.text}); + const Caption({ + required this.number, + required this.start, + required this.end, + required this.text, + }); /// The number that this caption was assigned. final int number; @@ -52,8 +53,12 @@ class Caption { /// A no caption object. This is a caption with [start] and [end] durations of zero, /// and an empty [text] string. - static const Caption none = - Caption(number: 0, start: Duration.zero, end: Duration.zero, text: ''); + static const Caption none = Caption( + number: 0, + start: Duration.zero, + end: Duration.zero, + text: '', + ); @override String toString() { diff --git a/packages/video_player/video_player/lib/video_player.dart b/packages/video_player/video_player/lib/video_player.dart index 6a2af76fa547..96dd73d3adea 100644 --- a/packages/video_player/video_player/lib/video_player.dart +++ b/packages/video_player/video_player/lib/video_player.dart @@ -87,12 +87,10 @@ class VideoPlayerValue { /// A description of the error if present. /// - /// If [hasError] is false this is [null]. + /// If [hasError] is false this is `null`. final String? errorDescription; /// The [size] of the currently loaded video. - /// - /// Is null when [initialized] is false. final Size size; /// Indicates whether or not the video has been loaded and is ready to play. @@ -102,8 +100,12 @@ class VideoPlayerValue { /// [errorDescription] should have information about the problem. bool get hasError => errorDescription != null; - /// Returns [size.width] / [size.height] when size is non-null, or `1.0.` when - /// size is null or the aspect ratio would be less than or equal to 0.0. + /// Returns [size.width] / [size.height]. + /// + /// Will return `1.0` if: + /// * [isInitialized] is `false` + /// * [size.width], or [size.height] is equal to `0.0` + /// * aspect ratio would be less than or equal to `0.0` double get aspectRatio { if (!isInitialized || size.width == 0 || size.height == 0) { return 1.0; diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index 3c6a34c7f78c..17442d7ec09a 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -1,7 +1,7 @@ name: video_player description: Flutter plugin for displaying inline video with other Flutter widgets on Android, iOS, and web. -version: 2.0.1 +version: 2.0.2 homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player flutter: From 79dd06a1eb1d007844df812328a5414b0fe8db26 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Wed, 10 Mar 2021 12:51:12 -0800 Subject: [PATCH 0264/1565] Streamline CI setup, and reenable macOS credits (#3697) This makes a few improvements to CI throughput: - Moves the flutter channel+upgrade step into each step, rather then doing it for both channels in the setup step. This avoids pointlessly doing twice the work in every setup (downloading two channels, only one of which will be used) - Re-enables credits for macOS tasks. These were disabled in a recent chance since I was unifying configurations, but it turns out that without credits there is *no* parallelization of macOS tasks, which makes the end-to-end time very long. - Dials back the Linux VM requirements based on looking at the new CPU and memory usage graphs for runs: - No task was ever reaching 4 CPUs or 12 GB of memory, so use those values for heavy workload; this will double concurrency of the heavy-workload tasks and should have no impact on run length. - Linux build+drive was extremely low usage, so move it to the light workload group. --- .cirrus.yml | 123 ++++++++++++++++++---------------------------------- 1 file changed, 42 insertions(+), 81 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index eac32d114269..8d992d5cbbd1 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,21 +1,24 @@ -# Light-workload tasks. -# These use default machines, with fewer CPUs, to reduce pressure on the -# concurrency limits. -task: - # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins +root_task_template: &ROOT_TASK_TEMPLATE + # Don't run on release tags since it creates O(n^2) tasks where n is the + # number of plugins only_if: $CIRRUS_TAG == '' use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_PR == '' - container: - dockerfile: .ci/Dockerfile env: INTEGRATION_TEST_PATH: "./packages/integration_test" - upgrade_script: - - flutter channel stable - - flutter upgrade - - flutter channel master + CHANNEL: "master" # Default to master when not explicitly set by a task. + setup_script: + - flutter channel $CHANNEL - flutter upgrade - - flutter config --enable-linux-desktop - - git fetch origin master + - git fetch origin master # To set FETCH_HEAD for "git merge-base" to work + + +# Light-workload Linux tasks. +# These use default machines, with fewer CPUs, to reduce pressure on the +# concurrency limits. +task: + << : *ROOT_TASK_TEMPLATE + container: + dockerfile: .ci/Dockerfile matrix: ### Platform-agnostic tasks ### - name: plugin_tools_tests @@ -25,7 +28,6 @@ task: - CIRRUS_BUILD_ID=null pub run test - name: publishable script: - - flutter channel master - ./script/check_publish.sh - name: format format_script: ./script/incremental_build.sh format --fail-on-change @@ -35,14 +37,12 @@ task: CHANNEL: "master" CHANNEL: "stable" test_script: - - flutter channel $CHANNEL - ./script/incremental_build.sh test - name: analyze_master env: matrix: CHANNEL: "master" script: - - flutter channel $CHANNEL - ./script/incremental_build.sh analyze ## TODO(cyanglaz): ## Combing stable and master analyze jobs when integration test null safety is ready on flutter stable. @@ -51,7 +51,6 @@ task: matrix: CHANNEL: "stable" script: - - flutter channel $CHANNEL - find . -depth -type d -wholename '*_web/example' -exec rm -rf {} \; - ./script/incremental_build.sh analyze ### Android tasks ### @@ -61,7 +60,6 @@ task: CHANNEL: "master" CHANNEL: "stable" script: - - flutter channel $CHANNEL - ./script/build_all_plugins_app.sh apk ### Web tasks ### - name: build_all_plugins_web @@ -70,14 +68,12 @@ task: CHANNEL: "master" CHANNEL: "stable" script: - - flutter channel $CHANNEL - ./script/build_all_plugins_app.sh web - name: build-web-examples env: matrix: CHANNEL: "master" build_script: - - flutter channel $CHANNEL - ./script/incremental_build.sh build-examples --web # TODO: Add driving examples (and move to heavy-workload group). ### Linux desktop tasks ### @@ -87,8 +83,17 @@ task: CHANNEL: "master" CHANNEL: "stable" script: - - flutter channel $CHANNEL + - flutter config --enable-linux-desktop - ./script/build_all_plugins_app.sh linux + - name: build-linux+drive-examples + env: + matrix: + CHANNEL: "master" + CHANNEL: "stable" + build_script: + - flutter config --enable-linux-desktop + - ./script/incremental_build.sh build-examples --linux + - xvfb-run ./script/incremental_build.sh drive-examples --linux # Legacy Dockerfile configuration for web integration tests. # https://github.com/flutter/web_installers doesn't yet support the current @@ -97,20 +102,9 @@ task: # tasks" block above once web_installers has been updated to support Chrome 89 # (which is what the current image generated from .ci/Dockerfile has). task: - # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins - only_if: $CIRRUS_TAG == '' - use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_PR == '' + << : *ROOT_TASK_TEMPLATE container: dockerfile: .ci/Dockerfile-LegacyChrome - env: - INTEGRATION_TEST_PATH: "./packages/integration_test" - upgrade_script: - - flutter channel stable - - flutter upgrade - - flutter channel master - - flutter upgrade - - flutter config --enable-linux-desktop - - git fetch origin master matrix: - name: integration_web_smoke_test env: @@ -120,7 +114,6 @@ task: # Tests integration example test in web. only_if: "changesInclude('.cirrus.yml', 'packages/integration_test/**') || $CIRRUS_PR == ''" install_script: - - flutter channel $CHANNEL - git clone https://github.com/flutter/web_installers.git - cd web_installers/packages/web_drivers/ - pub get @@ -130,26 +123,15 @@ task: - cd $INTEGRATION_TEST_PATH/example/ - flutter drive -v --driver=test_driver/integration_test.dart --target=integration_test/example_test.dart -d web-server --release --browser-name=chrome -# Heavy-workload tasks. +# Heavy-workload Linux tasks. # These use machines with more CPUs and memory, so will reduce parallelization # for non-credit runs. task: - # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins - only_if: $CIRRUS_TAG == '' - use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_PR == '' + << : *ROOT_TASK_TEMPLATE container: dockerfile: .ci/Dockerfile - cpu: 8 - memory: 16G - env: - INTEGRATION_TEST_PATH: "./packages/integration_test" - upgrade_script: - - flutter channel stable - - flutter upgrade - - flutter channel master - - flutter upgrade - - flutter config --enable-linux-desktop - - git fetch origin master + cpu: 4 + memory: 12G matrix: ### Android tasks ### - name: build-apks+java-test+firebase-test-lab @@ -165,7 +147,6 @@ task: MAPS_API_KEY: ENCRYPTED[596a9f6bca436694625ac50851dc5da6b4d34cba8025f7db5bc9465142e8cd44e15f69e3507787753accebfc4910d550] GCLOUD_FIREBASE_TESTLAB_KEY: ENCRYPTED[07586610af1fdfc894e5969f70ef2458341b9b7e9c3b7c4225a663b4a48732b7208a4d91c3b7d45305a6b55fa2a37fc4] script: - - flutter channel $CHANNEL # Unsetting CIRRUS_CHANGE_MESSAGE and CIRRUS_COMMIT_MESSAGE as they # might include non-ASCII characters which makes Gradle crash. # See: https://github.com/flutter/flutter/issues/24935 @@ -186,35 +167,16 @@ task: - fi - export CIRRUS_CHANGE_MESSAGE=`cat /tmp/cirrus_change_message.txt` - export CIRRUS_COMMIT_MESSAGE=`cat /tmp/cirrus_commit_message.txt` - ### Linux desktop tasks ### - - name: build-linux+drive-examples - env: - matrix: - CHANNEL: "master" - CHANNEL: "stable" - build_script: - - flutter channel $CHANNEL - - ./script/incremental_build.sh build-examples --linux - - xvfb-run ./script/incremental_build.sh drive-examples --linux +# macOS tasks. task: - # Xcode 12 task - # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins - only_if: $CIRRUS_TAG == '' - use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_PR == '' + << : *ROOT_TASK_TEMPLATE + # Only one macOS task can run in parallel without credits, so use them for + # PRs on macOS. + use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' osx_instance: image: big-sur-xcode-12.3 - upgrade_script: - - sudo gem install cocoapods - - flutter channel stable - - flutter upgrade - - flutter channel master - - flutter upgrade - - flutter config --enable-macos-desktop - - git fetch origin master - create_simulator_script: - - xcrun simctl list - - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-11 com.apple.CoreSimulator.SimRuntime.iOS-14-3 | xargs xcrun simctl boot + cocoapod_install_script: sudo gem install cocoapods matrix: ### Platform-agnostic tasks ### - name: lint_darwin_plugins @@ -225,8 +187,6 @@ task: script: # TODO(jmagman): Lint macOS podspecs but skip any that fail library validation. - find . -name "*.podspec" | xargs grep -l "osx" | xargs rm - # Skip the dummy podspecs used to placate the tool. - - find . -name "*_web*.podspec" -o -name "*_mac*.podspec" | xargs rm - ./script/incremental_build.sh podspecs ### iOS tasks ### - name: build_all_plugins_ipa @@ -235,7 +195,6 @@ task: CHANNEL: "master" CHANNEL: "stable" script: - - flutter channel $CHANNEL - ./script/build_all_plugins_app.sh ios --no-codesign - name: build-ipas+drive-examples env: @@ -250,8 +209,10 @@ task: CHANNEL: "master" CHANNEL: "stable" SIMCTL_CHILD_MAPS_API_KEY: ENCRYPTED[596a9f6bca436694625ac50851dc5da6b4d34cba8025f7db5bc9465142e8cd44e15f69e3507787753accebfc4910d550] + create_simulator_script: + - xcrun simctl list + - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-11 com.apple.CoreSimulator.SimRuntime.iOS-14-3 | xargs xcrun simctl boot build_script: - - flutter channel $CHANNEL - ./script/incremental_build.sh build-examples --ipa - ./script/incremental_build.sh xctest --skip $PLUGINS_TO_SKIP_XCTESTS --ios-destination "platform=iOS Simulator,name=iPhone 11,OS=latest" # `drive-examples` contains integration tests, which changes the UI of the application. @@ -265,7 +226,7 @@ task: CHANNEL: "master" CHANNEL: "stable" script: - - flutter channel $CHANNEL + - flutter config --enable-macos-desktop - ./script/build_all_plugins_app.sh macos - name: build-macos+drive-examples env: @@ -274,6 +235,6 @@ task: CHANNEL: "stable" PATH: $PATH:/usr/local/bin build_script: - - flutter channel $CHANNEL + - flutter config --enable-macos-desktop - ./script/incremental_build.sh build-examples --macos --no-ipa - ./script/incremental_build.sh drive-examples --macos From 8feb2e78070fffbf53b752e1a548ff3a9e295b8a Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Wed, 10 Mar 2021 14:15:04 -0800 Subject: [PATCH 0265/1565] [tool] Improve check version ci so that it enforces the version in CHANGELOG and pubspec matches. (#3678) --- .cirrus.yml | 9 +- script/incremental_build.sh | 3 - script/tool/lib/src/common.dart | 143 ++++++++++- .../tool/lib/src/version_check_command.dart | 139 ++++++----- script/tool/test/common_test.dart | 227 +++++++++++++++++- script/tool/test/util.dart | 19 +- script/tool/test/version_check_test.dart | 160 +++++++++++- 7 files changed, 619 insertions(+), 81 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 8d992d5cbbd1..8f61fabc4f2a 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -6,10 +6,13 @@ root_task_template: &ROOT_TASK_TEMPLATE env: INTEGRATION_TEST_PATH: "./packages/integration_test" CHANNEL: "master" # Default to master when not explicitly set by a task. + PLUGIN_TOOLS: "dart run ./script/tool/lib/src/main.dart" setup_script: - flutter channel $CHANNEL - flutter upgrade - git fetch origin master # To set FETCH_HEAD for "git merge-base" to work + - cd script/tool + - pub get # Light-workload Linux tasks. @@ -24,10 +27,14 @@ task: - name: plugin_tools_tests script: - cd script/tool - - pub get - CIRRUS_BUILD_ID=null pub run test - name: publishable script: + - if [[ "$CIRRUS_BRANCH" == "master" ]]; then + - $PLUGIN_TOOLS version-check + - else + - $PLUGIN_TOOLS version-check --run-on-changed-packages + - fi - ./script/check_publish.sh - name: format format_script: ./script/incremental_build.sh format --fail-on-change diff --git a/script/incremental_build.sh b/script/incremental_build.sh index 826229bced60..38a4d2d8edc7 100755 --- a/script/incremental_build.sh +++ b/script/incremental_build.sh @@ -49,8 +49,5 @@ else else echo running "${ACTIONS[@]}" (cd "$REPO_DIR" && plugin_tools "${ACTIONS[@]}" --plugins="$CHANGED_PACKAGES" --exclude="$ALL_EXCLUDED" ${PLUGIN_SHARDING[@]}) - echo "Running version check for changed packages" - # TODO(egarciad): Enable this check once in master. - # (cd "$REPO_DIR" && $PUB global run flutter_plugin_tools version-check --base_sha="$(get_branch_base_sha)") fi fi diff --git a/script/tool/lib/src/common.dart b/script/tool/lib/src/common.dart index 08622df281b4..ce4f37873b07 100644 --- a/script/tool/lib/src/common.dart +++ b/script/tool/lib/src/common.dart @@ -7,8 +7,12 @@ import 'dart:io' as io; import 'dart:math'; import 'package:args/command_runner.dart'; +import 'package:colorize/colorize.dart'; import 'package:file/file.dart'; +import 'package:git/git.dart'; +import 'package:meta/meta.dart'; import 'package:path/path.dart' as p; +import 'package:pub_semver/pub_semver.dart'; import 'package:yaml/yaml.dart'; typedef void Print(Object object); @@ -140,6 +144,13 @@ bool isLinuxPlugin(FileSystemEntity entity, FileSystem fileSystem) { return pluginSupportsPlatform(kLinux, entity, fileSystem); } +/// Throws a [ToolExit] with `exitCode` and log the `errorMessage` in red. +void printErrorAndExit({@required String errorMessage, int exitCode = 1}) { + final Colorize redError = Colorize(errorMessage)..red(); + print(redError); + throw ToolExit(exitCode); +} + /// Error thrown when a command needs to exit with a non-zero exit code. class ToolExit extends Error { ToolExit(this.exitCode); @@ -152,6 +163,7 @@ abstract class PluginCommand extends Command { this.packagesDir, this.fileSystem, { this.processRunner = const ProcessRunner(), + this.gitDir, }) { argParser.addMultiOption( _pluginsArg, @@ -179,12 +191,23 @@ abstract class PluginCommand extends Command { help: 'Exclude packages from this command.', defaultsTo: [], ); + argParser.addFlag(_runOnChangedPackagesArg, + help: 'Run the command on changed packages/plugins.\n' + 'If the $_pluginsArg is specified, this flag is ignored.\n' + 'The packages excluded with $_excludeArg is also excluded even if changed.\n' + 'See $_kBaseSha if a custom base is needed to determine the diff.'); + argParser.addOption(_kBaseSha, + help: 'The base sha used to determine git diff. \n' + 'This is useful when $_runOnChangedPackagesArg is specified.\n' + 'If not specified, merge-base is used as base sha.'); } static const String _pluginsArg = 'plugins'; static const String _shardIndexArg = 'shardIndex'; static const String _shardCountArg = 'shardCount'; static const String _excludeArg = 'exclude'; + static const String _runOnChangedPackagesArg = 'run-on-changed-packages'; + static const String _kBaseSha = 'base-sha'; /// The directory containing the plugin packages. final Directory packagesDir; @@ -199,6 +222,11 @@ abstract class PluginCommand extends Command { /// This can be overridden for testing. final ProcessRunner processRunner; + /// The git directory to use. By default it uses the parent directory. + /// + /// This can be mocked for testing. + final GitDir gitDir; + int _shardIndex; int _shardCount; @@ -273,9 +301,13 @@ abstract class PluginCommand extends Command { /// "client library" package, which declares the API for the plugin, as /// well as one or more platform-specific implementations. Stream _getAllPlugins() async* { - final Set plugins = Set.from(argResults[_pluginsArg]); + Set plugins = Set.from(argResults[_pluginsArg]); final Set excludedPlugins = Set.from(argResults[_excludeArg]); + final bool runOnChangedPackages = argResults[_runOnChangedPackagesArg]; + if (plugins.isEmpty && runOnChangedPackages) { + plugins = await _getChangedPackages(); + } await for (FileSystemEntity entity in packagesDir.list(followLinks: false)) { @@ -363,6 +395,50 @@ abstract class PluginCommand extends Command { (FileSystemEntity entity) => isFlutterPackage(entity, fileSystem)) .cast(); } + + /// Retrieve an instance of [GitVersionFinder] based on `_kBaseSha` and [gitDir]. + /// + /// Throws tool exit if [gitDir] nor root directory is a git directory. + Future retrieveVersionFinder() async { + final String rootDir = packagesDir.parent.absolute.path; + String baseSha = argResults[_kBaseSha]; + + GitDir baseGitDir = gitDir; + if (baseGitDir == null) { + if (!await GitDir.isGitDir(rootDir)) { + printErrorAndExit( + errorMessage: '$rootDir is not a valid Git repository.', + exitCode: 2); + } + baseGitDir = await GitDir.fromExisting(rootDir); + } + + final GitVersionFinder gitVersionFinder = + GitVersionFinder(baseGitDir, baseSha); + return gitVersionFinder; + } + + Future> _getChangedPackages() async { + final GitVersionFinder gitVersionFinder = await retrieveVersionFinder(); + + final List allChangedFiles = + await gitVersionFinder.getChangedFiles(); + final Set packages = {}; + allChangedFiles.forEach((String path) { + final List pathComponents = path.split('/'); + final int packagesIndex = + pathComponents.indexWhere((String element) => element == 'packages'); + if (packagesIndex != -1) { + packages.add(pathComponents[packagesIndex + 1]); + } + }); + if (packages.isNotEmpty) { + final String changedPackages = packages.join(','); + print(changedPackages); + } + print('No changed packages.'); + return packages; + } } /// A class used to run processes. @@ -466,3 +542,68 @@ class ProcessRunner { return 'ERROR: Unable to execute "$executable ${args.join(' ')}"$workdir.'; } } + +/// Finding diffs based on `baseGitDir` and `baseSha`. +class GitVersionFinder { + /// Constructor + GitVersionFinder(this.baseGitDir, this.baseSha); + + /// The top level directory of the git repo. + /// + /// That is where the .git/ folder exists. + final GitDir baseGitDir; + + /// The base sha used to get diff. + final String baseSha; + + static bool _isPubspec(String file) { + return file.trim().endsWith('pubspec.yaml'); + } + + /// Get a list of all the pubspec.yaml file that is changed. + Future> getChangedPubSpecs() async { + return (await getChangedFiles()).where(_isPubspec).toList(); + } + + /// Get a list of all the changed files. + Future> getChangedFiles() async { + final String baseSha = await _getBaseSha(); + final io.ProcessResult changedFilesCommand = await baseGitDir + .runCommand(['diff', '--name-only', '$baseSha', 'HEAD']); + print('Determine diff with base sha: $baseSha'); + final String changedFilesStdout = changedFilesCommand.stdout.toString() ?? ''; + if (changedFilesStdout.isEmpty) { + return []; + } + final List changedFiles = changedFilesStdout + .split('\n') + ..removeWhere((element) => element.isEmpty); + return changedFiles.toList(); + } + + /// Get the package version specified in the pubspec file in `pubspecPath` and at the revision of `gitRef`. + Future getPackageVersion(String pubspecPath, String gitRef) async { + final io.ProcessResult gitShow = + await baseGitDir.runCommand(['show', '$gitRef:$pubspecPath']); + final String fileContent = gitShow.stdout; + final String versionString = loadYaml(fileContent)['version']; + return versionString == null ? null : Version.parse(versionString); + } + + Future _getBaseSha() async { + if (baseSha != null && baseSha.isNotEmpty) { + return baseSha; + } + + io.ProcessResult baseShaFromMergeBase = await baseGitDir.runCommand( + ['merge-base', '--fork-point', 'FETCH_HEAD', 'HEAD'], + throwOnError: false); + if (baseShaFromMergeBase == null || + baseShaFromMergeBase.stderr != null || + baseShaFromMergeBase.stdout == null) { + baseShaFromMergeBase = await baseGitDir + .runCommand(['merge-base', 'FETCH_HEAD', 'HEAD']); + } + return (baseShaFromMergeBase.stdout as String).trim(); + } +} diff --git a/script/tool/lib/src/version_check_command.dart b/script/tool/lib/src/version_check_command.dart index 2c6b92bbcb7a..111239f0399a 100644 --- a/script/tool/lib/src/version_check_command.dart +++ b/script/tool/lib/src/version_check_command.dart @@ -6,43 +6,14 @@ import 'dart:async'; import 'dart:io' as io; import 'package:meta/meta.dart'; -import 'package:colorize/colorize.dart'; import 'package:file/file.dart'; import 'package:git/git.dart'; import 'package:pub_semver/pub_semver.dart'; import 'package:pubspec_parse/pubspec_parse.dart'; -import 'package:yaml/yaml.dart'; import 'common.dart'; -const String _kBaseSha = 'base_sha'; - -class GitVersionFinder { - GitVersionFinder(this.baseGitDir, this.baseSha); - - final GitDir baseGitDir; - final String baseSha; - - static bool isPubspec(String file) { - return file.trim().endsWith('pubspec.yaml'); - } - - Future> getChangedPubSpecs() async { - final io.ProcessResult changedFilesCommand = await baseGitDir - .runCommand(['diff', '--name-only', '$baseSha', 'HEAD']); - final List changedFiles = - changedFilesCommand.stdout.toString().split('\n'); - return changedFiles.where(isPubspec).toList(); - } - - Future getPackageVersion(String pubspecPath, String gitRef) async { - final io.ProcessResult gitShow = - await baseGitDir.runCommand(['show', '$gitRef:$pubspecPath']); - final String fileContent = gitShow.stdout; - final String versionString = loadYaml(fileContent)['version']; - return versionString == null ? null : Version.parse(versionString); - } -} +const String _kBaseSha = 'base-sha'; enum NextVersionType { BREAKING_MAJOR, @@ -128,46 +99,28 @@ class VersionCheckCommand extends PluginCommand { Directory packagesDir, FileSystem fileSystem, { ProcessRunner processRunner = const ProcessRunner(), - this.gitDir, - }) : super(packagesDir, fileSystem, processRunner: processRunner) { - argParser.addOption(_kBaseSha); - } - - /// The git directory to use. By default it uses the parent directory. - /// - /// This can be mocked for testing. - final GitDir gitDir; + GitDir gitDir, + }) : super(packagesDir, fileSystem, + processRunner: processRunner, gitDir: gitDir); @override final String name = 'version-check'; @override final String description = - 'Checks if the versions of the plugins have been incremented per pub specification.\n\n' + 'Checks if the versions of the plugins have been incremented per pub specification.\n' + 'Also checks if the latest version in CHANGELOG matches the version in pubspec.\n\n' 'This command requires "pub" and "flutter" to be in your path.'; @override Future run() async { checkSharding(); - - final String rootDir = packagesDir.parent.absolute.path; - final String baseSha = argResults[_kBaseSha]; - - GitDir baseGitDir = gitDir; - if (baseGitDir == null) { - if (!await GitDir.isGitDir(rootDir)) { - print('$rootDir is not a valid Git repository.'); - throw ToolExit(2); - } - baseGitDir = await GitDir.fromExisting(rootDir); - } - - final GitVersionFinder gitVersionFinder = - GitVersionFinder(baseGitDir, baseSha); + final GitVersionFinder gitVersionFinder = await retrieveVersionFinder(); final List changedPubspecs = await gitVersionFinder.getChangedPubSpecs(); + final String baseSha = argResults[_kBaseSha]; for (final String pubspecPath in changedPubspecs) { try { final File pubspecFile = fileSystem.file(pubspecPath); @@ -194,9 +147,7 @@ class VersionCheckCommand extends PluginCommand { final String error = '$pubspecPath incorrectly updated version.\n' 'HEAD: $headVersion, master: $masterVersion.\n' 'Allowed versions: $allowedNextVersions'; - final Colorize redError = Colorize(error)..red(); - print(redError); - throw ToolExit(1); + printErrorAndExit(errorMessage: error); } bool isPlatformInterface = pubspec.name.endsWith("_platform_interface"); @@ -205,9 +156,7 @@ class VersionCheckCommand extends PluginCommand { NextVersionType.BREAKING_MAJOR) { final String error = '$pubspecPath breaking change detected.\n' 'Breaking changes to platform interfaces are strongly discouraged.\n'; - final Colorize redError = Colorize(error)..red(); - print(redError); - throw ToolExit(1); + printErrorAndExit(errorMessage: error); } } on io.ProcessException { print('Unable to find pubspec in master for $pubspecPath.' @@ -215,6 +164,74 @@ class VersionCheckCommand extends PluginCommand { } } + await for (Directory plugin in getPlugins()) { + await _checkVersionsMatch(plugin); + } + print('No version check errors found!'); } + + Future _checkVersionsMatch(Directory plugin) async { + // get version from pubspec + final String packageName = plugin.basename; + print('-----------------------------------------'); + print( + 'Checking the first version listed in CHANGELOG.MD matches the version in pubspec.yaml for $packageName.'); + + final Pubspec pubspec = _tryParsePubspec(plugin); + if (pubspec == null) { + final String error = 'Cannot parse version from pubspec.yaml'; + printErrorAndExit(errorMessage: error); + } + final Version fromPubspec = pubspec.version; + + // get first version from CHANGELOG + final File changelog = plugin.childFile('CHANGELOG.md'); + final List lines = changelog.readAsLinesSync(); + String firstLineWithText; + final Iterator iterator = lines.iterator; + while (iterator.moveNext()) { + if ((iterator.current as String).trim().isNotEmpty) { + firstLineWithText = iterator.current; + break; + } + } + // Remove all leading mark down syntax from the version line. + final String versionString = firstLineWithText.split(' ').last; + Version fromChangeLog = Version.parse(versionString); + if (fromChangeLog == null) { + final String error = + 'Cannot find version on the first line of ${plugin.path}/CHANGELOG.md'; + printErrorAndExit(errorMessage: error); + } + + if (fromPubspec != fromChangeLog) { + final String error = ''' +versions for $packageName in CHANGELOG.md and pubspec.yaml do not match. +The version in pubspec.yaml is $fromPubspec. +The first version listed in CHANGELOG.md is $fromChangeLog. +'''; + printErrorAndExit(errorMessage: error); + } + print('${packageName} passed version check'); + } + + Pubspec _tryParsePubspec(Directory package) { + final File pubspecFile = package.childFile('pubspec.yaml'); + + try { + Pubspec pubspec = Pubspec.parse(pubspecFile.readAsStringSync()); + if (pubspec == null) { + final String error = + 'Failed to parse `pubspec.yaml` at ${pubspecFile.path}'; + printErrorAndExit(errorMessage: error); + } + return pubspec; + } on Exception catch (exception) { + final String error = + 'Failed to parse `pubspec.yaml` at ${pubspecFile.path}: $exception}'; + printErrorAndExit(errorMessage: error); + } + return null; + } } diff --git a/script/tool/test/common_test.dart b/script/tool/test/common_test.dart index b3504c2358d9..0fb3ce74c373 100644 --- a/script/tool/test/common_test.dart +++ b/script/tool/test/common_test.dart @@ -1,6 +1,10 @@ +import 'dart:io'; + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/common.dart'; +import 'package:git/git.dart'; +import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; import 'util.dart'; @@ -9,8 +13,21 @@ void main() { RecordingProcessRunner processRunner; CommandRunner runner; List plugins; + List> gitDirCommands; + String gitDiffResponse; setUp(() { + gitDirCommands = >[]; + gitDiffResponse = ''; + final MockGitDir gitDir = MockGitDir(); + when(gitDir.runCommand(any)).thenAnswer((Invocation invocation) { + gitDirCommands.add(invocation.positionalArguments[0]); + final MockProcessResult mockProcessResult = MockProcessResult(); + if (invocation.positionalArguments[0][0] == 'diff') { + when(mockProcessResult.stdout).thenReturn(gitDiffResponse); + } + return Future.value(mockProcessResult); + }); initializeFakePackages(); processRunner = RecordingProcessRunner(); plugins = []; @@ -19,6 +36,7 @@ void main() { mockPackagesDir, mockFileSystem, processRunner: processRunner, + gitDir: gitDir, ); runner = CommandRunner('common_command', 'Test for common functionality'); @@ -73,6 +91,207 @@ void main() { ]); expect(plugins, unorderedEquals([plugin2.path])); }); + + group('test run-on-changed-packages', () { + test('all plugins should be tested if there are no changes.', () async { + final Directory plugin1 = createFakePlugin('plugin1'); + final Directory plugin2 = createFakePlugin('plugin2'); + await runner.run( + ['sample', '--base-sha=master', '--run-on-changed-packages']); + + expect(plugins, unorderedEquals([plugin1.path, plugin2.path])); + }); + + test('all plugins should be tested if there are no plugin related changes.', + () async { + gitDiffResponse = ".cirrus"; + final Directory plugin1 = createFakePlugin('plugin1'); + final Directory plugin2 = createFakePlugin('plugin2'); + await runner.run( + ['sample', '--base-sha=master', '--run-on-changed-packages']); + + expect(plugins, unorderedEquals([plugin1.path, plugin2.path])); + }); + + test('Only changed plugin should be tested.', () async { + gitDiffResponse = "packages/plugin1/plugin1.dart"; + final Directory plugin1 = createFakePlugin('plugin1'); + createFakePlugin('plugin2'); + await runner.run( + ['sample', '--base-sha=master', '--run-on-changed-packages']); + + expect(plugins, unorderedEquals([plugin1.path])); + }); + + test('multiple files in one plugin should also test the plugin', () async { + gitDiffResponse = ''' +packages/plugin1/plugin1.dart +packages/plugin1/ios/plugin1.m +'''; + final Directory plugin1 = createFakePlugin('plugin1'); + createFakePlugin('plugin2'); + await runner.run( + ['sample', '--base-sha=master', '--run-on-changed-packages']); + + expect(plugins, unorderedEquals([plugin1.path])); + }); + + test('multiple plugins changed should test all the changed plugins', + () async { + gitDiffResponse = ''' +packages/plugin1/plugin1.dart +packages/plugin2/ios/plugin2.m +'''; + final Directory plugin1 = createFakePlugin('plugin1'); + final Directory plugin2 = createFakePlugin('plugin2'); + createFakePlugin('plugin3'); + await runner.run( + ['sample', '--base-sha=master', '--run-on-changed-packages']); + + expect(plugins, unorderedEquals([plugin1.path, plugin2.path])); + }); + + test( + 'multiple plugins inside the same plugin group changed should output the plugin group name', + () async { + gitDiffResponse = ''' +packages/plugin1/plugin1/plugin1.dart +packages/plugin1/plugin1_platform_interface/plugin1_platform_interface.dart +packages/plugin1/plugin1_web/plugin1_web.dart +'''; + final Directory plugin1 = + createFakePlugin('plugin1', parentDirectoryName: 'plugin1'); + createFakePlugin('plugin2'); + createFakePlugin('plugin3'); + await runner.run( + ['sample', '--base-sha=master', '--run-on-changed-packages']); + + expect(plugins, unorderedEquals([plugin1.path])); + }); + + test('--plugins flag overrides the behavior of --run-on-changed-packages', + () async { + gitDiffResponse = ''' +packages/plugin1/plugin1.dart +packages/plugin2/ios/plugin2.m +packages/plugin3/plugin3.dart +'''; + final Directory plugin1 = + createFakePlugin('plugin1', parentDirectoryName: 'plugin1'); + final Directory plugin2 = createFakePlugin('plugin2'); + createFakePlugin('plugin3'); + await runner.run([ + 'sample', + '--plugins=plugin1,plugin2', + '--base-sha=master', + '--run-on-changed-packages' + ]); + + expect(plugins, unorderedEquals([plugin1.path, plugin2.path])); + }); + + test('--exclude flag works with --run-on-changed-packages', () async { + gitDiffResponse = ''' +packages/plugin1/plugin1.dart +packages/plugin2/ios/plugin2.m +packages/plugin3/plugin3.dart +'''; + final Directory plugin1 = + createFakePlugin('plugin1', parentDirectoryName: 'plugin1'); + createFakePlugin('plugin2'); + createFakePlugin('plugin3'); + await runner.run([ + 'sample', + '--exclude=plugin2,plugin3', + '--base-sha=master', + '--run-on-changed-packages' + ]); + + expect(plugins, unorderedEquals([plugin1.path])); + }); + }); + + group('$GitVersionFinder', () { + List> gitDirCommands; + String gitDiffResponse; + String mergeBaseResponse; + MockGitDir gitDir; + + setUp(() { + gitDirCommands = >[]; + gitDiffResponse = ''; + gitDir = MockGitDir(); + when(gitDir.runCommand(any)).thenAnswer((Invocation invocation) { + gitDirCommands.add(invocation.positionalArguments[0]); + final MockProcessResult mockProcessResult = MockProcessResult(); + if (invocation.positionalArguments[0][0] == 'diff') { + when(mockProcessResult.stdout).thenReturn(gitDiffResponse); + } else if (invocation.positionalArguments[0][0] == 'merge-base') { + when(mockProcessResult.stdout).thenReturn(mergeBaseResponse); + } + return Future.value(mockProcessResult); + }); + initializeFakePackages(); + processRunner = RecordingProcessRunner(); + }); + + tearDown(() { + cleanupPackages(); + }); + + test('No git diff should result no files changed', () async { + final GitVersionFinder finder = GitVersionFinder(gitDir, 'some base sha'); + List changedFiles = await finder.getChangedFiles(); + + expect(changedFiles, isEmpty); + }); + + test('get correct files changed based on git diff', () async { + gitDiffResponse = ''' +file1/file1.cc +file2/file2.cc +'''; + final GitVersionFinder finder = GitVersionFinder(gitDir, 'some base sha'); + List changedFiles = await finder.getChangedFiles(); + + expect( + changedFiles, equals(['file1/file1.cc', 'file2/file2.cc'])); + }); + + test('get correct pubspec change based on git diff', () async { + gitDiffResponse = ''' +file1/pubspec.yaml +file2/file2.cc +'''; + final GitVersionFinder finder = GitVersionFinder(gitDir, 'some base sha'); + List changedFiles = await finder.getChangedPubSpecs(); + + expect(changedFiles, equals(['file1/pubspec.yaml'])); + }); + + test('use correct base sha if not specified', () async { + mergeBaseResponse = 'shaqwiueroaaidf12312jnadf123nd'; + gitDiffResponse = ''' +file1/pubspec.yaml +file2/file2.cc +'''; + final GitVersionFinder finder = GitVersionFinder(gitDir, null); + await finder.getChangedFiles(); + verify(gitDir + .runCommand(['diff', '--name-only', mergeBaseResponse, 'HEAD'])); + }); + + test('use correct base sha if specified', () async { + final String customBaseSha = 'aklsjdcaskf12312'; + gitDiffResponse = ''' +file1/pubspec.yaml +file2/file2.cc +'''; + final GitVersionFinder finder = GitVersionFinder(gitDir, customBaseSha); + await finder.getChangedFiles(); + verify(gitDir.runCommand(['diff', '--name-only', customBaseSha, 'HEAD'])); + }); + }); } class SamplePluginCommand extends PluginCommand { @@ -81,7 +300,9 @@ class SamplePluginCommand extends PluginCommand { Directory packagesDir, FileSystem fileSystem, { ProcessRunner processRunner = const ProcessRunner(), - }) : super(packagesDir, fileSystem, processRunner: processRunner); + GitDir gitDir, + }) : super(packagesDir, fileSystem, + processRunner: processRunner, gitDir: gitDir); List plugins_; @@ -98,3 +319,7 @@ class SamplePluginCommand extends PluginCommand { } } } + +class MockGitDir extends Mock implements GitDir {} + +class MockProcessResult extends Mock implements ProcessResult {} diff --git a/script/tool/test/util.dart b/script/tool/test/util.dart index ec0000d13f34..1538d9b554e8 100644 --- a/script/tool/test/util.dart +++ b/script/tool/test/util.dart @@ -37,6 +37,8 @@ Directory createFakePlugin( bool isLinuxPlugin = false, bool isMacOsPlugin = false, bool isWindowsPlugin = false, + bool includeChangeLog = false, + bool includeVersion = false, String parentDirectoryName = '', }) { assert(!(withSingleExample && withExamples.isNotEmpty), @@ -57,7 +59,14 @@ Directory createFakePlugin( isLinuxPlugin: isLinuxPlugin, isMacOsPlugin: isMacOsPlugin, isWindowsPlugin: isWindowsPlugin, + includeVersion: includeVersion, ); + if (includeChangeLog) { + createFakeCHANGELOG(pluginDirectory, ''' +## 0.0.1 + * Some changes. + '''); + } if (withSingleExample) { final Directory exampleDir = pluginDirectory.childDirectory('example') @@ -85,6 +94,11 @@ Directory createFakePlugin( return pluginDirectory; } +void createFakeCHANGELOG(Directory parent, String texts) { + parent.childFile('CHANGELOG.md').createSync(); + parent.childFile('CHANGELOG.md').writeAsStringSync(texts); +} + /// Creates a `pubspec.yaml` file with a flutter dependency. void createFakePubspec( Directory parent, { @@ -97,6 +111,7 @@ void createFakePubspec( bool isLinuxPlugin = false, bool isMacOsPlugin = false, bool isWindowsPlugin = false, + String version = '0.0.1', }) { parent.childFile('pubspec.yaml').createSync(); String yaml = ''' @@ -152,8 +167,8 @@ dependencies: } if (includeVersion) { yaml += ''' -version: 0.0.1 -publish_to: none # Hardcoded safeguard to prevent this from somehow being published by a broken test. +version: $version +publish_to: http://no_pub_server.com # Hardcoded safeguard to prevent this from somehow being published by a broken test. '''; } parent.childFile('pubspec.yaml').writeAsStringSync(yaml); diff --git a/script/tool/test/version_check_test.dart b/script/tool/test/version_check_test.dart index b9ace3811bff..ac0d378c2a26 100644 --- a/script/tool/test/version_check_test.dart +++ b/script/tool/test/version_check_test.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:io'; import 'package:args/command_runner.dart'; +import 'package:flutter_plugin_tools/src/common.dart'; import 'package:git/git.dart'; import 'package:mockito/mockito.dart'; import "package:test/test.dart"; @@ -74,18 +75,18 @@ void main() { }); test('allows valid version', () async { - createFakePlugin('plugin'); + createFakePlugin('plugin', includeChangeLog: true, includeVersion: true); gitDiffResponse = "packages/plugin/pubspec.yaml"; gitShowResponses = { 'master:packages/plugin/pubspec.yaml': 'version: 1.0.0', 'HEAD:packages/plugin/pubspec.yaml': 'version: 2.0.0', }; final List output = await runCapturingPrint( - runner, ['version-check', '--base_sha=master']); + runner, ['version-check', '--base-sha=master']); expect( output, - orderedEquals([ + containsAllInOrder([ 'No version check errors found!', ]), ); @@ -99,14 +100,14 @@ void main() { }); test('denies invalid version', () async { - createFakePlugin('plugin'); + createFakePlugin('plugin', includeChangeLog: true, includeVersion: true); gitDiffResponse = "packages/plugin/pubspec.yaml"; gitShowResponses = { 'master:packages/plugin/pubspec.yaml': 'version: 0.0.1', 'HEAD:packages/plugin/pubspec.yaml': 'version: 0.2.0', }; final Future> result = runCapturingPrint( - runner, ['version-check', '--base_sha=master']); + runner, ['version-check', '--base-sha=master']); await expectLater( result, @@ -122,7 +123,7 @@ void main() { }); test('gracefully handles missing pubspec.yaml', () async { - createFakePlugin('plugin'); + createFakePlugin('plugin', includeChangeLog: true, includeVersion: true); gitDiffResponse = "packages/plugin/pubspec.yaml"; mockFileSystem.currentDirectory .childDirectory('packages') @@ -130,11 +131,12 @@ void main() { .childFile('pubspec.yaml') .deleteSync(); final List output = await runCapturingPrint( - runner, ['version-check', '--base_sha=master']); + runner, ['version-check', '--base-sha=master']); expect( output, orderedEquals([ + 'Determine diff with base sha: master', 'No version check errors found!', ]), ); @@ -144,7 +146,8 @@ void main() { }); test('allows minor changes to platform interfaces', () async { - createFakePlugin('plugin_platform_interface'); + createFakePlugin('plugin_platform_interface', + includeChangeLog: true, includeVersion: true); gitDiffResponse = "packages/plugin_platform_interface/pubspec.yaml"; gitShowResponses = { 'master:packages/plugin_platform_interface/pubspec.yaml': @@ -153,10 +156,10 @@ void main() { 'version: 1.1.0', }; final List output = await runCapturingPrint( - runner, ['version-check', '--base_sha=master']); + runner, ['version-check', '--base-sha=master']); expect( output, - orderedEquals([ + containsAllInOrder([ 'No version check errors found!', ]), ); @@ -172,7 +175,8 @@ void main() { }); test('disallows breaking changes to platform interfaces', () async { - createFakePlugin('plugin_platform_interface'); + createFakePlugin('plugin_platform_interface', + includeChangeLog: true, includeVersion: true); gitDiffResponse = "packages/plugin_platform_interface/pubspec.yaml"; gitShowResponses = { 'master:packages/plugin_platform_interface/pubspec.yaml': @@ -181,7 +185,7 @@ void main() { 'version: 2.0.0', }; final Future> output = runCapturingPrint( - runner, ['version-check', '--base_sha=master']); + runner, ['version-check', '--base-sha=master']); await expectLater( output, throwsA(const TypeMatcher()), @@ -196,6 +200,138 @@ void main() { expect(gitDirCommands[2].join(' '), equals('show HEAD:packages/plugin_platform_interface/pubspec.yaml')); }); + + test('Allow empty lines in front of the first version in CHANGELOG', + () async { + createFakePlugin('plugin', includeChangeLog: true, includeVersion: true); + + final Directory pluginDirectory = + mockPackagesDir.childDirectory('plugin'); + + createFakePubspec(pluginDirectory, + isFlutter: true, includeVersion: true, version: '1.0.1'); + String changelog = ''' + + + +## 1.0.1 + +* Some changes. +'''; + createFakeCHANGELOG(pluginDirectory, changelog); + final List output = await runCapturingPrint( + runner, ['version-check', '--base-sha=master']); + await expect( + output, + containsAllInOrder([ + 'Checking the first version listed in CHANGELOG.MD matches the version in pubspec.yaml for plugin.', + 'plugin passed version check', + 'No version check errors found!' + ]), + ); + }); + + test('Throws if versions in changelog and pubspec do not match', () async { + createFakePlugin('plugin', includeChangeLog: true, includeVersion: true); + + final Directory pluginDirectory = + mockPackagesDir.childDirectory('plugin'); + + createFakePubspec(pluginDirectory, + isFlutter: true, includeVersion: true, version: '1.0.1'); + String changelog = ''' +## 1.0.2 + +* Some changes. +'''; + createFakeCHANGELOG(pluginDirectory, changelog); + final Future> output = runCapturingPrint( + runner, ['version-check', '--base-sha=master']); + await expectLater( + output, + throwsA(const TypeMatcher()), + ); + try { + List outputValue = await output; + await expectLater( + outputValue, + containsAllInOrder([ + ''' + versions for plugin in CHANGELOG.md and pubspec.yaml do not match. + The version in pubspec.yaml is 1.0.1. + The first version listed in CHANGELOG.md is 1.0.2. + ''', + ]), + ); + } on ToolExit catch (_) {} + }); + + test('Success if CHANGELOG and pubspec versions match', () async { + createFakePlugin('plugin', includeChangeLog: true, includeVersion: true); + + final Directory pluginDirectory = + mockPackagesDir.childDirectory('plugin'); + + createFakePubspec(pluginDirectory, + isFlutter: true, includeVersion: true, version: '1.0.1'); + String changelog = ''' +## 1.0.1 + +* Some changes. +'''; + createFakeCHANGELOG(pluginDirectory, changelog); + final List output = await runCapturingPrint( + runner, ['version-check', '--base-sha=master']); + await expect( + output, + containsAllInOrder([ + 'Checking the first version listed in CHANGELOG.MD matches the version in pubspec.yaml for plugin.', + 'plugin passed version check', + 'No version check errors found!' + ]), + ); + }); + + test( + 'Fail if pubspec version only matches an older version listed in CHANGELOG', + () async { + createFakePlugin('plugin', includeChangeLog: true, includeVersion: true); + + final Directory pluginDirectory = + mockPackagesDir.childDirectory('plugin'); + + createFakePubspec(pluginDirectory, + isFlutter: true, includeVersion: true, version: '1.0.0'); + String changelog = ''' +## 1.0.1 + +* Some changes. + +## 1.0.0 + +* Some other changes. +'''; + createFakeCHANGELOG(pluginDirectory, changelog); + Future> output = runCapturingPrint( + runner, ['version-check', '--base-sha=master']); + await expectLater( + output, + throwsA(const TypeMatcher()), + ); + try { + List outputValue = await output; + await expectLater( + outputValue, + containsAllInOrder([ + ''' + versions for plugin in CHANGELOG.md and pubspec.yaml do not match. + The version in pubspec.yaml is 1.0.0. + The first version listed in CHANGELOG.md is 1.0.1. + ''', + ]), + ); + } on ToolExit catch (_) {} + }); }); group("Pre 1.0", () { From d7724ad6f24a6deeec4a88a68d6903252b7961ff Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Wed, 10 Mar 2021 15:05:38 -0800 Subject: [PATCH 0266/1565] [cross_file] Delete. (#3698) The package now lives in flutter/packages. --- CODEOWNERS | 1 - packages/cross_file/CHANGELOG.md | 30 ---- packages/cross_file/LICENSE | 25 ---- packages/cross_file/README.md | 34 ----- packages/cross_file/lib/cross_file.dart | 5 - packages/cross_file/lib/src/types/base.dart | 86 ----------- packages/cross_file/lib/src/types/html.dart | 135 ------------------ .../cross_file/lib/src/types/interface.dart | 58 -------- packages/cross_file/lib/src/types/io.dart | 115 --------------- .../lib/src/web_helpers/web_helpers.dart | 38 ----- packages/cross_file/lib/src/x_file.dart | 7 - packages/cross_file/pubspec.yaml | 18 --- packages/cross_file/test/assets/hello.txt | 1 - .../cross_file/test/x_file_html_test.dart | 106 -------------- packages/cross_file/test/x_file_io_test.dart | 90 ------------ 15 files changed, 749 deletions(-) delete mode 100644 packages/cross_file/CHANGELOG.md delete mode 100644 packages/cross_file/LICENSE delete mode 100644 packages/cross_file/README.md delete mode 100644 packages/cross_file/lib/cross_file.dart delete mode 100644 packages/cross_file/lib/src/types/base.dart delete mode 100644 packages/cross_file/lib/src/types/html.dart delete mode 100644 packages/cross_file/lib/src/types/interface.dart delete mode 100644 packages/cross_file/lib/src/types/io.dart delete mode 100644 packages/cross_file/lib/src/web_helpers/web_helpers.dart delete mode 100644 packages/cross_file/lib/src/x_file.dart delete mode 100644 packages/cross_file/pubspec.yaml delete mode 100644 packages/cross_file/test/assets/hello.txt delete mode 100644 packages/cross_file/test/x_file_html_test.dart delete mode 100644 packages/cross_file/test/x_file_io_test.dart diff --git a/CODEOWNERS b/CODEOWNERS index 01732888ad89..8ab65bbb5a63 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -6,7 +6,6 @@ packages/camera/** @bparrishMines -packages/cross_file/** @ditman @mvanbeusekom packages/file_selector/** @ditman packages/google_maps_flutter/** @cyanglaz packages/image_picker/** @cyanglaz diff --git a/packages/cross_file/CHANGELOG.md b/packages/cross_file/CHANGELOG.md deleted file mode 100644 index 94bf4b29322a..000000000000 --- a/packages/cross_file/CHANGELOG.md +++ /dev/null @@ -1,30 +0,0 @@ -## 0.3.1 - -* Fix nullability of `XFileBase`'s `path` and `name` to match the - implementations to avoid potential analyzer issues. - -## 0.3.0 - -* Migrated package to null-safety. -* **breaking change** According to our unit tests, the API should be backwards-compatible. Some relevant changes were made, however: - * Web: `lastModified` returns the epoch time as a default value, to maintain the `Future` return type (and not `null`) - -## 0.2.1 - -* Prepare for breaking `package:http` change. - -## 0.2.0 - -* **breaking change** Make sure the `saveTo` method returns a `Future` so it can be awaited and users are sure the file has been written to disk. - -## 0.1.0+2 - -* Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) - -## 0.1.0+1 - -* Update Flutter SDK constraint. - -## 0.1.0 - -* Initial open-source release. diff --git a/packages/cross_file/LICENSE b/packages/cross_file/LICENSE deleted file mode 100644 index 2c91f1438173..000000000000 --- a/packages/cross_file/LICENSE +++ /dev/null @@ -1,25 +0,0 @@ -Copyright 2020 The Flutter Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of Google Inc. nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/packages/cross_file/README.md b/packages/cross_file/README.md deleted file mode 100644 index 65bd41896184..000000000000 --- a/packages/cross_file/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# cross_file - -An abstraction to allow working with files across multiple platforms. - -# Usage - -Import `package:cross/cross_info.dart`, instantiate a `CrossFile` -using a path or byte array and use its methods and properties to -access the file and its metadata. - -Example: - -```dart -import 'package:cross_file/cross_file.dart'; - -final file = CrossFile('assets/hello.txt'); - -print('File information:'); -print('- Path: ${file.path}'); -print('- Name: ${file.name}'); -print('- MIME type: ${file.mimeType}'); - -final fileContent = await file.readAsString(); -print('Content of the file: ${fileContent}'); // e.g. "Moto G (4)" -``` - -You will find links to the API docs on the [pub page](https://pub.dev/packages/cross_file). - -## Getting Started - -For help getting started with Flutter, view our online -[documentation](http://flutter.io/). - -For help on editing plugin code, view the [documentation](https://flutter.io/platform-plugins/#edit-code). \ No newline at end of file diff --git a/packages/cross_file/lib/cross_file.dart b/packages/cross_file/lib/cross_file.dart deleted file mode 100644 index a3e2873e670d..000000000000 --- a/packages/cross_file/lib/cross_file.dart +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 2018 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. - -export 'src/x_file.dart'; diff --git a/packages/cross_file/lib/src/types/base.dart b/packages/cross_file/lib/src/types/base.dart deleted file mode 100644 index 4522b7343c9b..000000000000 --- a/packages/cross_file/lib/src/types/base.dart +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2018 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. - -import 'dart:convert'; -import 'dart:typed_data'; - -/// The interface for a CrossFile. -/// -/// A CrossFile is a container that wraps the path of a selected -/// file by the user and (in some platforms, like web) the bytes -/// with the contents of the file. -/// -/// This class is a very limited subset of dart:io [File], so all -/// the methods should seem familiar. -abstract class XFileBase { - /// Construct a CrossFile - XFileBase(String? path); - - /// Save the CrossFile at the indicated file path. - Future saveTo(String path) { - throw UnimplementedError('saveTo has not been implemented.'); - } - - /// Get the path of the picked file. - /// - /// This should only be used as a backwards-compatibility clutch - /// for mobile apps, or cosmetic reasons only (to show the user - /// the path they've picked). - /// - /// Accessing the data contained in the picked file by its path - /// is platform-dependant (and won't work on web), so use the - /// byte getters in the CrossFile instance instead. - String get path { - throw UnimplementedError('.path has not been implemented.'); - } - - /// The name of the file as it was selected by the user in their device. - /// - /// Use only for cosmetic reasons, do not try to use this as a path. - String get name { - throw UnimplementedError('.name has not been implemented.'); - } - - /// For web, it may be necessary for a file to know its MIME type. - String? get mimeType { - throw UnimplementedError('.mimeType has not been implemented.'); - } - - /// Get the length of the file. Returns a `Future` that completes with the length in bytes. - Future length() { - throw UnimplementedError('.length() has not been implemented.'); - } - - /// Synchronously read the entire file contents as a string using the given [Encoding]. - /// - /// By default, `encoding` is [utf8]. - /// - /// Throws Exception if the operation fails. - Future readAsString({Encoding encoding = utf8}) { - throw UnimplementedError('readAsString() has not been implemented.'); - } - - /// Synchronously read the entire file contents as a list of bytes. - /// - /// Throws Exception if the operation fails. - Future readAsBytes() { - throw UnimplementedError('readAsBytes() has not been implemented.'); - } - - /// Create a new independent [Stream] for the contents of this file. - /// - /// If `start` is present, the file will be read from byte-offset `start`. Otherwise from the beginning (index 0). - /// - /// If `end` is present, only up to byte-index `end` will be read. Otherwise, until end of file. - /// - /// In order to make sure that system resources are freed, the stream must be read to completion or the subscription on the stream must be cancelled. - Stream openRead([int? start, int? end]) { - throw UnimplementedError('openRead() has not been implemented.'); - } - - /// Get the last-modified time for the CrossFile - Future lastModified() { - throw UnimplementedError('openRead() has not been implemented.'); - } -} diff --git a/packages/cross_file/lib/src/types/html.dart b/packages/cross_file/lib/src/types/html.dart deleted file mode 100644 index 203ab5d82e12..000000000000 --- a/packages/cross_file/lib/src/types/html.dart +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright 2018 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. - -import 'dart:convert'; -import 'dart:html'; -import 'dart:typed_data'; - -import 'package:meta/meta.dart'; - -import './base.dart'; -import '../web_helpers/web_helpers.dart'; - -/// A CrossFile that works on web. -/// -/// It wraps the bytes of a selected file. -class XFile extends XFileBase { - late String path; - - final String? mimeType; - final Uint8List? _data; - final int? _length; - final String name; - final DateTime? _lastModified; - - late Element _target; - - final CrossFileTestOverrides? _overrides; - - bool get _hasTestOverrides => _overrides != null; - - /// Construct a CrossFile object from its ObjectUrl. - /// - /// Optionally, this can be initialized with `bytes` and `length` - /// so no http requests are performed to retrieve files later. - /// - /// `name` needs to be passed from the outside, since we only have - /// access to it while we create the ObjectUrl. - XFile( - this.path, { - this.mimeType, - String? name, - int? length, - Uint8List? bytes, - DateTime? lastModified, - @visibleForTesting CrossFileTestOverrides? overrides, - }) : _data = bytes, - _length = length, - _overrides = overrides, - _lastModified = lastModified ?? DateTime.fromMillisecondsSinceEpoch(0), - name = name ?? '', - super(path); - - /// Construct an CrossFile from its data - XFile.fromData( - Uint8List bytes, { - this.mimeType, - String? name, - int? length, - DateTime? lastModified, - String? path, - @visibleForTesting CrossFileTestOverrides? overrides, - }) : _data = bytes, - _length = length, - _overrides = overrides, - _lastModified = lastModified ?? DateTime.fromMillisecondsSinceEpoch(0), - name = name ?? '', - super(path) { - if (path == null) { - final blob = (mimeType == null) ? Blob([bytes]) : Blob([bytes], mimeType); - this.path = Url.createObjectUrl(blob); - } else { - this.path = path; - } - } - - @override - Future lastModified() async => Future.value(_lastModified); - - Future get _bytes async { - if (_data != null) { - return Future.value(UnmodifiableUint8ListView(_data!)); - } - - // We can force 'response' to be a byte buffer by passing responseType: - ByteBuffer? response = - (await HttpRequest.request(path, responseType: 'arraybuffer')).response; - - return response?.asUint8List() ?? Uint8List(0); - } - - @override - Future length() async => _length ?? (await _bytes).length; - - @override - Future readAsString({Encoding encoding = utf8}) async { - return encoding.decode(await _bytes); - } - - @override - Future readAsBytes() async => Future.value(await _bytes); - - @override - Stream openRead([int? start, int? end]) async* { - final bytes = await _bytes; - yield bytes.sublist(start ?? 0, end ?? bytes.length); - } - - /// Saves the data of this CrossFile at the location indicated by path. - /// For the web implementation, the path variable is ignored. - Future saveTo(String path) async { - // Create a DOM container where we can host the anchor. - _target = ensureInitialized('__x_file_dom_element'); - - // Create an tag with the appropriate download attributes and click it - // May be overridden with CrossFileTestOverrides - final AnchorElement element = _hasTestOverrides - ? _overrides!.createAnchorElement(this.path, this.name) as AnchorElement - : createAnchorElement(this.path, this.name); - - // Clear the children in our container so we can add an element to click - _target.children.clear(); - addElementToContainerAndClick(_target, element); - } -} - -/// Overrides some functions to allow testing -@visibleForTesting -class CrossFileTestOverrides { - /// For overriding the creation of the file input element. - Element Function(String href, String suggestedName) createAnchorElement; - - /// Default constructor for overrides - CrossFileTestOverrides({required this.createAnchorElement}); -} diff --git a/packages/cross_file/lib/src/types/interface.dart b/packages/cross_file/lib/src/types/interface.dart deleted file mode 100644 index 122f3d1d9364..000000000000 --- a/packages/cross_file/lib/src/types/interface.dart +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2018 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. - -import 'dart:typed_data'; -import 'package:meta/meta.dart'; - -import './base.dart'; - -/// A CrossFile is a cross-platform, simplified File abstraction. -/// -/// It wraps the bytes of a selected file, and its (platform-dependant) path. -class XFile extends XFileBase { - /// Construct a CrossFile object from its path. - /// - /// Optionally, this can be initialized with `bytes` and `length` - /// so no http requests are performed to retrieve data later. - /// - /// `name` may be passed from the outside, for those cases where the effective - /// `path` of the file doesn't match what the user sees when selecting it - /// (like in web) - XFile( - String path, { - String? mimeType, - String? name, - int? length, - Uint8List? bytes, - DateTime? lastModified, - @visibleForTesting CrossFileTestOverrides? overrides, - }) : super(path) { - throw UnimplementedError( - 'CrossFile is not available in your current platform.'); - } - - /// Construct a CrossFile object from its data - XFile.fromData( - Uint8List bytes, { - String? mimeType, - String? name, - int? length, - DateTime? lastModified, - String? path, - @visibleForTesting CrossFileTestOverrides? overrides, - }) : super(path) { - throw UnimplementedError( - 'CrossFile is not available in your current platform.'); - } -} - -/// Overrides some functions of CrossFile for testing purposes -@visibleForTesting -class CrossFileTestOverrides { - /// For overriding the creation of the file input element. - dynamic Function(String href, String suggestedName) createAnchorElement; - - /// Default constructor for overrides - CrossFileTestOverrides({required this.createAnchorElement}); -} diff --git a/packages/cross_file/lib/src/types/io.dart b/packages/cross_file/lib/src/types/io.dart deleted file mode 100644 index 6eafaf0ce0cc..000000000000 --- a/packages/cross_file/lib/src/types/io.dart +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2018 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. - -import 'dart:convert'; -import 'dart:io'; -import 'dart:typed_data'; - -import './base.dart'; - -/// A CrossFile backed by a dart:io File. -class XFile extends XFileBase { - final File _file; - final String? mimeType; - final DateTime? _lastModified; - int? _length; - - final Uint8List? _bytes; - - /// Construct a CrossFile object backed by a dart:io File. - XFile( - String path, { - this.mimeType, - String? name, - int? length, - Uint8List? bytes, - DateTime? lastModified, - }) : _file = File(path), - _bytes = null, - _lastModified = lastModified, - super(path); - - /// Construct an CrossFile from its data - XFile.fromData( - Uint8List bytes, { - this.mimeType, - String? path, - String? name, - int? length, - DateTime? lastModified, - }) : _bytes = bytes, - _file = File(path ?? ''), - _length = length, - _lastModified = lastModified, - super(path) { - if (length == null) { - _length = bytes.length; - } - } - - @override - Future lastModified() { - if (_lastModified != null) { - return Future.value(_lastModified); - } - return _file.lastModified(); - } - - @override - Future saveTo(String path) async { - File fileToSave = File(path); - await fileToSave.writeAsBytes(_bytes ?? (await readAsBytes())); - await fileToSave.create(); - } - - @override - String get path { - return _file.path; - } - - @override - String get name { - return _file.path.split(Platform.pathSeparator).last; - } - - @override - Future length() { - if (_length != null) { - return Future.value(_length); - } - return _file.length(); - } - - @override - Future readAsString({Encoding encoding = utf8}) { - if (_bytes != null) { - return Future.value(String.fromCharCodes(_bytes!)); - } - return _file.readAsString(encoding: encoding); - } - - @override - Future readAsBytes() { - if (_bytes != null) { - return Future.value(_bytes); - } - return _file.readAsBytes(); - } - - Stream _getBytes(int? start, int? end) async* { - final bytes = _bytes!; - yield bytes.sublist(start ?? 0, end ?? bytes.length); - } - - @override - Stream openRead([int? start, int? end]) { - if (_bytes != null) { - return _getBytes(start, end); - } else { - return _file - .openRead(start ?? 0, end) - .map((chunk) => Uint8List.fromList(chunk)); - } - } -} diff --git a/packages/cross_file/lib/src/web_helpers/web_helpers.dart b/packages/cross_file/lib/src/web_helpers/web_helpers.dart deleted file mode 100644 index a963e9933f99..000000000000 --- a/packages/cross_file/lib/src/web_helpers/web_helpers.dart +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2018 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. - -import 'dart:html'; - -/// Create anchor element with download attribute -AnchorElement createAnchorElement(String href, String suggestedName) { - final element = AnchorElement(href: href); - - if (suggestedName == null) { - element.download = 'download'; - } else { - element.download = suggestedName; - } - - return element; -} - -/// Add an element to a container and click it -void addElementToContainerAndClick(Element container, Element element) { - // Add the element and click it - // All previous elements will be removed before adding the new one - container.children.add(element); - element.click(); -} - -/// Initializes a DOM container where we can host elements. -Element ensureInitialized(String id) { - var target = querySelector('#${id}'); - if (target == null) { - final Element targetElement = Element.tag('flt-x-file')..id = id; - - querySelector('body')!.children.add(targetElement); - target = targetElement; - } - return target; -} diff --git a/packages/cross_file/lib/src/x_file.dart b/packages/cross_file/lib/src/x_file.dart deleted file mode 100644 index 6136bff39f36..000000000000 --- a/packages/cross_file/lib/src/x_file.dart +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2018 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. - -export 'types/interface.dart' - if (dart.library.html) 'types/html.dart' - if (dart.library.io) 'types/io.dart'; diff --git a/packages/cross_file/pubspec.yaml b/packages/cross_file/pubspec.yaml deleted file mode 100644 index 66d3f46a84e3..000000000000 --- a/packages/cross_file/pubspec.yaml +++ /dev/null @@ -1,18 +0,0 @@ -name: cross_file -description: An abstraction to allow working with files across multiple platforms. -homepage: https://github.com/flutter/plugins/tree/master/packages/cross_file -version: 0.3.1 - -dependencies: - flutter: - sdk: flutter - meta: ^1.3.0 - -dev_dependencies: - flutter_test: - sdk: flutter - pedantic: ^1.10.0 - -environment: - sdk: ">=2.12.0-259.9.beta <3.0.0" - flutter: ">=1.22.0" diff --git a/packages/cross_file/test/assets/hello.txt b/packages/cross_file/test/assets/hello.txt deleted file mode 100644 index 5dd01c177f5d..000000000000 --- a/packages/cross_file/test/assets/hello.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/packages/cross_file/test/x_file_html_test.dart b/packages/cross_file/test/x_file_html_test.dart deleted file mode 100644 index a271aa1f1525..000000000000 --- a/packages/cross_file/test/x_file_html_test.dart +++ /dev/null @@ -1,106 +0,0 @@ -// 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. - -@TestOn('chrome') // Uses web-only Flutter SDK - -import 'dart:convert'; -import 'dart:html' as html; -import 'dart:typed_data'; - -import 'package:flutter_test/flutter_test.dart'; -import 'package:cross_file/cross_file.dart'; - -final String expectedStringContents = 'Hello, world!'; -final Uint8List bytes = Uint8List.fromList(utf8.encode(expectedStringContents)); -final html.File textFile = html.File([bytes], 'hello.txt'); -final String textFileUrl = html.Url.createObjectUrl(textFile); - -void main() { - group('Create with an objectUrl', () { - final file = XFile(textFileUrl); - - test('Can be read as a string', () async { - expect(await file.readAsString(), equals(expectedStringContents)); - }); - test('Can be read as bytes', () async { - expect(await file.readAsBytes(), equals(bytes)); - }); - - test('Can be read as a stream', () async { - expect(await file.openRead().first, equals(bytes)); - }); - - test('Stream can be sliced', () async { - expect(await file.openRead(2, 5).first, equals(bytes.sublist(2, 5))); - }); - }); - - group('Create from data', () { - final file = XFile.fromData(bytes); - - test('Can be read as a string', () async { - expect(await file.readAsString(), equals(expectedStringContents)); - }); - test('Can be read as bytes', () async { - expect(await file.readAsBytes(), equals(bytes)); - }); - - test('Can be read as a stream', () async { - expect(await file.openRead().first, equals(bytes)); - }); - - test('Stream can be sliced', () async { - expect(await file.openRead(2, 5).first, equals(bytes.sublist(2, 5))); - }); - }); - - group('saveTo(..)', () { - final String CrossFileDomElementId = '__x_file_dom_element'; - - group('CrossFile saveTo(..)', () { - test('creates a DOM container', () async { - XFile file = XFile.fromData(bytes); - - await file.saveTo(''); - - final container = html.querySelector('#${CrossFileDomElementId}'); - - expect(container, isNotNull); - }); - - test('create anchor element', () async { - XFile file = XFile.fromData(bytes, name: textFile.name); - - await file.saveTo('path'); - - final container = html.querySelector('#${CrossFileDomElementId}'); - final html.AnchorElement element = - container?.children.firstWhere((element) => element.tagName == 'A') - as html.AnchorElement; - - // if element is not found, the `firstWhere` call will throw StateError. - expect(element.href, file.path); - expect(element.download, file.name); - }); - - test('anchor element is clicked', () async { - final mockAnchor = html.AnchorElement(); - - CrossFileTestOverrides overrides = CrossFileTestOverrides( - createAnchorElement: (_, __) => mockAnchor, - ); - - XFile file = - XFile.fromData(bytes, name: textFile.name, overrides: overrides); - - bool clicked = false; - mockAnchor.onClick.listen((event) => clicked = true); - - await file.saveTo('path'); - - expect(clicked, true); - }); - }); - }); -} diff --git a/packages/cross_file/test/x_file_io_test.dart b/packages/cross_file/test/x_file_io_test.dart deleted file mode 100644 index 94ac81c4cac4..000000000000 --- a/packages/cross_file/test/x_file_io_test.dart +++ /dev/null @@ -1,90 +0,0 @@ -// 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. - -@TestOn('vm') // Uses dart:io - -import 'dart:convert'; -import 'dart:io'; -import 'dart:typed_data'; - -import 'package:flutter_test/flutter_test.dart'; -import 'package:cross_file/cross_file.dart'; - -final pathPrefix = - Directory.current.path.endsWith('test') ? './assets/' : './test/assets/'; -final path = pathPrefix + 'hello.txt'; -final String expectedStringContents = 'Hello, world!'; -final Uint8List bytes = Uint8List.fromList(utf8.encode(expectedStringContents)); -final File textFile = File(path); -final String textFilePath = textFile.path; - -void main() { - group('Create with a path', () { - final XFile file = XFile(textFilePath); - - test('Can be read as a string', () async { - expect(await file.readAsString(), equals(expectedStringContents)); - }); - test('Can be read as bytes', () async { - expect(await file.readAsBytes(), equals(bytes)); - }); - - test('Can be read as a stream', () async { - expect(await file.openRead().first, equals(bytes)); - }); - - test('Stream can be sliced', () async { - expect(await file.openRead(2, 5).first, equals(bytes.sublist(2, 5))); - }); - - test('saveTo(..) creates file', () async { - File removeBeforeTest = File(pathPrefix + 'newFilePath.txt'); - if (removeBeforeTest.existsSync()) { - await removeBeforeTest.delete(); - } - - await file.saveTo(pathPrefix + 'newFilePath.txt'); - File newFile = File(pathPrefix + 'newFilePath.txt'); - - expect(newFile.existsSync(), isTrue); - expect(newFile.readAsStringSync(), 'Hello, world!'); - - await newFile.delete(); - }); - }); - - group('Create with data', () { - final file = XFile.fromData(bytes); - - test('Can be read as a string', () async { - expect(await file.readAsString(), equals(expectedStringContents)); - }); - test('Can be read as bytes', () async { - expect(await file.readAsBytes(), equals(bytes)); - }); - - test('Can be read as a stream', () async { - expect(await file.openRead().first, equals(bytes)); - }); - - test('Stream can be sliced', () async { - expect(await file.openRead(2, 5).first, equals(bytes.sublist(2, 5))); - }); - - test('Function saveTo(..) creates file', () async { - File removeBeforeTest = File(pathPrefix + 'newFileData.txt'); - if (removeBeforeTest.existsSync()) { - await removeBeforeTest.delete(); - } - - await file.saveTo(pathPrefix + 'newFileData.txt'); - File newFile = File(pathPrefix + 'newFileData.txt'); - - expect(newFile.existsSync(), isTrue); - expect(newFile.readAsStringSync(), 'Hello, world!'); - - await newFile.delete(); - }); - }); -} From fd52de8dfc29387c78c8657c44faabba8227d566 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Wed, 10 Mar 2021 17:58:25 -0800 Subject: [PATCH 0267/1565] Skip flutter upgrade for pod linting Cirrus task (#3700) --- .cirrus.yml | 72 +++++++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 8f61fabc4f2a..67669d783192 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,25 +1,37 @@ -root_task_template: &ROOT_TASK_TEMPLATE - # Don't run on release tags since it creates O(n^2) tasks where n is the - # number of plugins - only_if: $CIRRUS_TAG == '' - use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_PR == '' - env: - INTEGRATION_TEST_PATH: "./packages/integration_test" - CHANNEL: "master" # Default to master when not explicitly set by a task. - PLUGIN_TOOLS: "dart run ./script/tool/lib/src/main.dart" - setup_script: - - flutter channel $CHANNEL - - flutter upgrade +# Don't run on release tags since it creates O(n^2) tasks where n is the +# number of plugins +only_if: $CIRRUS_TAG == '' +use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_PR == '' +env: + INTEGRATION_TEST_PATH: "./packages/integration_test" + CHANNEL: "master" # Default to master when not explicitly set by a task. + PLUGIN_TOOLS: "dart run ./script/tool/lib/src/main.dart" + +tool_setup_template: &TOOL_SETUP_TEMPLATE + tool_setup_script: - git fetch origin master # To set FETCH_HEAD for "git merge-base" to work - cd script/tool - pub get +flutter_upgrade_template: &FLUTTER_UPGRADE_TEMPLATE + upgrade_flutter_script: + - flutter channel $CHANNEL + - flutter upgrade + << : *TOOL_SETUP_TEMPLATE + +macos_template: &MACOS_TEMPLATE + # Only one macOS task can run in parallel without credits, so use them for + # PRs on macOS. + use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' + osx_instance: + image: big-sur-xcode-12.3 + cocoapod_install_script: sudo gem install cocoapods # Light-workload Linux tasks. # These use default machines, with fewer CPUs, to reduce pressure on the # concurrency limits. task: - << : *ROOT_TASK_TEMPLATE + << : *FLUTTER_UPGRADE_TEMPLATE container: dockerfile: .ci/Dockerfile matrix: @@ -109,7 +121,7 @@ task: # tasks" block above once web_installers has been updated to support Chrome 89 # (which is what the current image generated from .ci/Dockerfile has). task: - << : *ROOT_TASK_TEMPLATE + << : *FLUTTER_UPGRADE_TEMPLATE container: dockerfile: .ci/Dockerfile-LegacyChrome matrix: @@ -134,7 +146,7 @@ task: # These use machines with more CPUs and memory, so will reduce parallelization # for non-credit runs. task: - << : *ROOT_TASK_TEMPLATE + << : *FLUTTER_UPGRADE_TEMPLATE container: dockerfile: .ci/Dockerfile cpu: 4 @@ -177,24 +189,9 @@ task: # macOS tasks. task: - << : *ROOT_TASK_TEMPLATE - # Only one macOS task can run in parallel without credits, so use them for - # PRs on macOS. - use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' - osx_instance: - image: big-sur-xcode-12.3 - cocoapod_install_script: sudo gem install cocoapods + << : *MACOS_TEMPLATE + << : *FLUTTER_UPGRADE_TEMPLATE matrix: - ### Platform-agnostic tasks ### - - name: lint_darwin_plugins - env: - matrix: - PLUGIN_SHARDING: "--shardIndex 0 --shardCount 2" - PLUGIN_SHARDING: "--shardIndex 1 --shardCount 2" - script: - # TODO(jmagman): Lint macOS podspecs but skip any that fail library validation. - - find . -name "*.podspec" | xargs grep -l "osx" | xargs rm - - ./script/incremental_build.sh podspecs ### iOS tasks ### - name: build_all_plugins_ipa env: @@ -245,3 +242,14 @@ task: - flutter config --enable-macos-desktop - ./script/incremental_build.sh build-examples --macos --no-ipa - ./script/incremental_build.sh drive-examples --macos + +task: + # Don't use FLUTTER_UPGRADE_TEMPLATE, Flutter tooling not needed. + << : *MACOS_TEMPLATE + << : *TOOL_SETUP_TEMPLATE + matrix: + - name: lint_darwin_plugins + script: + # TODO(jmagman): Lint macOS podspecs but skip any that fail library validation. + - find . -name "*.podspec" | xargs grep -l "osx" | xargs rm + - ./script/incremental_build.sh podspecs From d72cebd235220000cc7b438c7b48c9a27e07699b Mon Sep 17 00:00:00 2001 From: Adam Koprowski Date: Thu, 11 Mar 2021 18:15:02 +0000 Subject: [PATCH 0268/1565] Typos in comments (#2846) --- packages/in_app_purchase/example/lib/main.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/in_app_purchase/example/lib/main.dart b/packages/in_app_purchase/example/lib/main.dart index c9f0bb6ece25..32676cf799ea 100644 --- a/packages/in_app_purchase/example/lib/main.dart +++ b/packages/in_app_purchase/example/lib/main.dart @@ -343,7 +343,7 @@ class _MyAppState extends State<_MyApp> { } void deliverProduct(PurchaseDetails purchaseDetails) async { - // IMPORTANT!! Always verify a purchase purchase details before delivering the product. + // IMPORTANT!! Always verify purchase details before delivering the product. if (purchaseDetails.productID == _kConsumableId) { await ConsumableStore.save(purchaseDetails.purchaseID!); List consumables = await ConsumableStore.load(); From f4c513eb8c4169b7b7fd5c0e74fcf94cea7bad2d Mon Sep 17 00:00:00 2001 From: Sunbreak Date: Fri, 12 Mar 2021 21:34:14 +0800 Subject: [PATCH 0269/1565] Fix missing declaration of windows' default_package (#3705) Signed-off-by: Sunbreak --- packages/shared_preferences/shared_preferences/CHANGELOG.md | 4 ++++ packages/shared_preferences/shared_preferences/pubspec.yaml | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/shared_preferences/shared_preferences/CHANGELOG.md b/packages/shared_preferences/shared_preferences/CHANGELOG.md index b0899d57a3c5..583d8c238315 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.5 + +* Fix missing declaration of windows' default_package + ## 2.0.4 * Fix a regression with simultaneous writes on Android. diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index b53bbfd93a38..3f8391f188d7 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -2,7 +2,7 @@ name: shared_preferences description: Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences -version: 2.0.4 +version: 2.0.5 flutter: plugin: @@ -18,6 +18,8 @@ flutter: default_package: shared_preferences_macos web: default_package: shared_preferences_web + windows: + default_package: shared_preferences_windows dependencies: meta: ^1.3.0 From e23390260b9f3ad8964a4a18cd7ffc103b813acb Mon Sep 17 00:00:00 2001 From: Sunbreak Date: Sat, 13 Mar 2021 08:32:55 +0800 Subject: [PATCH 0270/1565] Re-endorse connectivity_for_web (#3708) Signed-off-by: Sunbreak --- packages/connectivity/connectivity/CHANGELOG.md | 4 ++++ packages/connectivity/connectivity/pubspec.yaml | 6 ++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/connectivity/connectivity/CHANGELOG.md b/packages/connectivity/connectivity/CHANGELOG.md index 57de797ff045..3d69b7bad143 100644 --- a/packages/connectivity/connectivity/CHANGELOG.md +++ b/packages/connectivity/connectivity/CHANGELOG.md @@ -1,3 +1,7 @@ +## 3.0.3 + +* Re-endorse connectivity_for_web + ## 3.0.2 * Update platform_plugin_interface version requirement. diff --git a/packages/connectivity/connectivity/pubspec.yaml b/packages/connectivity/connectivity/pubspec.yaml index eeef53c4faa4..7b4dc60eee81 100644 --- a/packages/connectivity/connectivity/pubspec.yaml +++ b/packages/connectivity/connectivity/pubspec.yaml @@ -2,7 +2,7 @@ name: connectivity description: Flutter plugin for discovering the state of the network (WiFi & mobile/cellular) connectivity on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity -version: 3.0.2 +version: 3.0.3 flutter: plugin: @@ -22,10 +22,8 @@ dependencies: sdk: flutter meta: ^1.3.0 connectivity_platform_interface: ^2.0.0 - #TODO(cyanglaz): re-endorse the below plugins when they have migrated to nnbd. - # https://github.com/flutter/flutter/issues/68669 connectivity_macos: ^0.2.0 - # connectivity_for_web: ^0.3.0 + connectivity_for_web: ^0.4.0 dev_dependencies: flutter_test: From f7096d7d7be9883149a1fb6cebfaa6ff85fb01a5 Mon Sep 17 00:00:00 2001 From: Ian Hickson Date: Fri, 12 Mar 2021 23:23:26 -0800 Subject: [PATCH 0271/1565] Reorder the checkboxes in the PR template (#3666) ...so that they are listed in more or less the likely order that people will do them in. --- .github/PULL_REQUEST_TEMPLATE.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 741216982d35..84b9fd214751 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -6,16 +6,16 @@ ## Pre-launch Checklist -- [ ] The title of the PR starts with the name of the plugin surrounded by square brackets, e.g. `[shared_preferences]` - [ ] 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] and the [C++, Objective-C, Java style guides]. +- [ ] I signed the [CLA]. +- [ ] The title of the PR starts with the name of the plugin surrounded by square brackets, e.g. `[shared_preferences]` - [ ] I listed at least one issue that this PR fixes in the description above. -- [ ] I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test exempt. - [ ] I updated pubspec.yaml with an appropriate new version according to the [pub versioning philosophy]. - [ ] I updated CHANGELOG.md to add a description of the change. - [ ] I updated/added relevant documentation (doc comments with `///`). -- [ ] I signed the [CLA]. +- [ ] I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test exempt. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. From 4832a85d3b0c63afd0d1b5de46082a41ce92f70c Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Mon, 15 Mar 2021 08:12:45 -0700 Subject: [PATCH 0272/1565] [ci] Add libgcrypt to Docker image. (#3711) As recommended in https://github.com/flutter/website/pull/5466 --- .ci/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/Dockerfile b/.ci/Dockerfile index 14000e2032ed..13fd48be9c14 100644 --- a/.ci/Dockerfile +++ b/.ci/Dockerfile @@ -31,7 +31,7 @@ RUN sudo apt-get install -y xvfb libegl1-mesa # Install Linux desktop build tool requirements. RUN sudo apt-get install -y clang cmake ninja-build file pkg-config # Install necessary libraries. -RUN sudo apt-get install -y libgtk-3-dev libblkid-dev liblzma-dev +RUN sudo apt-get install -y libgtk-3-dev libblkid-dev liblzma-dev libgcrypt20-dev # Add repo for Google Chrome and install it RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add - From 8169973d8cddd87429ff3e221b13fe62793b0a1a Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Tue, 16 Mar 2021 17:50:51 -0400 Subject: [PATCH 0273/1565] Add missing licenses, and add a check (#3720) Adds a new CI check that all code files have a copyright+license block (and that it's one we are expecting to see). Fixes the ~350 files (!) that did not have them. This includes all of the files in the .../example/ directories, following the example of flutter/flutter. (This does mean some manual intervention will be needed when generating new example directories in the future, but it's one-time per example.) Also standardized some variants that used different line breaks than most of the rest of the repo (likely added since I standardized them all a while ago, but didn't add a check for at the time to enforce going forward), to simplify the checks. Fixes flutter/flutter#77114 --- .cirrus.yml | 5 + .../Application.java | 4 + .../android_alarm_manager_test.dart | 6 +- .../example/test_driver/integration_test.dart | 6 +- .../androidintent/AndroidIntentPlugin.java | 4 + .../plugins/androidintent/IntentSender.java | 4 + .../androidintent/MethodCallHandlerImpl.java | 4 + .../MethodCallHandlerImplTest.java | 4 + .../EmbeddingV1ActivityTest.java | 4 + .../MainActivityTest.java | 4 + packages/android_intent/lib/flag.dart | 4 + .../integration_test/battery_test.dart | 6 +- .../lib/enums/battery_state.dart | 4 + .../method_channel_battery.dart | 4 + .../EmbeddingV1ActivityTest.java | 4 + .../cameraexample/FlutterActivityTest.java | 4 + .../cameraexample/EmbeddingV1Activity.java | 4 + .../example/integration_test/camera_test.dart | 6 +- .../camera/example/ios/Runner/AppDelegate.h | 4 + .../camera/example/ios/Runner/AppDelegate.m | 4 + .../camera/camera/example/ios/Runner/main.m | 4 + .../example/test_driver/integration_test.dart | 6 +- .../camera/ios/Tests/CameraPluginTests.m | 4 + .../camera/test/camera_image_stream_test.dart | 4 + .../lib/src/types/image_format_group.dart | 4 + .../lib/src/utils/utils.dart | 4 + .../test/types/image_group_test.dart | 4 + .../test/utils/utils_test.dart | 4 + .../connectivityexample/ActivityTest.java | 4 + .../example/macos/Runner/AppDelegate.swift | 4 + .../macos/Runner/MainFlutterWindow.swift | 4 + .../connectivity/example/web/index.html | 3 + .../network_information_test.dart | 4 + .../src/connectivity_mocks.dart | 4 + .../connectivity_for_web/example/run_test.sh | 4 + .../example/web/index.html | 3 + .../lib/connectivity_for_web.dart | 4 + .../src/dart_html_connectivity_plugin.dart | 4 + ...k_information_api_connectivity_plugin.dart | 4 + .../lib/src/utils/connectivity_result.dart | 4 + .../test/tests_exist_elsewhere_test.dart | 4 + .../example/macos/Runner/AppDelegate.swift | 4 + .../macos/Runner/MainFlutterWindow.swift | 4 + .../lib/src/enums.dart | 4 + .../lib/src/utils.dart | 4 + .../EmbeddingV1ActivityTest.java | 4 + .../integration_test/device_info_test.dart | 6 +- .../example/test_driver/integration_test.dart | 6 +- .../internal/jsonrpc/message/ErrorObject.java | 4 + .../com/example/espresso/EspressoPlugin.java | 4 + .../espresso_example/MainActivity.java | 4 + packages/espresso/example/lib/main.dart | 4 + .../espresso/example/test_driver/example.dart | 4 + .../example/lib/get_directory_page.dart | 4 + .../file_selector/example/lib/home_page.dart | 4 + .../file_selector/example/lib/main.dart | 4 + .../example/lib/open_image_page.dart | 4 + .../lib/open_multiple_images_page.dart | 4 + .../example/lib/open_text_page.dart | 4 + .../example/lib/save_text_page.dart | 4 + .../file_selector/example/web/index.html | 3 + .../lib/file_selector_platform_interface.dart | 4 + .../lib/src/types/types.dart | 4 + .../lib/src/web_helpers/web_helpers.dart | 4 + .../file_selector_web/example/run_test.sh | 3 + .../test/more_tests_exist_elsewhere_test.dart | 4 + .../FlutterLifecycleAdapterTest.java | 4 + .../EmbeddingV1Activity.java | 4 + ...flutter_plugin_android_lifecycle_test.dart | 6 +- .../example/lib/main.dart | 6 +- .../lib/flutter_plugin_android_lifecycle.dart | 4 + .../plugins/googlemaps/CircleBuilderTest.java | 4 + .../googlemaps/CircleControllerTest.java | 4 + .../googlemaps/PolygonBuilderTest.java | 4 + .../googlemaps/PolygonControllerTest.java | 4 + .../googlemaps/PolylineBuilderTest.java | 4 + .../googlemaps/PolylineControllerTest.java | 4 + .../googlemaps/EmbeddingV1ActivityTest.java | 4 + .../plugins/googlemaps/MainActivityTest.java | 4 + .../EmbeddingV1Activity.java | 4 + .../googlemaps/GoogleMapControllerTest.java | 4 + .../google_map_inspector.dart | 6 +- .../integration_test/google_maps_test.dart | 6 +- .../example/ios/Runner/AppDelegate.h | 4 + .../example/ios/Runner/AppDelegate.m | 4 + .../example/ios/Runner/main.m | 4 + .../example/test_driver/integration_test.dart | 6 +- .../test/tile_overlay_updates_test.dart | 4 + .../resources/icon_image_base64.dart | 4 + .../example/run_test.sh | 4 + .../test/tests_exist_elsewhere_test.dart | 4 + .../googlesignin/BackgroundTaskRunner.java | 6 +- .../plugins/googlesignin/Executors.java | 6 +- .../googlesignin/GoogleSignInPlugin.java | 6 +- .../googlesignin/GoogleSignInWrapper.java | 6 +- .../google_sign_in/example/web/index.html | 3 + .../integration_test/google_sign_in_test.dart | 4 + .../ios/Classes/FLTGoogleSignInPlugin.h | 6 +- .../ios/Classes/FLTGoogleSignInPlugin.m | 6 +- .../google_sign_in/lib/google_sign_in.dart | 6 +- .../google_sign_in/lib/src/common.dart | 6 +- .../google_sign_in/lib/widgets.dart | 6 +- .../test_driver/integration_test.dart | 6 +- .../google_sign_in_web/example/run_test.sh | 3 + .../test/tests_exist_elsewhere_test.dart | 4 + .../FlutterActivityTest.java | 4 + .../imagepicker/ImagePickerDelegateTest.java | 4 + .../imagepicker/ImagePickerPluginTest.java | 4 + .../test_driver/test/integration_test.dart | 6 +- .../image_picker/example/web/index.html | 3 + .../old_image_picker_test.dart | 4 + .../lib/image_picker_for_web.dart | 4 + .../lib/image_picker_platform_interface.dart | 4 + .../lib/src/types/picked_file/base.dart | 4 + .../lib/src/types/picked_file/html.dart | 4 + .../lib/src/types/picked_file/io.dart | 4 + .../src/types/picked_file/picked_file.dart | 4 + .../src/types/picked_file/unsupported.dart | 4 + .../lib/src/types/types.dart | 4 + .../plugins/inapppurchase/Translator.java | 4 +- .../inapppurchase/MethodCallHandlerTest.java | 4 + .../plugins/inapppurchase/TranslatorTest.java | 4 +- .../example/ios/Runner/AppDelegate.h | 4 + .../example/ios/Runner/AppDelegate.m | 4 + .../in_app_purchase/example/ios/Runner/main.m | 4 + .../test_driver/test/integration_test.dart | 6 +- .../in_app_purchase_test.dart | 6 +- .../purchase_wrapper.dart | 4 +- .../sku_details_wrapper.dart | 4 +- .../purchase_wrapper_test.dart | 4 +- .../sku_details_wrapper_test.dart | 4 +- .../e2e_example/EmbedderV1ActivityTest.java | 4 + .../e2e_example/FlutterActivityTest.java | 4 + .../FlutterActivityWithPermissionTest.java | 4 + .../integration_test/_example_test_io.dart | 4 + .../integration_test/_example_test_web.dart | 4 + .../integration_test/_extended_test_io.dart | 4 + .../integration_test/_extended_test_web.dart | 4 + .../integration_test/example_test.dart | 4 + .../integration_test/extended_test.dart | 4 + .../example/ios/Runner/AppDelegate.h | 4 + .../example/ios/Runner/AppDelegate.m | 4 + .../example/ios/Runner/main.m | 4 + .../example/ios/RunnerTests/RunnerTests.m | 4 + .../integration_test/example/lib/main.dart | 4 + .../integration_test/example/lib/my_app.dart | 4 + .../example/lib/my_web_app.dart | 4 + .../example/macos/Runner/AppDelegate.swift | 4 + .../macos/Runner/MainFlutterWindow.swift | 4 + .../extended_integration_test.dart | 4 + .../example/test_driver/failure_test.dart | 4 + .../example/test_driver/integration_test.dart | 4 + .../integration_test/example/web/index.html | 3 + .../ios/Classes/IntegrationTestIosTest.h | 4 + .../ios/Classes/IntegrationTestIosTest.m | 4 + .../ios/Classes/IntegrationTestPlugin.h | 4 + .../ios/Classes/IntegrationTestPlugin.m | 4 + .../lib/integration_test_driver_extended.dart | 4 + .../test/binding_fail_test.dart | 4 + .../integration_test/test/binding_test.dart | 4 + .../test/data/fail_test_script.dart | 4 + .../test/data/pass_test_script.dart | 4 + .../test/data/pass_then_fail_test_script.dart | 4 + .../test/response_serialization_test.dart | 4 + .../example/ios/Runner/AppDelegate.swift | 4 + .../ios/Runner/Runner-Bridging-Header.h | 6 +- .../ios_platform_images/example/lib/main.dart | 4 + .../example/test/widget_test.dart | 4 + .../ios/Classes/IosPlatformImagesPlugin.h | 4 + .../ios/Classes/IosPlatformImagesPlugin.m | 4 + .../localauth/EmbeddingV1ActivityTest.java | 4 + .../FlutterFragmentActivityTest.java | 4 + .../localauthexample/EmbeddingV1Activity.java | 4 + packages/local_auth/example/ios/Runner/main.m | 4 + .../integration_test/package_info_test.dart | 6 +- .../example/macos/Runner/AppDelegate.swift | 4 + .../macos/Runner/MainFlutterWindow.swift | 4 + .../example/test_driver/integration_test.dart | 6 +- .../pathprovider/StorageDirectoryMapper.java | 5 +- .../StorageDirectoryMapperTest.java | 5 +- .../java/EmbeddingV1ActivityTest.java | 3 + .../androidTest/java/MainActivityTest.java | 3 + .../EmbeddingV1Activity.java | 3 + .../integration_test/path_provider_test.dart | 6 +- .../path_provider/example/linux/main.cc | 4 + .../example/linux/my_application.cc | 4 + .../example/linux/my_application.h | 4 + .../example/macos/Runner/AppDelegate.swift | 4 + .../macos/Runner/MainFlutterWindow.swift | 4 + .../example/test_driver/integration_test.dart | 6 +- .../example/windows/runner/flutter_window.cpp | 4 + .../example/windows/runner/flutter_window.h | 4 + .../example/windows/runner/main.cpp | 4 + .../example/windows/runner/run_loop.cpp | 4 + .../example/windows/runner/run_loop.h | 4 + .../example/windows/runner/utils.cpp | 4 + .../example/windows/runner/utils.h | 4 + .../example/windows/runner/win32_window.cpp | 4 + .../example/windows/runner/win32_window.h | 4 + .../integration_test/path_provider_test.dart | 6 +- .../path_provider_linux/example/lib/main.dart | 4 + .../path_provider_linux/example/linux/main.cc | 4 + .../example/linux/my_application.cc | 4 + .../example/linux/my_application.h | 4 + .../example/test/widget_test.dart | 4 + .../example/test_driver/integration_test.dart | 6 +- .../integration_test/path_provider_test.dart | 6 +- .../example/macos/Runner/AppDelegate.swift | 4 + .../macos/Runner/MainFlutterWindow.swift | 4 + .../example/test_driver/integration_test.dart | 6 +- .../lib/src/enums.dart | 4 + .../integration_test/path_provider_test.dart | 6 +- .../example/test_driver/integration_test.dart | 6 +- .../example/windows/runner/flutter_window.cpp | 4 + .../example/windows/runner/flutter_window.h | 4 + .../example/windows/runner/main.cpp | 4 + .../example/windows/runner/run_loop.cpp | 4 + .../example/windows/runner/run_loop.h | 4 + .../example/windows/runner/utils.cpp | 4 + .../example/windows/runner/utils.h | 4 + .../example/windows/runner/win32_window.cpp | 4 + .../example/windows/runner/win32_window.h | 4 + .../integration_test/quick_actions_test.dart | 6 +- .../example/test_driver/integration_test.dart | 6 +- .../EmbeddingV1ActivityTest.java | 4 + .../sensors/example/ios/Runner/AppDelegate.h | 4 + .../sensors/example/ios/Runner/AppDelegate.m | 4 + packages/sensors/example/ios/Runner/main.m | 4 + .../test_driver/test/integration_test.dart | 6 +- .../integration_test/sensors_test.dart | 6 +- .../shareexample/EmbeddingV1ActivityTest.java | 4 + .../share/example/lib/image_previews.dart | 4 + .../test_driver/test/integration_test.dart | 6 +- .../share/integration_test/share_test.dart | 6 +- .../example/ios/Runner/AppDelegate.swift | 4 + .../ios/Runner/Runner-Bridging-Header.h | 4 + .../shared_preferences/example/linux/main.cc | 4 + .../example/linux/my_application.cc | 4 + .../example/linux/my_application.h | 4 + .../example/macos/Runner/AppDelegate.swift | 4 + .../macos/Runner/MainFlutterWindow.swift | 4 + .../example/test_driver/integration_test.dart | 6 +- .../shared_preferences/example/web/index.html | 3 + .../example/windows/runner/flutter_window.cpp | 4 + .../example/windows/runner/flutter_window.h | 4 + .../example/windows/runner/main.cpp | 4 + .../example/windows/runner/run_loop.cpp | 4 + .../example/windows/runner/run_loop.h | 4 + .../example/windows/runner/utils.cpp | 4 + .../example/windows/runner/utils.h | 4 + .../example/windows/runner/win32_window.cpp | 4 + .../example/windows/runner/win32_window.h | 4 + .../example/linux/main.cc | 4 + .../example/linux/my_application.cc | 4 + .../example/linux/my_application.h | 4 + .../example/test_driver/integration_test.dart | 6 +- .../shared_preferences_test.dart | 6 +- .../example/macos/Runner/AppDelegate.swift | 4 + .../macos/Runner/MainFlutterWindow.swift | 4 + .../example/test_driver/integration_test.dart | 6 +- .../shared_preferences_test.dart | 6 +- .../example/test_driver/integration_test.dart | 6 +- .../example/windows/runner/flutter_window.cpp | 4 + .../example/windows/runner/flutter_window.h | 4 + .../example/windows/runner/main.cpp | 4 + .../example/windows/runner/run_loop.cpp | 4 + .../example/windows/runner/run_loop.h | 4 + .../example/windows/runner/utils.cpp | 4 + .../example/windows/runner/utils.h | 4 + .../example/windows/runner/win32_window.cpp | 4 + .../example/windows/runner/win32_window.h | 4 + .../urllauncher/MethodCallHandlerImpl.java | 4 + .../plugins/urllauncher/UrlLauncher.java | 4 + .../urllauncher/UrlLauncherPlugin.java | 4 + .../plugins/urllauncher/WebViewActivity.java | 4 + .../MethodCallHandlerImplTest.java | 4 + .../EmbeddingV1ActivityTest.java | 4 + .../urllauncherexample/MainActivityTest.java | 4 + .../integration_test/url_launcher_test.dart | 6 +- .../url_launcher/example/linux/main.cc | 4 + .../example/linux/my_application.cc | 4 + .../example/linux/my_application.h | 4 + .../example/macos/Runner/AppDelegate.swift | 4 + .../macos/Runner/MainFlutterWindow.swift | 4 + .../example/test_driver/integration_test.dart | 6 +- .../url_launcher/example/web/index.html | 3 + .../example/windows/runner/flutter_window.cpp | 4 + .../example/windows/runner/flutter_window.h | 4 + .../example/windows/runner/main.cpp | 4 + .../example/windows/runner/run_loop.cpp | 4 + .../example/windows/runner/run_loop.h | 4 + .../example/windows/runner/utils.cpp | 4 + .../example/windows/runner/utils.h | 4 + .../example/windows/runner/win32_window.cpp | 4 + .../example/windows/runner/win32_window.h | 4 + .../integration_test/url_launcher_test.dart | 6 +- .../url_launcher_linux/example/linux/main.cc | 4 + .../example/linux/my_application.cc | 4 + .../example/linux/my_application.h | 4 + .../example/test_driver/integration_test.dart | 6 +- .../lib/url_launcher_linux.dart | 3 - .../integration_test/url_launcher_test.dart | 6 +- .../example/macos/Runner/AppDelegate.swift | 4 + .../macos/Runner/MainFlutterWindow.swift | 4 + .../example/test_driver/integration_test.dart | 6 +- .../lib/url_launcher_macos.dart | 3 - .../url_launcher_web_test.mocks.dart | 4 + .../url_launcher_web/example/run_test.sh | 4 + .../test/tests_exist_elsewhere_test.dart | 4 + .../integration_test/url_launcher_test.dart | 6 +- .../example/test_driver/integration_test.dart | 6 +- .../example/windows/runner/flutter_window.cpp | 4 + .../example/windows/runner/flutter_window.h | 4 + .../example/windows/runner/main.cpp | 4 + .../example/windows/runner/run_loop.cpp | 4 + .../example/windows/runner/run_loop.h | 4 + .../example/windows/runner/utils.cpp | 4 + .../example/windows/runner/utils.h | 4 + .../example/windows/runner/win32_window.cpp | 4 + .../example/windows/runner/win32_window.h | 4 + .../lib/url_launcher_windows.dart | 3 - .../videoplayer/CustomSSLSocketFactory.java | 4 + .../flutter/plugins/videoplayer/Messages.java | 4 + .../plugins/videoplayer/VideoPlayer.java | 4 + .../videoplayer/VideoPlayerOptions.java | 4 + .../FlutterActivityTest.java | 4 + .../integration_test/video_player_test.dart | 6 +- .../example/test_driver/integration_test.dart | 6 +- .../example/test_driver/video_player.dart | 6 +- .../test_driver/video_player_test.dart | 6 +- .../video_player/example/web/index.html | 3 + .../video_player/ios/Classes/messages.h | 4 + .../video_player/ios/Classes/messages.m | 4 + .../video_player/pigeons/messages.dart | 4 + .../lib/messages.dart | 4 + .../lib/test.dart | 4 + .../lib/video_player_web.dart | 4 + .../webviewflutter/DisplayListenerProxy.java | 4 + .../EmbeddingV1ActivityTest.java | 4 + .../MainActivityTest.java | 4 + .../webview_flutter_test.dart | 6 +- .../example/test_driver/integration_test.dart | 6 +- .../MainActivity.java | 4 + .../example/ios/Runner/AppDelegate.h | 4 + .../example/ios/Runner/AppDelegate.m | 4 + .../example/ios/Runner/main.m | 4 + script/build_all_plugins_app.sh | 3 + script/check_publish.sh | 4 + script/common.sh | 3 + script/incremental_build.sh | 4 + .../tool/lib/src/license_check_command.dart | 209 ++++++++++++ script/tool/lib/src/main.dart | 2 + .../tool/lib/src/publish_plugin_command.dart | 4 + script/tool/test/analyze_command_test.dart | 4 + .../test/build_examples_command_test.dart | 4 + script/tool/test/common_test.dart | 4 + .../test/drive_examples_command_test.dart | 4 + script/tool/test/firebase_test_lab_test.dart | 4 + .../tool/test/license_check_command_test.dart | 306 ++++++++++++++++++ .../tool/test/lint_podspecs_command_test.dart | 4 + script/tool/test/list_command_test.dart | 4 + script/tool/test/mocks.dart | 4 + .../test/publish_plugin_command_test.dart | 4 + script/tool/test/test_command_test.dart | 4 + script/tool/test/util.dart | 4 + script/tool/test/version_check_test.dart | 4 + 366 files changed, 1870 insertions(+), 207 deletions(-) delete mode 100644 packages/url_launcher/url_launcher_linux/lib/url_launcher_linux.dart delete mode 100644 packages/url_launcher/url_launcher_macos/lib/url_launcher_macos.dart delete mode 100644 packages/url_launcher/url_launcher_windows/lib/url_launcher_windows.dart create mode 100644 script/tool/lib/src/license_check_command.dart create mode 100644 script/tool/test/license_check_command_test.dart diff --git a/.cirrus.yml b/.cirrus.yml index 67669d783192..26264b3fb926 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -50,6 +50,11 @@ task: - ./script/check_publish.sh - name: format format_script: ./script/incremental_build.sh format --fail-on-change + license_script: + - cd script/tool + - pub get + - cd ../.. + - dart script/tool/lib/src/main.dart license-check - name: test env: matrix: diff --git a/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/Application.java b/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/Application.java index 55b789bcb6a4..e2b3e8aae73d 100644 --- a/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/Application.java +++ b/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/Application.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.androidalarmmanagerexample; import io.flutter.app.FlutterApplication; diff --git a/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart b/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart index 4d53a5a945e6..68e35d581d89 100644 --- a/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart +++ b/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/android_alarm_manager/example/test_driver/integration_test.dart b/packages/android_alarm_manager/example/test_driver/integration_test.dart index 4e78d04fa971..a2fa9e1147e1 100644 --- a/packages/android_alarm_manager/example/test_driver/integration_test.dart +++ b/packages/android_alarm_manager/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java index 30e0915aed1f..04df4d9f7c01 100644 --- a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java +++ b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java @@ -1,3 +1,7 @@ +// 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. + package io.flutter.plugins.androidintent; import androidx.annotation.NonNull; diff --git a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/IntentSender.java b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/IntentSender.java index b1a590d79c84..0d2ff0c829e5 100644 --- a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/IntentSender.java +++ b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/IntentSender.java @@ -1,3 +1,7 @@ +// 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. + package io.flutter.plugins.androidintent; import android.app.Activity; diff --git a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/MethodCallHandlerImpl.java b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/MethodCallHandlerImpl.java index 753541bf9338..2cce443fd182 100644 --- a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/MethodCallHandlerImpl.java +++ b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/MethodCallHandlerImpl.java @@ -1,3 +1,7 @@ +// 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. + package io.flutter.plugins.androidintent; import android.content.ComponentName; diff --git a/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java b/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java index cf0a28e822d4..e36f4aab804d 100644 --- a/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java +++ b/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java @@ -1,3 +1,7 @@ +// 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. + package io.flutter.plugins.androidintent; import static org.junit.Assert.assertEquals; diff --git a/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/EmbeddingV1ActivityTest.java b/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/EmbeddingV1ActivityTest.java index 7ab0e87e7c5a..a370318927ba 100644 --- a/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/EmbeddingV1ActivityTest.java +++ b/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/EmbeddingV1ActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.androidintentexample; import androidx.test.rule.ActivityTestRule; diff --git a/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/MainActivityTest.java b/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/MainActivityTest.java index 619dbcd853e7..f7cddca2832f 100644 --- a/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/MainActivityTest.java +++ b/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/MainActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.androidintentexample; import androidx.test.rule.ActivityTestRule; diff --git a/packages/android_intent/lib/flag.dart b/packages/android_intent/lib/flag.dart index e05aa6d12666..990eed9db8fc 100644 --- a/packages/android_intent/lib/flag.dart +++ b/packages/android_intent/lib/flag.dart @@ -1,3 +1,7 @@ +// 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. + /// Special flags that can be set on an intent to control how it is handled. /// /// See diff --git a/packages/battery/battery/integration_test/battery_test.dart b/packages/battery/battery/integration_test/battery_test.dart index 2b0e26967b6c..1732380919b2 100644 --- a/packages/battery/battery/integration_test/battery_test.dart +++ b/packages/battery/battery/integration_test/battery_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/battery/battery_platform_interface/lib/enums/battery_state.dart b/packages/battery/battery_platform_interface/lib/enums/battery_state.dart index 7dd5e400faf2..2ceb35128b4b 100644 --- a/packages/battery/battery_platform_interface/lib/enums/battery_state.dart +++ b/packages/battery/battery_platform_interface/lib/enums/battery_state.dart @@ -1,3 +1,7 @@ +// 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. + /// Indicates the current battery state. enum BatteryState { /// The battery is completely full of energy. diff --git a/packages/battery/battery_platform_interface/lib/method_channel/method_channel_battery.dart b/packages/battery/battery_platform_interface/lib/method_channel/method_channel_battery.dart index 739812dc95e5..dbc561bf0e64 100644 --- a/packages/battery/battery_platform_interface/lib/method_channel/method_channel_battery.dart +++ b/packages/battery/battery_platform_interface/lib/method_channel/method_channel_battery.dart @@ -1,3 +1,7 @@ +// 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. + import 'dart:async'; import 'package:flutter/services.dart'; diff --git a/packages/camera/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/EmbeddingV1ActivityTest.java b/packages/camera/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/EmbeddingV1ActivityTest.java index 8a97e47072e9..08ae8e4274af 100644 --- a/packages/camera/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/EmbeddingV1ActivityTest.java +++ b/packages/camera/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/EmbeddingV1ActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.cameraexample; import androidx.test.rule.ActivityTestRule; diff --git a/packages/camera/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/FlutterActivityTest.java b/packages/camera/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/FlutterActivityTest.java index c90c66defc32..4f30e83a138c 100644 --- a/packages/camera/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/FlutterActivityTest.java +++ b/packages/camera/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/FlutterActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.cameraexample; import androidx.test.rule.ActivityTestRule; diff --git a/packages/camera/camera/example/android/app/src/main/java/io/flutter/plugins/cameraexample/EmbeddingV1Activity.java b/packages/camera/camera/example/android/app/src/main/java/io/flutter/plugins/cameraexample/EmbeddingV1Activity.java index a53dd6b756ad..e30d5ec7b07b 100644 --- a/packages/camera/camera/example/android/app/src/main/java/io/flutter/plugins/cameraexample/EmbeddingV1Activity.java +++ b/packages/camera/camera/example/android/app/src/main/java/io/flutter/plugins/cameraexample/EmbeddingV1Activity.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.cameraexample; import android.os.Bundle; diff --git a/packages/camera/camera/example/integration_test/camera_test.dart b/packages/camera/camera/example/integration_test/camera_test.dart index 4ff624c7d989..f30734180b20 100644 --- a/packages/camera/camera/example/integration_test/camera_test.dart +++ b/packages/camera/camera/example/integration_test/camera_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. // TODO(mvanbeusekom): Remove this once flutter_driver supports null safety. // https://github.com/flutter/flutter/issues/71379 diff --git a/packages/camera/camera/example/ios/Runner/AppDelegate.h b/packages/camera/camera/example/ios/Runner/AppDelegate.h index 36e21bbf9cf4..31fc381e7066 100644 --- a/packages/camera/camera/example/ios/Runner/AppDelegate.h +++ b/packages/camera/camera/example/ios/Runner/AppDelegate.h @@ -1,3 +1,7 @@ +// Copyright 2017 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 #import diff --git a/packages/camera/camera/example/ios/Runner/AppDelegate.m b/packages/camera/camera/example/ios/Runner/AppDelegate.m index 59a72e90be12..2147d3d605ac 100644 --- a/packages/camera/camera/example/ios/Runner/AppDelegate.m +++ b/packages/camera/camera/example/ios/Runner/AppDelegate.m @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "AppDelegate.h" #include "GeneratedPluginRegistrant.h" diff --git a/packages/camera/camera/example/ios/Runner/main.m b/packages/camera/camera/example/ios/Runner/main.m index dff6597e4513..f451b14cb751 100644 --- a/packages/camera/camera/example/ios/Runner/main.m +++ b/packages/camera/camera/example/ios/Runner/main.m @@ -1,3 +1,7 @@ +// Copyright 2017 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 #import #import "AppDelegate.h" diff --git a/packages/camera/camera/example/test_driver/integration_test.dart b/packages/camera/camera/example/test_driver/integration_test.dart index 160b48f8f72f..8a35ec06803d 100644 --- a/packages/camera/camera/example/test_driver/integration_test.dart +++ b/packages/camera/camera/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. // TODO(mvanbeusekom): Remove this once flutter_driver supports null safety. // https://github.com/flutter/flutter/issues/71379 diff --git a/packages/camera/camera/ios/Tests/CameraPluginTests.m b/packages/camera/camera/ios/Tests/CameraPluginTests.m index e5be3980bad0..8d9cbc2eb81a 100644 --- a/packages/camera/camera/ios/Tests/CameraPluginTests.m +++ b/packages/camera/camera/ios/Tests/CameraPluginTests.m @@ -1,3 +1,7 @@ +// Copyright 2019 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. + @import camera; @import XCTest; diff --git a/packages/camera/camera/test/camera_image_stream_test.dart b/packages/camera/camera/test/camera_image_stream_test.dart index 57e3aeb36f3f..41faeb1fd4b0 100644 --- a/packages/camera/camera/test/camera_image_stream_test.dart +++ b/packages/camera/camera/test/camera_image_stream_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'package:camera/camera.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/widgets.dart'; diff --git a/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart index 3d2c0180fe65..61ccbfc2638a 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + /// Group of image formats that are comparable across Android and iOS platforms. enum ImageFormatGroup { /// The image format does not fit into any specific group. diff --git a/packages/camera/camera_platform_interface/lib/src/utils/utils.dart b/packages/camera/camera_platform_interface/lib/src/utils/utils.dart index 5413f25bb8b7..f4c21bfca6cc 100644 --- a/packages/camera/camera_platform_interface/lib/src/utils/utils.dart +++ b/packages/camera/camera_platform_interface/lib/src/utils/utils.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/services.dart'; diff --git a/packages/camera/camera_platform_interface/test/types/image_group_test.dart b/packages/camera/camera_platform_interface/test/types/image_group_test.dart index c49b2f03a7a0..ac975fa6e6ce 100644 --- a/packages/camera/camera_platform_interface/test/types/image_group_test.dart +++ b/packages/camera/camera_platform_interface/test/types/image_group_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'package:camera_platform_interface/src/types/types.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/camera/camera_platform_interface/test/utils/utils_test.dart b/packages/camera/camera_platform_interface/test/utils/utils_test.dart index 63e3baff265d..822798160439 100644 --- a/packages/camera/camera_platform_interface/test/utils/utils_test.dart +++ b/packages/camera/camera_platform_interface/test/utils/utils_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:camera_platform_interface/src/utils/utils.dart'; import 'package:flutter/services.dart'; diff --git a/packages/connectivity/connectivity/example/android/app/src/test/java/io/flutter/plugins/connectivityexample/ActivityTest.java b/packages/connectivity/connectivity/example/android/app/src/test/java/io/flutter/plugins/connectivityexample/ActivityTest.java index f8f4247a7ef5..b531a2db2897 100644 --- a/packages/connectivity/connectivity/example/android/app/src/test/java/io/flutter/plugins/connectivityexample/ActivityTest.java +++ b/packages/connectivity/connectivity/example/android/app/src/test/java/io/flutter/plugins/connectivityexample/ActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.connectivityexample; import static org.junit.Assert.assertNotNull; diff --git a/packages/connectivity/connectivity/example/macos/Runner/AppDelegate.swift b/packages/connectivity/connectivity/example/macos/Runner/AppDelegate.swift index d53ef6437726..ca19fe95f8cf 100644 --- a/packages/connectivity/connectivity/example/macos/Runner/AppDelegate.swift +++ b/packages/connectivity/connectivity/example/macos/Runner/AppDelegate.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/connectivity/connectivity/example/macos/Runner/MainFlutterWindow.swift b/packages/connectivity/connectivity/example/macos/Runner/MainFlutterWindow.swift index 2722837ec918..2ce11b78604b 100644 --- a/packages/connectivity/connectivity/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/connectivity/connectivity/example/macos/Runner/MainFlutterWindow.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/connectivity/connectivity/example/web/index.html b/packages/connectivity/connectivity/example/web/index.html index 9b7a438f823a..97b1100c4244 100644 --- a/packages/connectivity/connectivity/example/web/index.html +++ b/packages/connectivity/connectivity/example/web/index.html @@ -1,4 +1,7 @@ + diff --git a/packages/connectivity/connectivity_for_web/example/integration_test/network_information_test.dart b/packages/connectivity/connectivity_for_web/example/integration_test/network_information_test.dart index f8e8059e7dba..1f4a1d5d8f60 100644 --- a/packages/connectivity/connectivity_for_web/example/integration_test/network_information_test.dart +++ b/packages/connectivity/connectivity_for_web/example/integration_test/network_information_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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:connectivity_for_web/src/network_information_api_connectivity_plugin.dart'; import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart b/packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart index fc795595e3f3..390a66556d10 100644 --- a/packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart +++ b/packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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:html'; import 'dart:js_util' show getProperty; diff --git a/packages/connectivity/connectivity_for_web/example/run_test.sh b/packages/connectivity/connectivity_for_web/example/run_test.sh index 8e6f149358c9..9bfce94f63b2 100755 --- a/packages/connectivity/connectivity_for_web/example/run_test.sh +++ b/packages/connectivity/connectivity_for_web/example/run_test.sh @@ -1,4 +1,8 @@ #!/usr/bin/bash +# Copyright 2017 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. + if pgrep -lf chromedriver > /dev/null; then echo "chromedriver is running." diff --git a/packages/connectivity/connectivity_for_web/example/web/index.html b/packages/connectivity/connectivity_for_web/example/web/index.html index 6eff9a740d43..27464c33811a 100644 --- a/packages/connectivity/connectivity_for_web/example/web/index.html +++ b/packages/connectivity/connectivity_for_web/example/web/index.html @@ -1,4 +1,7 @@ + diff --git a/packages/connectivity/connectivity_for_web/lib/connectivity_for_web.dart b/packages/connectivity/connectivity_for_web/lib/connectivity_for_web.dart index fd061a878867..14de31db1125 100644 --- a/packages/connectivity/connectivity_for_web/lib/connectivity_for_web.dart +++ b/packages/connectivity/connectivity_for_web/lib/connectivity_for_web.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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:connectivity_platform_interface/connectivity_platform_interface.dart'; diff --git a/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart b/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart index 950d26804371..09fbeaf7fd0d 100644 --- a/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart +++ b/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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:html' as html show window; diff --git a/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart b/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart index 800be2ef238f..2b319b1fb5ab 100644 --- a/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart +++ b/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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:html' as html show window, NetworkInformation; import 'dart:js' show allowInterop; diff --git a/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart b/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart index e7eb8969231a..9f1b111eccd3 100644 --- a/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart +++ b/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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:html' as html show NetworkInformation; import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; diff --git a/packages/connectivity/connectivity_for_web/test/tests_exist_elsewhere_test.dart b/packages/connectivity/connectivity_for_web/test/tests_exist_elsewhere_test.dart index 334f52186d9d..64d8e547e485 100644 --- a/packages/connectivity/connectivity_for_web/test/tests_exist_elsewhere_test.dart +++ b/packages/connectivity/connectivity_for_web/test/tests_exist_elsewhere_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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_test/flutter_test.dart'; void main() { diff --git a/packages/connectivity/connectivity_macos/example/macos/Runner/AppDelegate.swift b/packages/connectivity/connectivity_macos/example/macos/Runner/AppDelegate.swift index d53ef6437726..ca19fe95f8cf 100644 --- a/packages/connectivity/connectivity_macos/example/macos/Runner/AppDelegate.swift +++ b/packages/connectivity/connectivity_macos/example/macos/Runner/AppDelegate.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/connectivity/connectivity_macos/example/macos/Runner/MainFlutterWindow.swift b/packages/connectivity/connectivity_macos/example/macos/Runner/MainFlutterWindow.swift index 2722837ec918..2ce11b78604b 100644 --- a/packages/connectivity/connectivity_macos/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/connectivity/connectivity_macos/example/macos/Runner/MainFlutterWindow.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart b/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart index 9d8cef9e1a66..640e378de0ce 100644 --- a/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart +++ b/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart @@ -1,3 +1,7 @@ +// Copyright 2020 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. + /// Connection status check result. enum ConnectivityResult { /// WiFi: Device connected via Wi-Fi diff --git a/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart b/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart index 2ae22e1c9fc3..4df92974ba0c 100644 --- a/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart +++ b/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart @@ -1,3 +1,7 @@ +// Copyright 2020 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. + import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; /// Convert a String to a ConnectivityResult value. diff --git a/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1ActivityTest.java b/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1ActivityTest.java index 8fa880842d51..ca680684e3ea 100644 --- a/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1ActivityTest.java +++ b/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1ActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.deviceinfoexample; import androidx.test.rule.ActivityTestRule; diff --git a/packages/device_info/device_info/example/integration_test/device_info_test.dart b/packages/device_info/device_info/example/integration_test/device_info_test.dart index 61c4396b0d8e..a2a3ba7733ce 100644 --- a/packages/device_info/device_info/example/integration_test/device_info_test.dart +++ b/packages/device_info/device_info/example/integration_test/device_info_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. // TODO(cyanglaz): Remove once https://github.com/flutter/plugins/pull/3158 is landed. // @dart = 2.9 diff --git a/packages/device_info/device_info/example/test_driver/integration_test.dart b/packages/device_info/device_info/example/test_driver/integration_test.dart index 13327bb884c9..84004cebd1a6 100644 --- a/packages/device_info/device_info/example/test_driver/integration_test.dart +++ b/packages/device_info/device_info/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. // TODO(cyanglaz): Remove once https://github.com/flutter/flutter/issues/59879 is fixed. // @dart = 2.9 diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/ErrorObject.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/ErrorObject.java index af5c68e574aa..d7779d3e5ec7 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/ErrorObject.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/ErrorObject.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package androidx.test.espresso.flutter.internal.jsonrpc.message; import com.google.gson.JsonObject; diff --git a/packages/espresso/android/src/main/java/com/example/espresso/EspressoPlugin.java b/packages/espresso/android/src/main/java/com/example/espresso/EspressoPlugin.java index e1b1e3ac86db..634b5fe53ad7 100644 --- a/packages/espresso/android/src/main/java/com/example/espresso/EspressoPlugin.java +++ b/packages/espresso/android/src/main/java/com/example/espresso/EspressoPlugin.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package com.example.espresso; import androidx.annotation.NonNull; diff --git a/packages/espresso/example/android/app/src/main/java/com/example/espresso_example/MainActivity.java b/packages/espresso/example/android/app/src/main/java/com/example/espresso_example/MainActivity.java index 413ef9e50448..ff62ed2521d5 100644 --- a/packages/espresso/example/android/app/src/main/java/com/example/espresso_example/MainActivity.java +++ b/packages/espresso/example/android/app/src/main/java/com/example/espresso_example/MainActivity.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package com.example.espresso_example; import androidx.annotation.NonNull; diff --git a/packages/espresso/example/lib/main.dart b/packages/espresso/example/lib/main.dart index 958d26a0c149..2ab6632113d5 100644 --- a/packages/espresso/example/lib/main.dart +++ b/packages/espresso/example/lib/main.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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/material.dart'; void main() => runApp(MyApp()); diff --git a/packages/espresso/example/test_driver/example.dart b/packages/espresso/example/test_driver/example.dart index ab74ff550930..42acdeb61a2c 100644 --- a/packages/espresso/example/test_driver/example.dart +++ b/packages/espresso/example/test_driver/example.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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_driver/driver_extension.dart'; import 'package:espresso_example/main.dart' as app; diff --git a/packages/file_selector/file_selector/example/lib/get_directory_page.dart b/packages/file_selector/file_selector/example/lib/get_directory_page.dart index cf4cde9fa9a8..be278f374fa8 100644 --- a/packages/file_selector/file_selector/example/lib/get_directory_page.dart +++ b/packages/file_selector/file_selector/example/lib/get_directory_page.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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:file_selector/file_selector.dart'; import 'package:flutter/material.dart'; diff --git a/packages/file_selector/file_selector/example/lib/home_page.dart b/packages/file_selector/file_selector/example/lib/home_page.dart index 1cb7ef261e88..842094c9acaa 100644 --- a/packages/file_selector/file_selector/example/lib/home_page.dart +++ b/packages/file_selector/file_selector/example/lib/home_page.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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/material.dart'; /// Home Page of the application diff --git a/packages/file_selector/file_selector/example/lib/main.dart b/packages/file_selector/file_selector/example/lib/main.dart index bb34918e36a3..e355109d1799 100644 --- a/packages/file_selector/file_selector/example/lib/main.dart +++ b/packages/file_selector/file_selector/example/lib/main.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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/material.dart'; import 'package:example/home_page.dart'; import 'package:example/get_directory_page.dart'; diff --git a/packages/file_selector/file_selector/example/lib/open_image_page.dart b/packages/file_selector/file_selector/example/lib/open_image_page.dart index 986bfe712893..da11ead1c09f 100644 --- a/packages/file_selector/file_selector/example/lib/open_image_page.dart +++ b/packages/file_selector/file_selector/example/lib/open_image_page.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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:io'; import 'package:flutter/foundation.dart'; import 'package:file_selector/file_selector.dart'; diff --git a/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart b/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart index c6f73f5aed12..d91d126c940f 100644 --- a/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart +++ b/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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:io'; import 'package:flutter/foundation.dart'; import 'package:file_selector/file_selector.dart'; diff --git a/packages/file_selector/file_selector/example/lib/open_text_page.dart b/packages/file_selector/file_selector/example/lib/open_text_page.dart index 74d79dd72b19..52296abd4379 100644 --- a/packages/file_selector/file_selector/example/lib/open_text_page.dart +++ b/packages/file_selector/file_selector/example/lib/open_text_page.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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:file_selector/file_selector.dart'; import 'package:flutter/material.dart'; diff --git a/packages/file_selector/file_selector/example/lib/save_text_page.dart b/packages/file_selector/file_selector/example/lib/save_text_page.dart index 82046c35128a..982692bc40f8 100644 --- a/packages/file_selector/file_selector/example/lib/save_text_page.dart +++ b/packages/file_selector/file_selector/example/lib/save_text_page.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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:typed_data'; import 'package:file_selector/file_selector.dart'; import 'package:flutter/material.dart'; diff --git a/packages/file_selector/file_selector/example/web/index.html b/packages/file_selector/file_selector/example/web/index.html index 9b7a438f823a..97b1100c4244 100644 --- a/packages/file_selector/file_selector/example/web/index.html +++ b/packages/file_selector/file_selector/example/web/index.html @@ -1,4 +1,7 @@ + diff --git a/packages/file_selector/file_selector_platform_interface/lib/file_selector_platform_interface.dart b/packages/file_selector/file_selector_platform_interface/lib/file_selector_platform_interface.dart index 69e3064150b5..dcd87aaed4a7 100644 --- a/packages/file_selector/file_selector_platform_interface/lib/file_selector_platform_interface.dart +++ b/packages/file_selector/file_selector_platform_interface/lib/file_selector_platform_interface.dart @@ -1,2 +1,6 @@ +// 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. + export 'src/platform_interface/file_selector_interface.dart'; export 'src/types/types.dart'; diff --git a/packages/file_selector/file_selector_platform_interface/lib/src/types/types.dart b/packages/file_selector/file_selector_platform_interface/lib/src/types/types.dart index 88dc3c2a5f83..65a0bdcd1583 100644 --- a/packages/file_selector/file_selector_platform_interface/lib/src/types/types.dart +++ b/packages/file_selector/file_selector_platform_interface/lib/src/types/types.dart @@ -1,2 +1,6 @@ +// 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. + export 'package:cross_file/cross_file.dart'; export 'x_type_group/x_type_group.dart'; diff --git a/packages/file_selector/file_selector_platform_interface/lib/src/web_helpers/web_helpers.dart b/packages/file_selector/file_selector_platform_interface/lib/src/web_helpers/web_helpers.dart index 5330c5cf6dcd..f9e33aed1389 100644 --- a/packages/file_selector/file_selector_platform_interface/lib/src/web_helpers/web_helpers.dart +++ b/packages/file_selector/file_selector_platform_interface/lib/src/web_helpers/web_helpers.dart @@ -1,3 +1,7 @@ +// 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 'dart:html'; /// Create anchor element with download attribute diff --git a/packages/file_selector/file_selector_web/example/run_test.sh b/packages/file_selector/file_selector_web/example/run_test.sh index c9f547a4f7d7..a381127c2716 100755 --- a/packages/file_selector/file_selector_web/example/run_test.sh +++ b/packages/file_selector/file_selector_web/example/run_test.sh @@ -1,4 +1,7 @@ #!/usr/bin/bash +# Copyright 2017 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. if pgrep -lf chromedriver > /dev/null; then echo "chromedriver is running." diff --git a/packages/file_selector/file_selector_web/test/more_tests_exist_elsewhere_test.dart b/packages/file_selector/file_selector_web/test/more_tests_exist_elsewhere_test.dart index e9faa3af4808..6aaf4475d537 100644 --- a/packages/file_selector/file_selector_web/test/more_tests_exist_elsewhere_test.dart +++ b/packages/file_selector/file_selector_web/test/more_tests_exist_elsewhere_test.dart @@ -1,3 +1,7 @@ +// 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_test/flutter_test.dart'; void main() { diff --git a/packages/flutter_plugin_android_lifecycle/android/src/test/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapterTest.java b/packages/flutter_plugin_android_lifecycle/android/src/test/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapterTest.java index 2a5a91d02f60..6657dfbb5a71 100644 --- a/packages/flutter_plugin_android_lifecycle/android/src/test/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapterTest.java +++ b/packages/flutter_plugin_android_lifecycle/android/src/test/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapterTest.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.embedding.engine.plugins.lifecycle; import static org.junit.Assert.assertEquals; diff --git a/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/EmbeddingV1Activity.java b/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/EmbeddingV1Activity.java index f303f4c61d20..5859e177b2fc 100644 --- a/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/EmbeddingV1Activity.java +++ b/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/EmbeddingV1Activity.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.flutter_plugin_android_lifecycle_example; import android.os.Bundle; 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 ba67043bcf43..e4b92c8db7ed 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 @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/flutter_plugin_android_lifecycle/example/lib/main.dart b/packages/flutter_plugin_android_lifecycle/example/lib/main.dart index eb82aacd0237..c055c5359515 100644 --- a/packages/flutter_plugin_android_lifecycle/example/lib/main.dart +++ b/packages/flutter_plugin_android_lifecycle/example/lib/main.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project authors. 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 diff --git a/packages/flutter_plugin_android_lifecycle/lib/flutter_plugin_android_lifecycle.dart b/packages/flutter_plugin_android_lifecycle/lib/flutter_plugin_android_lifecycle.dart index 4352552e3eda..ea111552567d 100644 --- a/packages/flutter_plugin_android_lifecycle/lib/flutter_plugin_android_lifecycle.dart +++ b/packages/flutter_plugin_android_lifecycle/lib/flutter_plugin_android_lifecycle.dart @@ -1,2 +1,6 @@ +// Copyright 2019 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. + // The flutter_plugin_android_lifecycle plugin only provides a Java API // for use by Android plugins. This plugin has no Dart code. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleBuilderTest.java b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleBuilderTest.java index 6585090e6e26..24bee4ea7550 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleBuilderTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleBuilderTest.java @@ -1,3 +1,7 @@ +// Copyright 2018 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. + package io.flutter.plugins.googlemaps; import static junit.framework.TestCase.assertEquals; diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleControllerTest.java b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleControllerTest.java index e032dd436d5a..7c8032b2b0d4 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleControllerTest.java @@ -1,3 +1,7 @@ +// Copyright 2018 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. + package io.flutter.plugins.googlemaps; import static org.mockito.Mockito.mock; diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonBuilderTest.java b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonBuilderTest.java index 644e8982f246..e3c2f339f250 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonBuilderTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonBuilderTest.java @@ -1,3 +1,7 @@ +// Copyright 2018 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. + package io.flutter.plugins.googlemaps; import static junit.framework.TestCase.assertEquals; diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonControllerTest.java b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonControllerTest.java index 834c42766e07..e65cb1f22dc9 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonControllerTest.java @@ -1,3 +1,7 @@ +// Copyright 2018 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. + package io.flutter.plugins.googlemaps; import static org.mockito.Mockito.mock; diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineBuilderTest.java b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineBuilderTest.java index bf6d06066fbf..7e5d39c380fd 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineBuilderTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineBuilderTest.java @@ -1,3 +1,7 @@ +// Copyright 2018 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. + package io.flutter.plugins.googlemaps; import static junit.framework.TestCase.assertEquals; diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineControllerTest.java b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineControllerTest.java index acd231623825..1f0a7000f5e7 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineControllerTest.java @@ -1,3 +1,7 @@ +// Copyright 2018 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. + package io.flutter.plugins.googlemaps; import static org.mockito.Mockito.mock; diff --git a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/EmbeddingV1ActivityTest.java b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/EmbeddingV1ActivityTest.java index 76dc5df3422a..5ade4367835a 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/EmbeddingV1ActivityTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/EmbeddingV1ActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.googlemaps; import androidx.test.rule.ActivityTestRule; diff --git a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/MainActivityTest.java b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/MainActivityTest.java index c70f16a17454..7c624bb556a9 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/MainActivityTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/MainActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.googlemaps; import androidx.test.rule.ActivityTestRule; diff --git a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/main/java/io/flutter/plugins/googlemapsexample/EmbeddingV1Activity.java b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/main/java/io/flutter/plugins/googlemapsexample/EmbeddingV1Activity.java index 3853b5d2d4df..9924fa03e3aa 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/main/java/io/flutter/plugins/googlemapsexample/EmbeddingV1Activity.java +++ b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/main/java/io/flutter/plugins/googlemapsexample/EmbeddingV1Activity.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.googlemapsexample; import android.os.Bundle; diff --git a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java index 94b93473a5e1..7b81f287a9d1 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.googlemaps; import static org.junit.Assert.assertNull; diff --git a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart index a5025590d72a..33ad5d03778e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 'dart:typed_data'; diff --git a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart index 01b0c9b03e68..44412d490ec0 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 'dart:async'; diff --git a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/AppDelegate.h b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/AppDelegate.h index 5abb821e75eb..8e973d51585b 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/AppDelegate.h +++ b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/AppDelegate.h @@ -1,3 +1,7 @@ +// Copyright 2017 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 #import diff --git a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/AppDelegate.m b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/AppDelegate.m index 6896c5c190b1..b22c283d4704 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/AppDelegate.m +++ b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/AppDelegate.m @@ -1,3 +1,7 @@ +// Copyright 2017 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 "AppDelegate.h" #import "GeneratedPluginRegistrant.h" diff --git a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/main.m b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/main.m index dff6597e4513..f451b14cb751 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/main.m +++ b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/main.m @@ -1,3 +1,7 @@ +// Copyright 2017 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 #import #import "AppDelegate.h" diff --git a/packages/google_maps_flutter/google_maps_flutter/example/test_driver/integration_test.dart b/packages/google_maps_flutter/google_maps_flutter/example/test_driver/integration_test.dart index ceb6c4d6a3a0..7a26a52ae1a1 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/test_driver/integration_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 'dart:async'; diff --git a/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart index d2b6efb69e66..953d85ec85e6 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart @@ -1,3 +1,7 @@ +// Copyright 2018 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. + import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/resources/icon_image_base64.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/resources/icon_image_base64.dart index aa4a80baddbb..66814d8df7ca 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/resources/icon_image_base64.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/resources/icon_image_base64.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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. + final iconImageBase64 = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAIRlWElmTU' '0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIA' diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh b/packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh index 8e6f149358c9..9bfce94f63b2 100755 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh @@ -1,4 +1,8 @@ #!/usr/bin/bash +# Copyright 2017 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. + if pgrep -lf chromedriver > /dev/null; then echo "chromedriver is running." diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/tests_exist_elsewhere_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/tests_exist_elsewhere_test.dart index 334f52186d9d..a8cd22dbe285 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/test/tests_exist_elsewhere_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/tests_exist_elsewhere_test.dart @@ -1,3 +1,7 @@ +// 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. + import 'package:flutter_test/flutter_test.dart'; void main() { diff --git a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/BackgroundTaskRunner.java b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/BackgroundTaskRunner.java index e05130178ec4..e667be2aa0f9 100755 --- a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/BackgroundTaskRunner.java +++ b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/BackgroundTaskRunner.java @@ -1,6 +1,6 @@ -// Copyright 2017, the Flutter 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. +// Copyright 2017, the Flutter project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. package io.flutter.plugins.googlesignin; diff --git a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/Executors.java b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/Executors.java index ee4273873d8d..80b9d187d939 100755 --- a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/Executors.java +++ b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/Executors.java @@ -1,6 +1,6 @@ -// Copyright 2017, the Flutter 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. +// Copyright 2017, the Flutter project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. package io.flutter.plugins.googlesignin; diff --git a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java index dab6f4c4db8e..f6673e5d5978 100755 --- a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java +++ b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java @@ -1,6 +1,6 @@ -// Copyright 2017, the Flutter 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. +// Copyright 2017, the Flutter project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. package io.flutter.plugins.googlesignin; diff --git a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInWrapper.java b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInWrapper.java index 985903f1853c..100069080bb4 100644 --- a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInWrapper.java +++ b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInWrapper.java @@ -1,6 +1,6 @@ -// Copyright 2020, the Flutter 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. +// Copyright 2020, the Flutter project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. package io.flutter.plugins.googlesignin; diff --git a/packages/google_sign_in/google_sign_in/example/web/index.html b/packages/google_sign_in/google_sign_in/example/web/index.html index bd373458a2f1..187eeb5ff8ff 100644 --- a/packages/google_sign_in/google_sign_in/example/web/index.html +++ b/packages/google_sign_in/google_sign_in/example/web/index.html @@ -1,4 +1,7 @@ + diff --git a/packages/google_sign_in/google_sign_in/integration_test/google_sign_in_test.dart b/packages/google_sign_in/google_sign_in/integration_test/google_sign_in_test.dart index a900bfbfdc2e..86423507fffc 100644 --- a/packages/google_sign_in/google_sign_in/integration_test/google_sign_in_test.dart +++ b/packages/google_sign_in/google_sign_in/integration_test/google_sign_in_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Flutter project 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:integration_test/integration_test.dart'; diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.h b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.h index 9474e371e176..f9d7f322a2e3 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.h +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.h @@ -1,6 +1,6 @@ -// Copyright 2017, the Flutter 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. +// Copyright 2017, the Flutter project 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 diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m index f621d1e68312..660a32272f84 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m @@ -1,6 +1,6 @@ -// Copyright 2017, the Flutter 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. +// Copyright 2017, the Flutter project 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 "FLTGoogleSignInPlugin.h" #import diff --git a/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart b/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart index 1317eb91ecfb..f803f96f85ed 100644 --- a/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart +++ b/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart @@ -1,6 +1,6 @@ -// Copyright 2017, the Flutter 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. +// Copyright 2017, the Flutter project 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' show hashValues; diff --git a/packages/google_sign_in/google_sign_in/lib/src/common.dart b/packages/google_sign_in/google_sign_in/lib/src/common.dart index 60c74ab4c6d5..f9aaf199b899 100644 --- a/packages/google_sign_in/google_sign_in/lib/src/common.dart +++ b/packages/google_sign_in/google_sign_in/lib/src/common.dart @@ -1,6 +1,6 @@ -// Copyright 2017, the Flutter 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. +// Copyright 2017, the Flutter project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. /// Encapsulation of the fields that represent a Google user's identity. abstract class GoogleIdentity { diff --git a/packages/google_sign_in/google_sign_in/lib/widgets.dart b/packages/google_sign_in/google_sign_in/lib/widgets.dart index c9682930b089..f47e78fde2b2 100644 --- a/packages/google_sign_in/google_sign_in/lib/widgets.dart +++ b/packages/google_sign_in/google_sign_in/lib/widgets.dart @@ -1,6 +1,6 @@ -// Copyright 2017, the Flutter 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. +// Copyright 2017, the Flutter project 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:typed_data'; diff --git a/packages/google_sign_in/google_sign_in/test_driver/integration_test.dart b/packages/google_sign_in/google_sign_in/test_driver/integration_test.dart index 4a27ac2f986b..abb86f07086a 100644 --- a/packages/google_sign_in/google_sign_in/test_driver/integration_test.dart +++ b/packages/google_sign_in/google_sign_in/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// Copyright 2020, 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. +// Copyright 2020, the Chromium project 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 diff --git a/packages/google_sign_in/google_sign_in_web/example/run_test.sh b/packages/google_sign_in/google_sign_in_web/example/run_test.sh index 0f76f4a47e16..d6b5dbb18ae9 100755 --- a/packages/google_sign_in/google_sign_in_web/example/run_test.sh +++ b/packages/google_sign_in/google_sign_in_web/example/run_test.sh @@ -1,4 +1,7 @@ #!/usr/bin/bash +# Copyright 2017 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. if pgrep -lf chromedriver > /dev/null; then echo "chromedriver is running." diff --git a/packages/google_sign_in/google_sign_in_web/test/tests_exist_elsewhere_test.dart b/packages/google_sign_in/google_sign_in_web/test/tests_exist_elsewhere_test.dart index 334f52186d9d..d6a165667707 100644 --- a/packages/google_sign_in/google_sign_in_web/test/tests_exist_elsewhere_test.dart +++ b/packages/google_sign_in/google_sign_in_web/test/tests_exist_elsewhere_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019, the Flutter project 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_test/flutter_test.dart'; void main() { diff --git a/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/FlutterActivityTest.java b/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/FlutterActivityTest.java index 58f8df35dc4f..cfe112e39cb2 100644 --- a/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/FlutterActivityTest.java +++ b/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/FlutterActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.imagepickerexample; import androidx.test.rule.ActivityTestRule; diff --git a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java index aa9b00521f53..858d929dbc5d 100644 --- a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java +++ b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.imagepicker; import static org.hamcrest.core.IsEqual.equalTo; diff --git a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerPluginTest.java b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerPluginTest.java index de1623e93db4..27bc57bd2dcd 100644 --- a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerPluginTest.java +++ b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerPluginTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.imagepicker; import static org.junit.Assert.assertTrue; diff --git a/packages/image_picker/image_picker/example/test_driver/test/integration_test.dart b/packages/image_picker/image_picker/example/test_driver/test/integration_test.dart index 0352d4aaeb2d..6332de2cfd8d 100644 --- a/packages/image_picker/image_picker/example/test_driver/test/integration_test.dart +++ b/packages/image_picker/image_picker/example/test_driver/test/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 'dart:async'; diff --git a/packages/image_picker/image_picker/example/web/index.html b/packages/image_picker/image_picker/example/web/index.html index 787bbc72f6b1..a692cdb87e02 100644 --- a/packages/image_picker/image_picker/example/web/index.html +++ b/packages/image_picker/image_picker/example/web/index.html @@ -1,4 +1,7 @@ + diff --git a/packages/image_picker/image_picker/integration_test/old_image_picker_test.dart b/packages/image_picker/image_picker/integration_test/old_image_picker_test.dart index 76c971c2881b..953acd1a8da3 100644 --- a/packages/image_picker/image_picker/integration_test/old_image_picker_test.dart +++ b/packages/image_picker/image_picker/integration_test/old_image_picker_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + // @dart=2.9 import 'package:integration_test/integration_test.dart'; diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index 05afd2e54a4c..ccee15066b8c 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'dart:async'; import 'dart:html' as html; diff --git a/packages/image_picker/image_picker_platform_interface/lib/image_picker_platform_interface.dart b/packages/image_picker/image_picker_platform_interface/lib/image_picker_platform_interface.dart index 6e7641324805..e46ee58e766b 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/image_picker_platform_interface.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/image_picker_platform_interface.dart @@ -1,2 +1,6 @@ +// 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. + export 'package:image_picker_platform_interface/src/platform_interface/image_picker_platform.dart'; export 'package:image_picker_platform_interface/src/types/types.dart'; diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart index 2b078ef28190..39db13951fd1 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart @@ -1,3 +1,7 @@ +// 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. + import 'dart:convert'; import 'dart:typed_data'; diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart index b855eb3fa20d..ea1ad9a84606 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart @@ -1,3 +1,7 @@ +// 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. + import 'dart:convert'; import 'dart:typed_data'; diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart index 4b56add0add4..06bc52308095 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart @@ -1,3 +1,7 @@ +// 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. + import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/picked_file.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/picked_file.dart index b2a614ccb304..125b1e968740 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/picked_file.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/picked_file.dart @@ -1,3 +1,7 @@ +// 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. + export 'lost_data.dart'; export 'unsupported.dart' if (dart.library.html) 'html.dart' diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/unsupported.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/unsupported.dart index bc10a4890c8d..e204604f5a13 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/unsupported.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/unsupported.dart @@ -1,3 +1,7 @@ +// 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. + import './base.dart'; /// A PickedFile is a cross-platform, simplified File abstraction. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart index f38a4ec74005..8ea3cfe06de6 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart @@ -1,3 +1,7 @@ +// 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. + export 'camera_device.dart'; export 'image_source.dart'; export 'retrieve_type.dart'; diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java index 73180ec5ec05..f9fc12fbb34e 100644 --- a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java +++ b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java @@ -1,6 +1,6 @@ // Copyright 2019 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. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. package io.flutter.plugins.inapppurchase; diff --git a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java index eef43346f655..374dc3297e9e 100644 --- a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java +++ b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.inapppurchase; import static io.flutter.plugins.inapppurchase.InAppPurchasePlugin.MethodNames.ACKNOWLEDGE_PURCHASE; diff --git a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java index 2ee1044fe0c5..476577d330c8 100644 --- a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java +++ b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java @@ -1,6 +1,6 @@ // Copyright 2019 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. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. package io.flutter.plugins.inapppurchase; diff --git a/packages/in_app_purchase/example/ios/Runner/AppDelegate.h b/packages/in_app_purchase/example/ios/Runner/AppDelegate.h index 36e21bbf9cf4..31fc381e7066 100644 --- a/packages/in_app_purchase/example/ios/Runner/AppDelegate.h +++ b/packages/in_app_purchase/example/ios/Runner/AppDelegate.h @@ -1,3 +1,7 @@ +// Copyright 2017 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 #import diff --git a/packages/in_app_purchase/example/ios/Runner/AppDelegate.m b/packages/in_app_purchase/example/ios/Runner/AppDelegate.m index 59a72e90be12..2147d3d605ac 100644 --- a/packages/in_app_purchase/example/ios/Runner/AppDelegate.m +++ b/packages/in_app_purchase/example/ios/Runner/AppDelegate.m @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "AppDelegate.h" #include "GeneratedPluginRegistrant.h" diff --git a/packages/in_app_purchase/example/ios/Runner/main.m b/packages/in_app_purchase/example/ios/Runner/main.m index dff6597e4513..f451b14cb751 100644 --- a/packages/in_app_purchase/example/ios/Runner/main.m +++ b/packages/in_app_purchase/example/ios/Runner/main.m @@ -1,3 +1,7 @@ +// Copyright 2017 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 #import #import "AppDelegate.h" diff --git a/packages/in_app_purchase/example/test_driver/test/integration_test.dart b/packages/in_app_purchase/example/test_driver/test/integration_test.dart index 0352d4aaeb2d..6332de2cfd8d 100644 --- a/packages/in_app_purchase/example/test_driver/test/integration_test.dart +++ b/packages/in_app_purchase/example/test_driver/test/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 'dart:async'; diff --git a/packages/in_app_purchase/integration_test/in_app_purchase_test.dart b/packages/in_app_purchase/integration_test/in_app_purchase_test.dart index aa3430fbc7d2..758d266e7f8b 100644 --- a/packages/in_app_purchase/integration_test/in_app_purchase_test.dart +++ b/packages/in_app_purchase/integration_test/in_app_purchase_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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'; diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart index 929b58292a2f..567e8bbd4f2b 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart @@ -1,6 +1,6 @@ // Copyright 2019 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. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. import 'dart:ui' show hashValues; import 'package:flutter/foundation.dart'; diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart index f93dd60284f8..7451a24a8b4f 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart @@ -1,6 +1,6 @@ // Copyright 2019 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. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. import 'dart:ui' show hashValues; import 'package:flutter/foundation.dart'; diff --git a/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart b/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart index df5b8f5bde22..f97b937c96df 100644 --- a/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart +++ b/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart @@ -1,6 +1,6 @@ // Copyright 2019 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. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. import 'package:in_app_purchase/src/in_app_purchase/purchase_details.dart'; import 'package:test/test.dart'; diff --git a/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart b/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart index 7a7b7fb86364..f7f410a1cd8b 100644 --- a/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart +++ b/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart @@ -1,6 +1,6 @@ // Copyright 2019 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. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. import 'package:test/test.dart'; import 'package:in_app_purchase/billing_client_wrappers.dart'; diff --git a/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/EmbedderV1ActivityTest.java b/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/EmbedderV1ActivityTest.java index 0ce7dc14d4a5..2ae8cbb37db2 100644 --- a/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/EmbedderV1ActivityTest.java +++ b/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/EmbedderV1ActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package com.example.integration_test_example; import androidx.test.rule.ActivityTestRule; diff --git a/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityTest.java b/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityTest.java index 36ae1ddfc7e8..b84b290f175b 100644 --- a/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityTest.java +++ b/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package com.example.integration_test_example; import androidx.test.rule.ActivityTestRule; diff --git a/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityWithPermissionTest.java b/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityWithPermissionTest.java index c01d23466fed..a8e868a76838 100644 --- a/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityWithPermissionTest.java +++ b/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityWithPermissionTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package com.example.integration_test_example; import android.Manifest.permission; diff --git a/packages/integration_test/example/integration_test/_example_test_io.dart b/packages/integration_test/example/integration_test/_example_test_io.dart index 7ed28963c32b..01bcfe2928b1 100644 --- a/packages/integration_test/example/integration_test/_example_test_io.dart +++ b/packages/integration_test/example/integration_test/_example_test_io.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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. + // This is a basic Flutter widget test. // // To perform an interaction with a widget in your test, use the WidgetTester diff --git a/packages/integration_test/example/integration_test/_example_test_web.dart b/packages/integration_test/example/integration_test/_example_test_web.dart index e1141cc010c8..f0fd6212615a 100644 --- a/packages/integration_test/example/integration_test/_example_test_web.dart +++ b/packages/integration_test/example/integration_test/_example_test_web.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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. + // This is a basic Flutter widget test. // // To perform an interaction with a widget in your test, use the WidgetTester diff --git a/packages/integration_test/example/integration_test/_extended_test_io.dart b/packages/integration_test/example/integration_test/_extended_test_io.dart index 56fee6f7179c..ee0618a5adbc 100644 --- a/packages/integration_test/example/integration_test/_extended_test_io.dart +++ b/packages/integration_test/example/integration_test/_extended_test_io.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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. + // This is a basic Flutter widget test. // // To perform an interaction with a widget in your test, use the WidgetTester diff --git a/packages/integration_test/example/integration_test/_extended_test_web.dart b/packages/integration_test/example/integration_test/_extended_test_web.dart index 210c2dac75ba..878d9949af20 100644 --- a/packages/integration_test/example/integration_test/_extended_test_web.dart +++ b/packages/integration_test/example/integration_test/_extended_test_web.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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. + // This is a basic Flutter widget test. // // To perform an interaction with a widget in your test, use the WidgetTester diff --git a/packages/integration_test/example/integration_test/example_test.dart b/packages/integration_test/example/integration_test/example_test.dart index 918aec8777de..382094b9232f 100644 --- a/packages/integration_test/example/integration_test/example_test.dart +++ b/packages/integration_test/example/integration_test/example_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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. + // This is a basic Flutter widget test. // // To perform an interaction with a widget in your test, use the WidgetTester diff --git a/packages/integration_test/example/integration_test/extended_test.dart b/packages/integration_test/example/integration_test/extended_test.dart index 23d69a8f9438..b2a42ffafc00 100644 --- a/packages/integration_test/example/integration_test/extended_test.dart +++ b/packages/integration_test/example/integration_test/extended_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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. + // This is a Flutter widget test can take a screenshot. // // NOTE: Screenshots are only supported on Web for now. For Web, this needs to diff --git a/packages/integration_test/example/ios/Runner/AppDelegate.h b/packages/integration_test/example/ios/Runner/AppDelegate.h index 36e21bbf9cf4..b7984f089a9c 100644 --- a/packages/integration_test/example/ios/Runner/AppDelegate.h +++ b/packages/integration_test/example/ios/Runner/AppDelegate.h @@ -1,3 +1,7 @@ +// Copyright 2019 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. + #import #import diff --git a/packages/integration_test/example/ios/Runner/AppDelegate.m b/packages/integration_test/example/ios/Runner/AppDelegate.m index 59a72e90be12..60df7408bded 100644 --- a/packages/integration_test/example/ios/Runner/AppDelegate.m +++ b/packages/integration_test/example/ios/Runner/AppDelegate.m @@ -1,3 +1,7 @@ +// Copyright 2019 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. + #include "AppDelegate.h" #include "GeneratedPluginRegistrant.h" diff --git a/packages/integration_test/example/ios/Runner/main.m b/packages/integration_test/example/ios/Runner/main.m index dff6597e4513..84022b1644c3 100644 --- a/packages/integration_test/example/ios/Runner/main.m +++ b/packages/integration_test/example/ios/Runner/main.m @@ -1,3 +1,7 @@ +// Copyright 2019 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. + #import #import #import "AppDelegate.h" diff --git a/packages/integration_test/example/ios/RunnerTests/RunnerTests.m b/packages/integration_test/example/ios/RunnerTests/RunnerTests.m index ac89c60e5f06..15cc596a22cb 100644 --- a/packages/integration_test/example/ios/RunnerTests/RunnerTests.m +++ b/packages/integration_test/example/ios/RunnerTests/RunnerTests.m @@ -1,3 +1,7 @@ +// Copyright 2017 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 #import diff --git a/packages/integration_test/example/lib/main.dart b/packages/integration_test/example/lib/main.dart index 1f33324acd01..76d2378b32e1 100644 --- a/packages/integration_test/example/lib/main.dart +++ b/packages/integration_test/example/lib/main.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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 'my_app.dart' if (dart.library.html) 'my_web_app.dart'; // ignore_for_file: public_member_api_docs diff --git a/packages/integration_test/example/lib/my_app.dart b/packages/integration_test/example/lib/my_app.dart index bfbdb860c76d..bfcee0911064 100644 --- a/packages/integration_test/example/lib/my_app.dart +++ b/packages/integration_test/example/lib/my_app.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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:io' show Platform; import 'package:flutter/material.dart'; diff --git a/packages/integration_test/example/lib/my_web_app.dart b/packages/integration_test/example/lib/my_web_app.dart index c2ced1af97ae..b3efb24a54a8 100644 --- a/packages/integration_test/example/lib/my_web_app.dart +++ b/packages/integration_test/example/lib/my_web_app.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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:html' as html; import 'package:flutter/material.dart'; diff --git a/packages/integration_test/example/macos/Runner/AppDelegate.swift b/packages/integration_test/example/macos/Runner/AppDelegate.swift index d53ef6437726..ca19fe95f8cf 100644 --- a/packages/integration_test/example/macos/Runner/AppDelegate.swift +++ b/packages/integration_test/example/macos/Runner/AppDelegate.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/integration_test/example/macos/Runner/MainFlutterWindow.swift b/packages/integration_test/example/macos/Runner/MainFlutterWindow.swift index 2722837ec918..2ce11b78604b 100644 --- a/packages/integration_test/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/integration_test/example/macos/Runner/MainFlutterWindow.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/integration_test/example/test_driver/extended_integration_test.dart b/packages/integration_test/example/test_driver/extended_integration_test.dart index 056ba4bad722..059a3d13a2eb 100644 --- a/packages/integration_test/example/test_driver/extended_integration_test.dart +++ b/packages/integration_test/example/test_driver/extended_integration_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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_driver/flutter_driver.dart'; import 'package:integration_test/integration_test_driver_extended.dart'; diff --git a/packages/integration_test/example/test_driver/failure_test.dart b/packages/integration_test/example/test_driver/failure_test.dart index fce6adc42c92..c90eaafa7090 100644 --- a/packages/integration_test/example/test_driver/failure_test.dart +++ b/packages/integration_test/example/test_driver/failure_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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_driver/flutter_driver.dart'; import 'package:integration_test/common.dart' as common; import 'package:test/test.dart'; diff --git a/packages/integration_test/example/test_driver/integration_test.dart b/packages/integration_test/example/test_driver/integration_test.dart index b38629cca97b..8c650ee9f293 100644 --- a/packages/integration_test/example/test_driver/integration_test.dart +++ b/packages/integration_test/example/test_driver/integration_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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:integration_test/integration_test_driver.dart'; Future main() => integrationDriver(); diff --git a/packages/integration_test/example/web/index.html b/packages/integration_test/example/web/index.html index 96629657328f..492b9fd4cefc 100644 --- a/packages/integration_test/example/web/index.html +++ b/packages/integration_test/example/web/index.html @@ -1,4 +1,7 @@ + diff --git a/packages/integration_test/ios/Classes/IntegrationTestIosTest.h b/packages/integration_test/ios/Classes/IntegrationTestIosTest.h index 9c53edb160e9..7c09a1171267 100644 --- a/packages/integration_test/ios/Classes/IntegrationTestIosTest.h +++ b/packages/integration_test/ios/Classes/IntegrationTestIosTest.h @@ -1,3 +1,7 @@ +// Copyright 2019 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. + #import @interface IntegrationTestIosTest : NSObject diff --git a/packages/integration_test/ios/Classes/IntegrationTestIosTest.m b/packages/integration_test/ios/Classes/IntegrationTestIosTest.m index 1397f547e6f6..b3a7602b74b2 100644 --- a/packages/integration_test/ios/Classes/IntegrationTestIosTest.m +++ b/packages/integration_test/ios/Classes/IntegrationTestIosTest.m @@ -1,3 +1,7 @@ +// Copyright 2019 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. + #import "IntegrationTestIosTest.h" #import "IntegrationTestPlugin.h" diff --git a/packages/integration_test/ios/Classes/IntegrationTestPlugin.h b/packages/integration_test/ios/Classes/IntegrationTestPlugin.h index 8dd3109ffe09..6a6171fd16e8 100644 --- a/packages/integration_test/ios/Classes/IntegrationTestPlugin.h +++ b/packages/integration_test/ios/Classes/IntegrationTestPlugin.h @@ -1,3 +1,7 @@ +// Copyright 2019 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. + #import NS_ASSUME_NONNULL_BEGIN diff --git a/packages/integration_test/ios/Classes/IntegrationTestPlugin.m b/packages/integration_test/ios/Classes/IntegrationTestPlugin.m index e7e5a74c01ee..5c4d0e6bfb24 100644 --- a/packages/integration_test/ios/Classes/IntegrationTestPlugin.m +++ b/packages/integration_test/ios/Classes/IntegrationTestPlugin.m @@ -1,3 +1,7 @@ +// Copyright 2019 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. + #import "IntegrationTestPlugin.h" static NSString *const kIntegrationTestPluginChannel = @"plugins.flutter.io/integration_test"; diff --git a/packages/integration_test/lib/integration_test_driver_extended.dart b/packages/integration_test/lib/integration_test_driver_extended.dart index bc38bb71de50..c423f296c331 100644 --- a/packages/integration_test/lib/integration_test_driver_extended.dart +++ b/packages/integration_test/lib/integration_test_driver_extended.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'dart:async'; import 'dart:io'; diff --git a/packages/integration_test/test/binding_fail_test.dart b/packages/integration_test/test/binding_fail_test.dart index 7ec176897c0c..d0d5fd423b67 100644 --- a/packages/integration_test/test/binding_fail_test.dart +++ b/packages/integration_test/test/binding_fail_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'dart:async'; import 'dart:io'; import 'dart:convert'; diff --git a/packages/integration_test/test/binding_test.dart b/packages/integration_test/test/binding_test.dart index ef4efc59aac0..10e3c093b140 100644 --- a/packages/integration_test/test/binding_test.dart +++ b/packages/integration_test/test/binding_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'dart:convert'; import 'package:flutter/material.dart'; diff --git a/packages/integration_test/test/data/fail_test_script.dart b/packages/integration_test/test/data/fail_test_script.dart index 05a75d7d031e..a495a3b3f698 100644 --- a/packages/integration_test/test/data/fail_test_script.dart +++ b/packages/integration_test/test/data/fail_test_script.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'dart:convert'; import 'package:integration_test/integration_test.dart'; diff --git a/packages/integration_test/test/data/pass_test_script.dart b/packages/integration_test/test/data/pass_test_script.dart index 7e222c8e8961..e31651de74ac 100644 --- a/packages/integration_test/test/data/pass_test_script.dart +++ b/packages/integration_test/test/data/pass_test_script.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'dart:convert'; import 'package:integration_test/integration_test.dart'; diff --git a/packages/integration_test/test/data/pass_then_fail_test_script.dart b/packages/integration_test/test/data/pass_then_fail_test_script.dart index 324c1c21cfa6..9116fde266e0 100644 --- a/packages/integration_test/test/data/pass_then_fail_test_script.dart +++ b/packages/integration_test/test/data/pass_then_fail_test_script.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'dart:convert'; import 'package:integration_test/integration_test.dart'; diff --git a/packages/integration_test/test/response_serialization_test.dart b/packages/integration_test/test/response_serialization_test.dart index 8b969402035d..ee6cacc73a5e 100644 --- a/packages/integration_test/test/response_serialization_test.dart +++ b/packages/integration_test/test/response_serialization_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/common.dart'; diff --git a/packages/ios_platform_images/example/ios/Runner/AppDelegate.swift b/packages/ios_platform_images/example/ios/Runner/AppDelegate.swift index 70693e4a8c12..f26669f6bd4f 100644 --- a/packages/ios_platform_images/example/ios/Runner/AppDelegate.swift +++ b/packages/ios_platform_images/example/ios/Runner/AppDelegate.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 UIKit import Flutter diff --git a/packages/ios_platform_images/example/ios/Runner/Runner-Bridging-Header.h b/packages/ios_platform_images/example/ios/Runner/Runner-Bridging-Header.h index 7335fdf9000c..3a69a7befa44 100644 --- a/packages/ios_platform_images/example/ios/Runner/Runner-Bridging-Header.h +++ b/packages/ios_platform_images/example/ios/Runner/Runner-Bridging-Header.h @@ -1 +1,5 @@ -#import "GeneratedPluginRegistrant.h" \ No newline at end of file +// Copyright 2017 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 "GeneratedPluginRegistrant.h" diff --git a/packages/ios_platform_images/example/lib/main.dart b/packages/ios_platform_images/example/lib/main.dart index 394d983ab66c..aa4392243785 100644 --- a/packages/ios_platform_images/example/lib/main.dart +++ b/packages/ios_platform_images/example/lib/main.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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/material.dart'; import 'package:ios_platform_images/ios_platform_images.dart'; diff --git a/packages/ios_platform_images/example/test/widget_test.dart b/packages/ios_platform_images/example/test/widget_test.dart index ae8e5a41e4be..66d964302180 100644 --- a/packages/ios_platform_images/example/test/widget_test.dart +++ b/packages/ios_platform_images/example/test/widget_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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:io'; import 'package:flutter/material.dart'; diff --git a/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.h b/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.h index d4106b598d75..e53977a3d9cd 100644 --- a/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.h +++ b/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.h @@ -1,3 +1,7 @@ +// 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. + #import /// A plugin for Flutter that allows Flutter to load images in a platform diff --git a/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.m b/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.m index bad6f11417b9..151c418c2f6a 100644 --- a/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.m +++ b/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.m @@ -1,3 +1,7 @@ +// 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. + #import "IosPlatformImagesPlugin.h" #if !__has_feature(objc_arc) diff --git a/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/EmbeddingV1ActivityTest.java b/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/EmbeddingV1ActivityTest.java index 30d2126f0609..dc28926caa08 100644 --- a/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/EmbeddingV1ActivityTest.java +++ b/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/EmbeddingV1ActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.localauth; import androidx.test.rule.ActivityTestRule; diff --git a/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java b/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java index 3d2d55bce0fa..ebaf3ccf92ba 100644 --- a/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java +++ b/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.localauth; import androidx.test.rule.ActivityTestRule; diff --git a/packages/local_auth/example/android/app/src/main/java/io/flutter/plugins/localauthexample/EmbeddingV1Activity.java b/packages/local_auth/example/android/app/src/main/java/io/flutter/plugins/localauthexample/EmbeddingV1Activity.java index 91bef9dd13d7..83af839a9fbb 100644 --- a/packages/local_auth/example/android/app/src/main/java/io/flutter/plugins/localauthexample/EmbeddingV1Activity.java +++ b/packages/local_auth/example/android/app/src/main/java/io/flutter/plugins/localauthexample/EmbeddingV1Activity.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.localauthexample; import android.os.Bundle; diff --git a/packages/local_auth/example/ios/Runner/main.m b/packages/local_auth/example/ios/Runner/main.m index dff6597e4513..f451b14cb751 100644 --- a/packages/local_auth/example/ios/Runner/main.m +++ b/packages/local_auth/example/ios/Runner/main.m @@ -1,3 +1,7 @@ +// Copyright 2017 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 #import #import "AppDelegate.h" diff --git a/packages/package_info/example/integration_test/package_info_test.dart b/packages/package_info/example/integration_test/package_info_test.dart index e70c8a5f0eca..75bae13cc8f7 100644 --- a/packages/package_info/example/integration_test/package_info_test.dart +++ b/packages/package_info/example/integration_test/package_info_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/package_info/example/macos/Runner/AppDelegate.swift b/packages/package_info/example/macos/Runner/AppDelegate.swift index d53ef6437726..ca19fe95f8cf 100644 --- a/packages/package_info/example/macos/Runner/AppDelegate.swift +++ b/packages/package_info/example/macos/Runner/AppDelegate.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/package_info/example/macos/Runner/MainFlutterWindow.swift b/packages/package_info/example/macos/Runner/MainFlutterWindow.swift index 2722837ec918..2ce11b78604b 100644 --- a/packages/package_info/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/package_info/example/macos/Runner/MainFlutterWindow.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/package_info/example/test_driver/integration_test.dart b/packages/package_info/example/test_driver/integration_test.dart index 437b3609d119..a2977d367f9f 100644 --- a/packages/package_info/example/test_driver/integration_test.dart +++ b/packages/package_info/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/path_provider/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java b/packages/path_provider/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java index 820509ba86ea..c41b81deaff6 100644 --- a/packages/path_provider/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java +++ b/packages/path_provider/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.pathprovider; import android.os.Build.VERSION; @@ -6,7 +10,6 @@ /** Helps to map the Dart `StorageDirectory` enum to a Android system constant. */ class StorageDirectoryMapper { - /** * Return a Android Environment constant for a Dart Index. * diff --git a/packages/path_provider/path_provider/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java b/packages/path_provider/path_provider/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java index 74a4e6d5169d..2df4497332b3 100644 --- a/packages/path_provider/path_provider/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java +++ b/packages/path_provider/path_provider/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java @@ -1,3 +1,7 @@ +// Copyright 2019 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. + package io.flutter.plugins.pathprovider; import static org.junit.Assert.assertEquals; @@ -8,7 +12,6 @@ import org.junit.Test; public class StorageDirectoryMapperTest { - @org.junit.Test public void testAndroidType_null() { assertNull(StorageDirectoryMapper.androidType(null)); diff --git a/packages/path_provider/path_provider/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java b/packages/path_provider/path_provider/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java index 385740db166d..9292edb43dd7 100644 --- a/packages/path_provider/path_provider/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java +++ b/packages/path_provider/path_provider/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java @@ -1,3 +1,6 @@ +// Copyright 2017 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. package io.flutter.plugins.pathprovider; diff --git a/packages/path_provider/path_provider/example/android/app/src/androidTest/java/MainActivityTest.java b/packages/path_provider/path_provider/example/android/app/src/androidTest/java/MainActivityTest.java index a99767c4ccf9..986e3a439b0f 100644 --- a/packages/path_provider/path_provider/example/android/app/src/androidTest/java/MainActivityTest.java +++ b/packages/path_provider/path_provider/example/android/app/src/androidTest/java/MainActivityTest.java @@ -1,3 +1,6 @@ +// Copyright 2017 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. package io.flutter.plugins.pathprovider; diff --git a/packages/path_provider/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java b/packages/path_provider/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java index 2ff41b25a4fc..2853fb394179 100644 --- a/packages/path_provider/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java +++ b/packages/path_provider/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java @@ -1,3 +1,6 @@ +// Copyright 2017 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. package io.flutter.plugins.pathproviderexample; diff --git a/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart b/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart index 2b12c82f959b..cb0b8744c84f 100644 --- a/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/path_provider/path_provider/example/linux/main.cc b/packages/path_provider/path_provider/example/linux/main.cc index 10835acb58ed..a15afa068a7b 100644 --- a/packages/path_provider/path_provider/example/linux/main.cc +++ b/packages/path_provider/path_provider/example/linux/main.cc @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "my_application.h" int main(int argc, char** argv) { diff --git a/packages/path_provider/path_provider/example/linux/my_application.cc b/packages/path_provider/path_provider/example/linux/my_application.cc index 67ed0b9025b2..3843c07aaf04 100644 --- a/packages/path_provider/path_provider/example/linux/my_application.cc +++ b/packages/path_provider/path_provider/example/linux/my_application.cc @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "my_application.h" #include diff --git a/packages/path_provider/path_provider/example/linux/my_application.h b/packages/path_provider/path_provider/example/linux/my_application.h index 72271d5e4170..abbdf1213815 100644 --- a/packages/path_provider/path_provider/example/linux/my_application.h +++ b/packages/path_provider/path_provider/example/linux/my_application.h @@ -1,3 +1,7 @@ +// 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. + #ifndef FLUTTER_MY_APPLICATION_H_ #define FLUTTER_MY_APPLICATION_H_ diff --git a/packages/path_provider/path_provider/example/macos/Runner/AppDelegate.swift b/packages/path_provider/path_provider/example/macos/Runner/AppDelegate.swift index d53ef6437726..ca19fe95f8cf 100644 --- a/packages/path_provider/path_provider/example/macos/Runner/AppDelegate.swift +++ b/packages/path_provider/path_provider/example/macos/Runner/AppDelegate.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/path_provider/path_provider/example/macos/Runner/MainFlutterWindow.swift b/packages/path_provider/path_provider/example/macos/Runner/MainFlutterWindow.swift index 2722837ec918..2ce11b78604b 100644 --- a/packages/path_provider/path_provider/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/path_provider/path_provider/example/macos/Runner/MainFlutterWindow.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/path_provider/path_provider/example/test_driver/integration_test.dart b/packages/path_provider/path_provider/example/test_driver/integration_test.dart index ac106b63b339..a82b5fb51e77 100644 --- a/packages/path_provider/path_provider/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/path_provider/path_provider/example/windows/runner/flutter_window.cpp b/packages/path_provider/path_provider/example/windows/runner/flutter_window.cpp index c422723045ca..dd2e3cca5666 100644 --- a/packages/path_provider/path_provider/example/windows/runner/flutter_window.cpp +++ b/packages/path_provider/path_provider/example/windows/runner/flutter_window.cpp @@ -1,3 +1,7 @@ +// 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. + #include "flutter_window.h" #include diff --git a/packages/path_provider/path_provider/example/windows/runner/flutter_window.h b/packages/path_provider/path_provider/example/windows/runner/flutter_window.h index b663ddd50125..9b4ef089621b 100644 --- a/packages/path_provider/path_provider/example/windows/runner/flutter_window.h +++ b/packages/path_provider/path_provider/example/windows/runner/flutter_window.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef RUNNER_FLUTTER_WINDOW_H_ #define RUNNER_FLUTTER_WINDOW_H_ diff --git a/packages/path_provider/path_provider/example/windows/runner/main.cpp b/packages/path_provider/path_provider/example/windows/runner/main.cpp index fc17fec6140c..e74157ed999a 100644 --- a/packages/path_provider/path_provider/example/windows/runner/main.cpp +++ b/packages/path_provider/path_provider/example/windows/runner/main.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include #include #include diff --git a/packages/path_provider/path_provider/example/windows/runner/run_loop.cpp b/packages/path_provider/path_provider/example/windows/runner/run_loop.cpp index 2d6636ab6bc6..ee2e2fd5eae9 100644 --- a/packages/path_provider/path_provider/example/windows/runner/run_loop.cpp +++ b/packages/path_provider/path_provider/example/windows/runner/run_loop.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "run_loop.h" #include diff --git a/packages/path_provider/path_provider/example/windows/runner/run_loop.h b/packages/path_provider/path_provider/example/windows/runner/run_loop.h index 5f2c4a9ad7d3..a24c47f2e55f 100644 --- a/packages/path_provider/path_provider/example/windows/runner/run_loop.h +++ b/packages/path_provider/path_provider/example/windows/runner/run_loop.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef RUNNER_RUN_LOOP_H_ #define RUNNER_RUN_LOOP_H_ diff --git a/packages/path_provider/path_provider/example/windows/runner/utils.cpp b/packages/path_provider/path_provider/example/windows/runner/utils.cpp index 37501e5db777..9eba364025d0 100644 --- a/packages/path_provider/path_provider/example/windows/runner/utils.cpp +++ b/packages/path_provider/path_provider/example/windows/runner/utils.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "utils.h" #include diff --git a/packages/path_provider/path_provider/example/windows/runner/utils.h b/packages/path_provider/path_provider/example/windows/runner/utils.h index d792603bb139..640587eb23ab 100644 --- a/packages/path_provider/path_provider/example/windows/runner/utils.h +++ b/packages/path_provider/path_provider/example/windows/runner/utils.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef RUNNER_UTILS_H_ #define RUNNER_UTILS_H_ diff --git a/packages/path_provider/path_provider/example/windows/runner/win32_window.cpp b/packages/path_provider/path_provider/example/windows/runner/win32_window.cpp index c63ad013b02d..97628170c2c2 100644 --- a/packages/path_provider/path_provider/example/windows/runner/win32_window.cpp +++ b/packages/path_provider/path_provider/example/windows/runner/win32_window.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "win32_window.h" #include diff --git a/packages/path_provider/path_provider/example/windows/runner/win32_window.h b/packages/path_provider/path_provider/example/windows/runner/win32_window.h index 4ae64a12b465..59b78382b27d 100644 --- a/packages/path_provider/path_provider/example/windows/runner/win32_window.h +++ b/packages/path_provider/path_provider/example/windows/runner/win32_window.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef RUNNER_WIN32_WINDOW_H_ #define RUNNER_WIN32_WINDOW_H_ diff --git a/packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart b/packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart index d08b3878a4d5..6cd19401cf0e 100644 --- a/packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/path_provider/path_provider_linux/example/lib/main.dart b/packages/path_provider/path_provider_linux/example/lib/main.dart index 6958ed10cb23..bd1c80a12fb7 100644 --- a/packages/path_provider/path_provider_linux/example/lib/main.dart +++ b/packages/path_provider/path_provider_linux/example/lib/main.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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/material.dart'; import 'dart:async'; diff --git a/packages/path_provider/path_provider_linux/example/linux/main.cc b/packages/path_provider/path_provider_linux/example/linux/main.cc index 10835acb58ed..a15afa068a7b 100644 --- a/packages/path_provider/path_provider_linux/example/linux/main.cc +++ b/packages/path_provider/path_provider_linux/example/linux/main.cc @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "my_application.h" int main(int argc, char** argv) { diff --git a/packages/path_provider/path_provider_linux/example/linux/my_application.cc b/packages/path_provider/path_provider_linux/example/linux/my_application.cc index 67ed0b9025b2..3843c07aaf04 100644 --- a/packages/path_provider/path_provider_linux/example/linux/my_application.cc +++ b/packages/path_provider/path_provider_linux/example/linux/my_application.cc @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "my_application.h" #include diff --git a/packages/path_provider/path_provider_linux/example/linux/my_application.h b/packages/path_provider/path_provider_linux/example/linux/my_application.h index 72271d5e4170..b3d62442a005 100644 --- a/packages/path_provider/path_provider_linux/example/linux/my_application.h +++ b/packages/path_provider/path_provider_linux/example/linux/my_application.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef FLUTTER_MY_APPLICATION_H_ #define FLUTTER_MY_APPLICATION_H_ diff --git a/packages/path_provider/path_provider_linux/example/test/widget_test.dart b/packages/path_provider/path_provider_linux/example/test/widget_test.dart index 086b6d614e13..e25ebe36fb08 100644 --- a/packages/path_provider/path_provider_linux/example/test/widget_test.dart +++ b/packages/path_provider/path_provider_linux/example/test/widget_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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. + // This is a basic Flutter widget test. // // To perform an interaction with a widget in your test, use the WidgetTester diff --git a/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart b/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart index ac106b63b339..a82b5fb51e77 100644 --- a/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/path_provider/path_provider_macos/example/integration_test/path_provider_test.dart b/packages/path_provider/path_provider_macos/example/integration_test/path_provider_test.dart index 1bb079051cfc..10be231d064e 100644 --- a/packages/path_provider/path_provider_macos/example/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider_macos/example/integration_test/path_provider_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/AppDelegate.swift b/packages/path_provider/path_provider_macos/example/macos/Runner/AppDelegate.swift index d53ef6437726..ca19fe95f8cf 100644 --- a/packages/path_provider/path_provider_macos/example/macos/Runner/AppDelegate.swift +++ b/packages/path_provider/path_provider_macos/example/macos/Runner/AppDelegate.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/MainFlutterWindow.swift b/packages/path_provider/path_provider_macos/example/macos/Runner/MainFlutterWindow.swift index 2722837ec918..2ce11b78604b 100644 --- a/packages/path_provider/path_provider_macos/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/path_provider/path_provider_macos/example/macos/Runner/MainFlutterWindow.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart b/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart index ac106b63b339..a82b5fb51e77 100644 --- a/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart b/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart index c97ef5d2b0f5..f563b5ed0b2d 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart @@ -1,3 +1,7 @@ +// Copyright 2020 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. + /// Corresponds to constants defined in Androids `android.os.Environment` class. /// /// https://developer.android.com/reference/android/os/Environment.html#fields_1 diff --git a/packages/path_provider/path_provider_windows/example/integration_test/path_provider_test.dart b/packages/path_provider/path_provider_windows/example/integration_test/path_provider_test.dart index 0953fc100950..0d521a5df247 100644 --- a/packages/path_provider/path_provider_windows/example/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider_windows/example/integration_test/path_provider_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart b/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart index ac106b63b339..a82b5fb51e77 100644 --- a/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/path_provider/path_provider_windows/example/windows/runner/flutter_window.cpp b/packages/path_provider/path_provider_windows/example/windows/runner/flutter_window.cpp index c422723045ca..b7d078e4d4a5 100644 --- a/packages/path_provider/path_provider_windows/example/windows/runner/flutter_window.cpp +++ b/packages/path_provider/path_provider_windows/example/windows/runner/flutter_window.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "flutter_window.h" #include diff --git a/packages/path_provider/path_provider_windows/example/windows/runner/flutter_window.h b/packages/path_provider/path_provider_windows/example/windows/runner/flutter_window.h index b663ddd50125..9b4ef089621b 100644 --- a/packages/path_provider/path_provider_windows/example/windows/runner/flutter_window.h +++ b/packages/path_provider/path_provider_windows/example/windows/runner/flutter_window.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef RUNNER_FLUTTER_WINDOW_H_ #define RUNNER_FLUTTER_WINDOW_H_ diff --git a/packages/path_provider/path_provider_windows/example/windows/runner/main.cpp b/packages/path_provider/path_provider_windows/example/windows/runner/main.cpp index fc17fec6140c..e74157ed999a 100644 --- a/packages/path_provider/path_provider_windows/example/windows/runner/main.cpp +++ b/packages/path_provider/path_provider_windows/example/windows/runner/main.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include #include #include diff --git a/packages/path_provider/path_provider_windows/example/windows/runner/run_loop.cpp b/packages/path_provider/path_provider_windows/example/windows/runner/run_loop.cpp index 2d6636ab6bc6..ee2e2fd5eae9 100644 --- a/packages/path_provider/path_provider_windows/example/windows/runner/run_loop.cpp +++ b/packages/path_provider/path_provider_windows/example/windows/runner/run_loop.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "run_loop.h" #include diff --git a/packages/path_provider/path_provider_windows/example/windows/runner/run_loop.h b/packages/path_provider/path_provider_windows/example/windows/runner/run_loop.h index 5f2c4a9ad7d3..a24c47f2e55f 100644 --- a/packages/path_provider/path_provider_windows/example/windows/runner/run_loop.h +++ b/packages/path_provider/path_provider_windows/example/windows/runner/run_loop.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef RUNNER_RUN_LOOP_H_ #define RUNNER_RUN_LOOP_H_ diff --git a/packages/path_provider/path_provider_windows/example/windows/runner/utils.cpp b/packages/path_provider/path_provider_windows/example/windows/runner/utils.cpp index 37501e5db777..9eba364025d0 100644 --- a/packages/path_provider/path_provider_windows/example/windows/runner/utils.cpp +++ b/packages/path_provider/path_provider_windows/example/windows/runner/utils.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "utils.h" #include diff --git a/packages/path_provider/path_provider_windows/example/windows/runner/utils.h b/packages/path_provider/path_provider_windows/example/windows/runner/utils.h index d792603bb139..640587eb23ab 100644 --- a/packages/path_provider/path_provider_windows/example/windows/runner/utils.h +++ b/packages/path_provider/path_provider_windows/example/windows/runner/utils.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef RUNNER_UTILS_H_ #define RUNNER_UTILS_H_ diff --git a/packages/path_provider/path_provider_windows/example/windows/runner/win32_window.cpp b/packages/path_provider/path_provider_windows/example/windows/runner/win32_window.cpp index c63ad013b02d..97628170c2c2 100644 --- a/packages/path_provider/path_provider_windows/example/windows/runner/win32_window.cpp +++ b/packages/path_provider/path_provider_windows/example/windows/runner/win32_window.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "win32_window.h" #include diff --git a/packages/path_provider/path_provider_windows/example/windows/runner/win32_window.h b/packages/path_provider/path_provider_windows/example/windows/runner/win32_window.h index 4ae64a12b465..59b78382b27d 100644 --- a/packages/path_provider/path_provider_windows/example/windows/runner/win32_window.h +++ b/packages/path_provider/path_provider_windows/example/windows/runner/win32_window.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef RUNNER_WIN32_WINDOW_H_ #define RUNNER_WIN32_WINDOW_H_ diff --git a/packages/quick_actions/example/integration_test/quick_actions_test.dart b/packages/quick_actions/example/integration_test/quick_actions_test.dart index 43822c9e8b2b..bad84debefd6 100644 --- a/packages/quick_actions/example/integration_test/quick_actions_test.dart +++ b/packages/quick_actions/example/integration_test/quick_actions_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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'; diff --git a/packages/quick_actions/example/test_driver/integration_test.dart b/packages/quick_actions/example/test_driver/integration_test.dart index 0352d4aaeb2d..6332de2cfd8d 100644 --- a/packages/quick_actions/example/test_driver/integration_test.dart +++ b/packages/quick_actions/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 'dart:async'; diff --git a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1ActivityTest.java b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1ActivityTest.java index 65a4dca981aa..9760ef098572 100644 --- a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1ActivityTest.java +++ b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1ActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.sensorsexample; import androidx.test.rule.ActivityTestRule; diff --git a/packages/sensors/example/ios/Runner/AppDelegate.h b/packages/sensors/example/ios/Runner/AppDelegate.h index 36e21bbf9cf4..31fc381e7066 100644 --- a/packages/sensors/example/ios/Runner/AppDelegate.h +++ b/packages/sensors/example/ios/Runner/AppDelegate.h @@ -1,3 +1,7 @@ +// Copyright 2017 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 #import diff --git a/packages/sensors/example/ios/Runner/AppDelegate.m b/packages/sensors/example/ios/Runner/AppDelegate.m index 59a72e90be12..2147d3d605ac 100644 --- a/packages/sensors/example/ios/Runner/AppDelegate.m +++ b/packages/sensors/example/ios/Runner/AppDelegate.m @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "AppDelegate.h" #include "GeneratedPluginRegistrant.h" diff --git a/packages/sensors/example/ios/Runner/main.m b/packages/sensors/example/ios/Runner/main.m index dff6597e4513..f451b14cb751 100644 --- a/packages/sensors/example/ios/Runner/main.m +++ b/packages/sensors/example/ios/Runner/main.m @@ -1,3 +1,7 @@ +// Copyright 2017 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 #import #import "AppDelegate.h" diff --git a/packages/sensors/example/test_driver/test/integration_test.dart b/packages/sensors/example/test_driver/test/integration_test.dart index a8a56aa90f6a..c62ef5dba800 100644 --- a/packages/sensors/example/test_driver/test/integration_test.dart +++ b/packages/sensors/example/test_driver/test/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/sensors/integration_test/sensors_test.dart b/packages/sensors/integration_test/sensors_test.dart index 348bda00d86e..5ae15967d8e4 100644 --- a/packages/sensors/integration_test/sensors_test.dart +++ b/packages/sensors/integration_test/sensors_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1ActivityTest.java b/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1ActivityTest.java index 489b224a62ea..77bc7cedcfa5 100644 --- a/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1ActivityTest.java +++ b/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1ActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.shareexample; import androidx.test.rule.ActivityTestRule; diff --git a/packages/share/example/lib/image_previews.dart b/packages/share/example/lib/image_previews.dart index 9070749267fc..7298ed4348b1 100644 --- a/packages/share/example/lib/image_previews.dart +++ b/packages/share/example/lib/image_previews.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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:io'; import 'package:flutter/material.dart'; diff --git a/packages/share/example/test_driver/test/integration_test.dart b/packages/share/example/test_driver/test/integration_test.dart index a8a56aa90f6a..c62ef5dba800 100644 --- a/packages/share/example/test_driver/test/integration_test.dart +++ b/packages/share/example/test_driver/test/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/share/integration_test/share_test.dart b/packages/share/integration_test/share_test.dart index 7b66480d0681..a6a2ddb4f7cd 100644 --- a/packages/share/integration_test/share_test.dart +++ b/packages/share/integration_test/share_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.swift b/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.swift index 70693e4a8c12..f26669f6bd4f 100644 --- a/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.swift +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 UIKit import Flutter diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner/Runner-Bridging-Header.h b/packages/shared_preferences/shared_preferences/example/ios/Runner/Runner-Bridging-Header.h index 308a2a560b42..0592e2dd559c 100644 --- a/packages/shared_preferences/shared_preferences/example/ios/Runner/Runner-Bridging-Header.h +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner/Runner-Bridging-Header.h @@ -1 +1,5 @@ +// 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. + #import "GeneratedPluginRegistrant.h" diff --git a/packages/shared_preferences/shared_preferences/example/linux/main.cc b/packages/shared_preferences/shared_preferences/example/linux/main.cc index 10835acb58ed..a15afa068a7b 100644 --- a/packages/shared_preferences/shared_preferences/example/linux/main.cc +++ b/packages/shared_preferences/shared_preferences/example/linux/main.cc @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "my_application.h" int main(int argc, char** argv) { diff --git a/packages/shared_preferences/shared_preferences/example/linux/my_application.cc b/packages/shared_preferences/shared_preferences/example/linux/my_application.cc index 67ed0b9025b2..3843c07aaf04 100644 --- a/packages/shared_preferences/shared_preferences/example/linux/my_application.cc +++ b/packages/shared_preferences/shared_preferences/example/linux/my_application.cc @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "my_application.h" #include diff --git a/packages/shared_preferences/shared_preferences/example/linux/my_application.h b/packages/shared_preferences/shared_preferences/example/linux/my_application.h index 72271d5e4170..abbdf1213815 100644 --- a/packages/shared_preferences/shared_preferences/example/linux/my_application.h +++ b/packages/shared_preferences/shared_preferences/example/linux/my_application.h @@ -1,3 +1,7 @@ +// 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. + #ifndef FLUTTER_MY_APPLICATION_H_ #define FLUTTER_MY_APPLICATION_H_ diff --git a/packages/shared_preferences/shared_preferences/example/macos/Runner/AppDelegate.swift b/packages/shared_preferences/shared_preferences/example/macos/Runner/AppDelegate.swift index d53ef6437726..ca19fe95f8cf 100644 --- a/packages/shared_preferences/shared_preferences/example/macos/Runner/AppDelegate.swift +++ b/packages/shared_preferences/shared_preferences/example/macos/Runner/AppDelegate.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/shared_preferences/shared_preferences/example/macos/Runner/MainFlutterWindow.swift b/packages/shared_preferences/shared_preferences/example/macos/Runner/MainFlutterWindow.swift index 2722837ec918..2ce11b78604b 100644 --- a/packages/shared_preferences/shared_preferences/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/shared_preferences/shared_preferences/example/macos/Runner/MainFlutterWindow.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/shared_preferences/shared_preferences/example/test_driver/integration_test.dart b/packages/shared_preferences/shared_preferences/example/test_driver/integration_test.dart index ac106b63b339..a82b5fb51e77 100644 --- a/packages/shared_preferences/shared_preferences/example/test_driver/integration_test.dart +++ b/packages/shared_preferences/shared_preferences/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/shared_preferences/shared_preferences/example/web/index.html b/packages/shared_preferences/shared_preferences/example/web/index.html index 6eff9a740d43..27464c33811a 100644 --- a/packages/shared_preferences/shared_preferences/example/web/index.html +++ b/packages/shared_preferences/shared_preferences/example/web/index.html @@ -1,4 +1,7 @@ + diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.cpp b/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.cpp index c422723045ca..dd2e3cca5666 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.cpp +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.cpp @@ -1,3 +1,7 @@ +// 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. + #include "flutter_window.h" #include diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.h b/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.h index b663ddd50125..a9d273e419eb 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.h +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.h @@ -1,3 +1,7 @@ +// 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. + #ifndef RUNNER_FLUTTER_WINDOW_H_ #define RUNNER_FLUTTER_WINDOW_H_ diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/main.cpp b/packages/shared_preferences/shared_preferences/example/windows/runner/main.cpp index fc17fec6140c..40492ac76edb 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/main.cpp +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/main.cpp @@ -1,3 +1,7 @@ +// 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. + #include #include #include diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.cpp b/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.cpp index 2d6636ab6bc6..4dd13b6d1db9 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.cpp +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.cpp @@ -1,3 +1,7 @@ +// 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. + #include "run_loop.h" #include diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.h b/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.h index 5f2c4a9ad7d3..12aaab42c59b 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.h +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.h @@ -1,3 +1,7 @@ +// 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. + #ifndef RUNNER_RUN_LOOP_H_ #define RUNNER_RUN_LOOP_H_ diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/utils.cpp b/packages/shared_preferences/shared_preferences/example/windows/runner/utils.cpp index 37501e5db777..c408cb3f7a74 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/utils.cpp +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/utils.cpp @@ -1,3 +1,7 @@ +// 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. + #include "utils.h" #include diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/utils.h b/packages/shared_preferences/shared_preferences/example/windows/runner/utils.h index d792603bb139..2754c7a7f9ef 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/utils.h +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/utils.h @@ -1,3 +1,7 @@ +// 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. + #ifndef RUNNER_UTILS_H_ #define RUNNER_UTILS_H_ diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.cpp b/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.cpp index c63ad013b02d..878b64afe276 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.cpp +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.cpp @@ -1,3 +1,7 @@ +// 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. + #include "win32_window.h" #include diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.h b/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.h index 4ae64a12b465..99e24a555afa 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.h +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.h @@ -1,3 +1,7 @@ +// 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. + #ifndef RUNNER_WIN32_WINDOW_H_ #define RUNNER_WIN32_WINDOW_H_ diff --git a/packages/shared_preferences/shared_preferences_linux/example/linux/main.cc b/packages/shared_preferences/shared_preferences_linux/example/linux/main.cc index e7c5c5437037..612325f29cd7 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/linux/main.cc +++ b/packages/shared_preferences/shared_preferences_linux/example/linux/main.cc @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "my_application.h" int main(int argc, char** argv) { diff --git a/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.cc b/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.cc index f079e19eb396..a8f67ccc9a86 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.cc +++ b/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.cc @@ -1,3 +1,7 @@ +// 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. + #include "my_application.h" #include diff --git a/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.h b/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.h index 72271d5e4170..d1c3f9c4fb0b 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.h +++ b/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.h @@ -1,3 +1,7 @@ +// Copyright 2020 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. + #ifndef FLUTTER_MY_APPLICATION_H_ #define FLUTTER_MY_APPLICATION_H_ diff --git a/packages/shared_preferences/shared_preferences_linux/example/test_driver/integration_test.dart b/packages/shared_preferences/shared_preferences_linux/example/test_driver/integration_test.dart index ac106b63b339..a82b5fb51e77 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/test_driver/integration_test.dart +++ b/packages/shared_preferences/shared_preferences_linux/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/shared_preferences/shared_preferences_macos/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_macos/example/integration_test/shared_preferences_test.dart index 58b59463b352..94dee2d73c9d 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_macos/example/integration_test/shared_preferences_test.dart @@ -1,6 +1,6 @@ -// Copyright 2017, 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. +// Copyright 2017, the Chromium project 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 diff --git a/packages/shared_preferences/shared_preferences_macos/example/macos/Runner/AppDelegate.swift b/packages/shared_preferences/shared_preferences_macos/example/macos/Runner/AppDelegate.swift index d53ef6437726..ca19fe95f8cf 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/macos/Runner/AppDelegate.swift +++ b/packages/shared_preferences/shared_preferences_macos/example/macos/Runner/AppDelegate.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/shared_preferences/shared_preferences_macos/example/macos/Runner/MainFlutterWindow.swift b/packages/shared_preferences/shared_preferences_macos/example/macos/Runner/MainFlutterWindow.swift index 2722837ec918..2ce11b78604b 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/shared_preferences/shared_preferences_macos/example/macos/Runner/MainFlutterWindow.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/shared_preferences/shared_preferences_macos/example/test_driver/integration_test.dart b/packages/shared_preferences/shared_preferences_macos/example/test_driver/integration_test.dart index ac106b63b339..a82b5fb51e77 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/test_driver/integration_test.dart +++ b/packages/shared_preferences/shared_preferences_macos/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart index 027daa6eaeb1..41fc5dbf8b2a 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart @@ -1,6 +1,6 @@ -// Copyright 2017, 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. +// Copyright 2017, the Chromium project 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 diff --git a/packages/shared_preferences/shared_preferences_windows/example/test_driver/integration_test.dart b/packages/shared_preferences/shared_preferences_windows/example/test_driver/integration_test.dart index 353548ee0e8c..5504f8c79080 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/test_driver/integration_test.dart +++ b/packages/shared_preferences/shared_preferences_windows/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// Copyright 2017, 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. +// Copyright 2017, the Chromium project 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 diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.cpp b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.cpp index c422723045ca..dd2e3cca5666 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.cpp +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.cpp @@ -1,3 +1,7 @@ +// 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. + #include "flutter_window.h" #include diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.h b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.h index b663ddd50125..a9d273e419eb 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.h +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.h @@ -1,3 +1,7 @@ +// 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. + #ifndef RUNNER_FLUTTER_WINDOW_H_ #define RUNNER_FLUTTER_WINDOW_H_ diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/main.cpp b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/main.cpp index fc17fec6140c..40492ac76edb 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/main.cpp +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/main.cpp @@ -1,3 +1,7 @@ +// 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. + #include #include #include diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.cpp b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.cpp index 2d6636ab6bc6..4dd13b6d1db9 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.cpp +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.cpp @@ -1,3 +1,7 @@ +// 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. + #include "run_loop.h" #include diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.h b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.h index 5f2c4a9ad7d3..12aaab42c59b 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.h +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.h @@ -1,3 +1,7 @@ +// 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. + #ifndef RUNNER_RUN_LOOP_H_ #define RUNNER_RUN_LOOP_H_ diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.cpp b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.cpp index 37501e5db777..c408cb3f7a74 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.cpp +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.cpp @@ -1,3 +1,7 @@ +// 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. + #include "utils.h" #include diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.h b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.h index d792603bb139..2754c7a7f9ef 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.h +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.h @@ -1,3 +1,7 @@ +// 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. + #ifndef RUNNER_UTILS_H_ #define RUNNER_UTILS_H_ diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.cpp b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.cpp index c63ad013b02d..878b64afe276 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.cpp +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.cpp @@ -1,3 +1,7 @@ +// 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. + #include "win32_window.h" #include diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.h b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.h index 4ae64a12b465..99e24a555afa 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.h +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.h @@ -1,3 +1,7 @@ +// 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. + #ifndef RUNNER_WIN32_WINDOW_H_ #define RUNNER_WIN32_WINDOW_H_ diff --git a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/MethodCallHandlerImpl.java b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/MethodCallHandlerImpl.java index 2ca6b7ce3fde..7a4b37488e69 100644 --- a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/MethodCallHandlerImpl.java +++ b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/MethodCallHandlerImpl.java @@ -1,3 +1,7 @@ +// 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. + package io.flutter.plugins.urllauncher; import android.os.Bundle; diff --git a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java index 44ecc337c43b..a6f29e1af68d 100644 --- a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java +++ b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java @@ -1,3 +1,7 @@ +// 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. + package io.flutter.plugins.urllauncher; import android.app.Activity; diff --git a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java index 17af0abda23c..79198200c526 100644 --- a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java +++ b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java @@ -1,3 +1,7 @@ +// 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. + package io.flutter.plugins.urllauncher; import android.util.Log; diff --git a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java index 7c6978fd657d..160e24e331d3 100644 --- a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java +++ b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java @@ -1,3 +1,7 @@ +// 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. + package io.flutter.plugins.urllauncher; import android.annotation.TargetApi; diff --git a/packages/url_launcher/url_launcher/android/src/test/java/io/flutter/plugins/urllauncher/MethodCallHandlerImplTest.java b/packages/url_launcher/url_launcher/android/src/test/java/io/flutter/plugins/urllauncher/MethodCallHandlerImplTest.java index e759dedd5f75..e9d27e3e3b01 100644 --- a/packages/url_launcher/url_launcher/android/src/test/java/io/flutter/plugins/urllauncher/MethodCallHandlerImplTest.java +++ b/packages/url_launcher/url_launcher/android/src/test/java/io/flutter/plugins/urllauncher/MethodCallHandlerImplTest.java @@ -1,3 +1,7 @@ +// 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. + package io.flutter.plugins.urllauncher; import static org.mockito.Matchers.any; diff --git a/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/EmbeddingV1ActivityTest.java b/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/EmbeddingV1ActivityTest.java index b144786fe925..9002012ce18c 100644 --- a/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/EmbeddingV1ActivityTest.java +++ b/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/EmbeddingV1ActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.urllauncherexample; import androidx.test.rule.ActivityTestRule; diff --git a/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/MainActivityTest.java b/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/MainActivityTest.java index 5b50523f7f40..7760741b2127 100644 --- a/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/MainActivityTest.java +++ b/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/MainActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.urllauncherexample; import androidx.test.rule.ActivityTestRule; diff --git a/packages/url_launcher/url_launcher/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher/example/integration_test/url_launcher_test.dart index 80d21b740c1e..9e7b04b38b46 100644 --- a/packages/url_launcher/url_launcher/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher/example/integration_test/url_launcher_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. // TODO(egarciad): Remove once integration_test is migrated to null safety. // @dart = 2.9 diff --git a/packages/url_launcher/url_launcher/example/linux/main.cc b/packages/url_launcher/url_launcher/example/linux/main.cc index e7c5c5437037..612325f29cd7 100644 --- a/packages/url_launcher/url_launcher/example/linux/main.cc +++ b/packages/url_launcher/url_launcher/example/linux/main.cc @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "my_application.h" int main(int argc, char** argv) { diff --git a/packages/url_launcher/url_launcher/example/linux/my_application.cc b/packages/url_launcher/url_launcher/example/linux/my_application.cc index f079e19eb396..1a873cdf7b19 100644 --- a/packages/url_launcher/url_launcher/example/linux/my_application.cc +++ b/packages/url_launcher/url_launcher/example/linux/my_application.cc @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "my_application.h" #include diff --git a/packages/url_launcher/url_launcher/example/linux/my_application.h b/packages/url_launcher/url_launcher/example/linux/my_application.h index 72271d5e4170..b3d62442a005 100644 --- a/packages/url_launcher/url_launcher/example/linux/my_application.h +++ b/packages/url_launcher/url_launcher/example/linux/my_application.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef FLUTTER_MY_APPLICATION_H_ #define FLUTTER_MY_APPLICATION_H_ diff --git a/packages/url_launcher/url_launcher/example/macos/Runner/AppDelegate.swift b/packages/url_launcher/url_launcher/example/macos/Runner/AppDelegate.swift index d53ef6437726..ca19fe95f8cf 100644 --- a/packages/url_launcher/url_launcher/example/macos/Runner/AppDelegate.swift +++ b/packages/url_launcher/url_launcher/example/macos/Runner/AppDelegate.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/url_launcher/url_launcher/example/macos/Runner/MainFlutterWindow.swift b/packages/url_launcher/url_launcher/example/macos/Runner/MainFlutterWindow.swift index 2722837ec918..2ce11b78604b 100644 --- a/packages/url_launcher/url_launcher/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/url_launcher/url_launcher/example/macos/Runner/MainFlutterWindow.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/url_launcher/url_launcher/example/test_driver/integration_test.dart b/packages/url_launcher/url_launcher/example/test_driver/integration_test.dart index e56756f38cbd..3e3caf844689 100644 --- a/packages/url_launcher/url_launcher/example/test_driver/integration_test.dart +++ b/packages/url_launcher/url_launcher/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. // TODO(egarciad): Remove once flutter_driver is migrated to null safety. // @dart = 2.9 diff --git a/packages/url_launcher/url_launcher/example/web/index.html b/packages/url_launcher/url_launcher/example/web/index.html index 3d1872c20298..1127c04820dd 100644 --- a/packages/url_launcher/url_launcher/example/web/index.html +++ b/packages/url_launcher/url_launcher/example/web/index.html @@ -1,4 +1,7 @@ + diff --git a/packages/url_launcher/url_launcher/example/windows/runner/flutter_window.cpp b/packages/url_launcher/url_launcher/example/windows/runner/flutter_window.cpp index c422723045ca..b7d078e4d4a5 100644 --- a/packages/url_launcher/url_launcher/example/windows/runner/flutter_window.cpp +++ b/packages/url_launcher/url_launcher/example/windows/runner/flutter_window.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "flutter_window.h" #include diff --git a/packages/url_launcher/url_launcher/example/windows/runner/flutter_window.h b/packages/url_launcher/url_launcher/example/windows/runner/flutter_window.h index b663ddd50125..9b4ef089621b 100644 --- a/packages/url_launcher/url_launcher/example/windows/runner/flutter_window.h +++ b/packages/url_launcher/url_launcher/example/windows/runner/flutter_window.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef RUNNER_FLUTTER_WINDOW_H_ #define RUNNER_FLUTTER_WINDOW_H_ diff --git a/packages/url_launcher/url_launcher/example/windows/runner/main.cpp b/packages/url_launcher/url_launcher/example/windows/runner/main.cpp index fc17fec6140c..e74157ed999a 100644 --- a/packages/url_launcher/url_launcher/example/windows/runner/main.cpp +++ b/packages/url_launcher/url_launcher/example/windows/runner/main.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include #include #include diff --git a/packages/url_launcher/url_launcher/example/windows/runner/run_loop.cpp b/packages/url_launcher/url_launcher/example/windows/runner/run_loop.cpp index 2d6636ab6bc6..ee2e2fd5eae9 100644 --- a/packages/url_launcher/url_launcher/example/windows/runner/run_loop.cpp +++ b/packages/url_launcher/url_launcher/example/windows/runner/run_loop.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "run_loop.h" #include diff --git a/packages/url_launcher/url_launcher/example/windows/runner/run_loop.h b/packages/url_launcher/url_launcher/example/windows/runner/run_loop.h index 5f2c4a9ad7d3..a24c47f2e55f 100644 --- a/packages/url_launcher/url_launcher/example/windows/runner/run_loop.h +++ b/packages/url_launcher/url_launcher/example/windows/runner/run_loop.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef RUNNER_RUN_LOOP_H_ #define RUNNER_RUN_LOOP_H_ diff --git a/packages/url_launcher/url_launcher/example/windows/runner/utils.cpp b/packages/url_launcher/url_launcher/example/windows/runner/utils.cpp index 37501e5db777..9eba364025d0 100644 --- a/packages/url_launcher/url_launcher/example/windows/runner/utils.cpp +++ b/packages/url_launcher/url_launcher/example/windows/runner/utils.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "utils.h" #include diff --git a/packages/url_launcher/url_launcher/example/windows/runner/utils.h b/packages/url_launcher/url_launcher/example/windows/runner/utils.h index d792603bb139..640587eb23ab 100644 --- a/packages/url_launcher/url_launcher/example/windows/runner/utils.h +++ b/packages/url_launcher/url_launcher/example/windows/runner/utils.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef RUNNER_UTILS_H_ #define RUNNER_UTILS_H_ diff --git a/packages/url_launcher/url_launcher/example/windows/runner/win32_window.cpp b/packages/url_launcher/url_launcher/example/windows/runner/win32_window.cpp index c63ad013b02d..97628170c2c2 100644 --- a/packages/url_launcher/url_launcher/example/windows/runner/win32_window.cpp +++ b/packages/url_launcher/url_launcher/example/windows/runner/win32_window.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "win32_window.h" #include diff --git a/packages/url_launcher/url_launcher/example/windows/runner/win32_window.h b/packages/url_launcher/url_launcher/example/windows/runner/win32_window.h index 4ae64a12b465..59b78382b27d 100644 --- a/packages/url_launcher/url_launcher/example/windows/runner/win32_window.h +++ b/packages/url_launcher/url_launcher/example/windows/runner/win32_window.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef RUNNER_WIN32_WINDOW_H_ #define RUNNER_WIN32_WINDOW_H_ diff --git a/packages/url_launcher/url_launcher_linux/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_linux/example/integration_test/url_launcher_test.dart index e1008fddd4e1..aa668ed747b5 100644 --- a/packages/url_launcher/url_launcher_linux/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_linux/example/integration_test/url_launcher_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/url_launcher/url_launcher_linux/example/linux/main.cc b/packages/url_launcher/url_launcher_linux/example/linux/main.cc index e7c5c5437037..612325f29cd7 100644 --- a/packages/url_launcher/url_launcher_linux/example/linux/main.cc +++ b/packages/url_launcher/url_launcher_linux/example/linux/main.cc @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "my_application.h" int main(int argc, char** argv) { diff --git a/packages/url_launcher/url_launcher_linux/example/linux/my_application.cc b/packages/url_launcher/url_launcher_linux/example/linux/my_application.cc index f079e19eb396..1a873cdf7b19 100644 --- a/packages/url_launcher/url_launcher_linux/example/linux/my_application.cc +++ b/packages/url_launcher/url_launcher_linux/example/linux/my_application.cc @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "my_application.h" #include diff --git a/packages/url_launcher/url_launcher_linux/example/linux/my_application.h b/packages/url_launcher/url_launcher_linux/example/linux/my_application.h index 72271d5e4170..b3d62442a005 100644 --- a/packages/url_launcher/url_launcher_linux/example/linux/my_application.h +++ b/packages/url_launcher/url_launcher_linux/example/linux/my_application.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef FLUTTER_MY_APPLICATION_H_ #define FLUTTER_MY_APPLICATION_H_ diff --git a/packages/url_launcher/url_launcher_linux/example/test_driver/integration_test.dart b/packages/url_launcher/url_launcher_linux/example/test_driver/integration_test.dart index a8a56aa90f6a..c62ef5dba800 100644 --- a/packages/url_launcher/url_launcher_linux/example/test_driver/integration_test.dart +++ b/packages/url_launcher/url_launcher_linux/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/url_launcher/url_launcher_linux/lib/url_launcher_linux.dart b/packages/url_launcher/url_launcher_linux/lib/url_launcher_linux.dart deleted file mode 100644 index 18f7af1836ce..000000000000 --- a/packages/url_launcher/url_launcher_linux/lib/url_launcher_linux.dart +++ /dev/null @@ -1,3 +0,0 @@ -// The url_launcher_platform_interface defaults to MethodChannelUrlLauncher -// as its instance, which is all the Linux implementation needs. This file -// is here to silence warnings when publishing to pub. diff --git a/packages/url_launcher/url_launcher_macos/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_macos/example/integration_test/url_launcher_test.dart index d0c1a8bd7325..6775a637f7dc 100644 --- a/packages/url_launcher/url_launcher_macos/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_macos/example/integration_test/url_launcher_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/url_launcher/url_launcher_macos/example/macos/Runner/AppDelegate.swift b/packages/url_launcher/url_launcher_macos/example/macos/Runner/AppDelegate.swift index d53ef6437726..ca19fe95f8cf 100644 --- a/packages/url_launcher/url_launcher_macos/example/macos/Runner/AppDelegate.swift +++ b/packages/url_launcher/url_launcher_macos/example/macos/Runner/AppDelegate.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/url_launcher/url_launcher_macos/example/macos/Runner/MainFlutterWindow.swift b/packages/url_launcher/url_launcher_macos/example/macos/Runner/MainFlutterWindow.swift index 2722837ec918..2ce11b78604b 100644 --- a/packages/url_launcher/url_launcher_macos/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/url_launcher/url_launcher_macos/example/macos/Runner/MainFlutterWindow.swift @@ -1,3 +1,7 @@ +// Copyright 2017 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 Cocoa import FlutterMacOS diff --git a/packages/url_launcher/url_launcher_macos/example/test_driver/integration_test.dart b/packages/url_launcher/url_launcher_macos/example/test_driver/integration_test.dart index a8a56aa90f6a..c62ef5dba800 100644 --- a/packages/url_launcher/url_launcher_macos/example/test_driver/integration_test.dart +++ b/packages/url_launcher/url_launcher_macos/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/url_launcher/url_launcher_macos/lib/url_launcher_macos.dart b/packages/url_launcher/url_launcher_macos/lib/url_launcher_macos.dart deleted file mode 100644 index 5a1956c9a9c1..000000000000 --- a/packages/url_launcher/url_launcher_macos/lib/url_launcher_macos.dart +++ /dev/null @@ -1,3 +0,0 @@ -// The url_launcher_platform_interface defaults to MethodChannelUrlLauncher -// as its instance, which is all the macOS implementation needs. This file -// is here to silence warnings when publishing to pub. diff --git a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart index 73d3bf355d67..7e72b5ff1da3 100644 --- a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart +++ b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart @@ -1,3 +1,7 @@ +// Copyright 2017 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' as _i4; import 'dart:html' as _i2; import 'dart:math' as _i5; diff --git a/packages/url_launcher/url_launcher_web/example/run_test.sh b/packages/url_launcher/url_launcher_web/example/run_test.sh index b243f2938b1f..5d235967ac3d 100755 --- a/packages/url_launcher/url_launcher_web/example/run_test.sh +++ b/packages/url_launcher/url_launcher_web/example/run_test.sh @@ -1,4 +1,8 @@ #!/usr/bin/bash +# Copyright 2017 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. + if pgrep -lf chromedriver > /dev/null; then echo "chromedriver is running." diff --git a/packages/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart b/packages/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart index 334f52186d9d..11f9b24dc878 100644 --- a/packages/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart +++ b/packages/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'package:flutter_test/flutter_test.dart'; void main() { diff --git a/packages/url_launcher/url_launcher_windows/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_windows/example/integration_test/url_launcher_test.dart index e1008fddd4e1..aa668ed747b5 100644 --- a/packages/url_launcher/url_launcher_windows/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_windows/example/integration_test/url_launcher_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/url_launcher/url_launcher_windows/example/test_driver/integration_test.dart b/packages/url_launcher/url_launcher_windows/example/test_driver/integration_test.dart index a8a56aa90f6a..c62ef5dba800 100644 --- a/packages/url_launcher/url_launcher_windows/example/test_driver/integration_test.dart +++ b/packages/url_launcher/url_launcher_windows/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/url_launcher/url_launcher_windows/example/windows/runner/flutter_window.cpp b/packages/url_launcher/url_launcher_windows/example/windows/runner/flutter_window.cpp index c422723045ca..b7d078e4d4a5 100644 --- a/packages/url_launcher/url_launcher_windows/example/windows/runner/flutter_window.cpp +++ b/packages/url_launcher/url_launcher_windows/example/windows/runner/flutter_window.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "flutter_window.h" #include diff --git a/packages/url_launcher/url_launcher_windows/example/windows/runner/flutter_window.h b/packages/url_launcher/url_launcher_windows/example/windows/runner/flutter_window.h index b663ddd50125..9b4ef089621b 100644 --- a/packages/url_launcher/url_launcher_windows/example/windows/runner/flutter_window.h +++ b/packages/url_launcher/url_launcher_windows/example/windows/runner/flutter_window.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef RUNNER_FLUTTER_WINDOW_H_ #define RUNNER_FLUTTER_WINDOW_H_ diff --git a/packages/url_launcher/url_launcher_windows/example/windows/runner/main.cpp b/packages/url_launcher/url_launcher_windows/example/windows/runner/main.cpp index fc17fec6140c..e74157ed999a 100644 --- a/packages/url_launcher/url_launcher_windows/example/windows/runner/main.cpp +++ b/packages/url_launcher/url_launcher_windows/example/windows/runner/main.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include #include #include diff --git a/packages/url_launcher/url_launcher_windows/example/windows/runner/run_loop.cpp b/packages/url_launcher/url_launcher_windows/example/windows/runner/run_loop.cpp index 2d6636ab6bc6..ee2e2fd5eae9 100644 --- a/packages/url_launcher/url_launcher_windows/example/windows/runner/run_loop.cpp +++ b/packages/url_launcher/url_launcher_windows/example/windows/runner/run_loop.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "run_loop.h" #include diff --git a/packages/url_launcher/url_launcher_windows/example/windows/runner/run_loop.h b/packages/url_launcher/url_launcher_windows/example/windows/runner/run_loop.h index 5f2c4a9ad7d3..a24c47f2e55f 100644 --- a/packages/url_launcher/url_launcher_windows/example/windows/runner/run_loop.h +++ b/packages/url_launcher/url_launcher_windows/example/windows/runner/run_loop.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef RUNNER_RUN_LOOP_H_ #define RUNNER_RUN_LOOP_H_ diff --git a/packages/url_launcher/url_launcher_windows/example/windows/runner/utils.cpp b/packages/url_launcher/url_launcher_windows/example/windows/runner/utils.cpp index 37501e5db777..9eba364025d0 100644 --- a/packages/url_launcher/url_launcher_windows/example/windows/runner/utils.cpp +++ b/packages/url_launcher/url_launcher_windows/example/windows/runner/utils.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "utils.h" #include diff --git a/packages/url_launcher/url_launcher_windows/example/windows/runner/utils.h b/packages/url_launcher/url_launcher_windows/example/windows/runner/utils.h index d792603bb139..640587eb23ab 100644 --- a/packages/url_launcher/url_launcher_windows/example/windows/runner/utils.h +++ b/packages/url_launcher/url_launcher_windows/example/windows/runner/utils.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef RUNNER_UTILS_H_ #define RUNNER_UTILS_H_ diff --git a/packages/url_launcher/url_launcher_windows/example/windows/runner/win32_window.cpp b/packages/url_launcher/url_launcher_windows/example/windows/runner/win32_window.cpp index c63ad013b02d..97628170c2c2 100644 --- a/packages/url_launcher/url_launcher_windows/example/windows/runner/win32_window.cpp +++ b/packages/url_launcher/url_launcher_windows/example/windows/runner/win32_window.cpp @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #include "win32_window.h" #include diff --git a/packages/url_launcher/url_launcher_windows/example/windows/runner/win32_window.h b/packages/url_launcher/url_launcher_windows/example/windows/runner/win32_window.h index 4ae64a12b465..59b78382b27d 100644 --- a/packages/url_launcher/url_launcher_windows/example/windows/runner/win32_window.h +++ b/packages/url_launcher/url_launcher_windows/example/windows/runner/win32_window.h @@ -1,3 +1,7 @@ +// Copyright 2017 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. + #ifndef RUNNER_WIN32_WINDOW_H_ #define RUNNER_WIN32_WINDOW_H_ diff --git a/packages/url_launcher/url_launcher_windows/lib/url_launcher_windows.dart b/packages/url_launcher/url_launcher_windows/lib/url_launcher_windows.dart deleted file mode 100644 index 83435f981838..000000000000 --- a/packages/url_launcher/url_launcher_windows/lib/url_launcher_windows.dart +++ /dev/null @@ -1,3 +0,0 @@ -// The url_launcher_platform_interface defaults to MethodChannelUrlLauncher -// as its instance, which is all the Windows implementation needs. This file -// is here to silence warnings when publishing to pub. diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/CustomSSLSocketFactory.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/CustomSSLSocketFactory.java index a7b609f4d930..adccd2e2cdcd 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/CustomSSLSocketFactory.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/CustomSSLSocketFactory.java @@ -1,3 +1,7 @@ +// 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. + package io.flutter.plugins.videoplayer; import java.io.IOException; diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java index 053e3faa9694..0d108caa0597 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java @@ -1,3 +1,7 @@ +// 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. + // Autogenerated from Pigeon (v0.1.19), do not edit directly. // See also: https://pub.dev/packages/pigeon diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java index c3a31432e896..bba301666993 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java @@ -1,3 +1,7 @@ +// 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. + package io.flutter.plugins.videoplayer; import static com.google.android.exoplayer2.Player.REPEAT_MODE_ALL; diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerOptions.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerOptions.java index 7381f4a941a5..fa51fbf50b43 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerOptions.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerOptions.java @@ -1,3 +1,7 @@ +// 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. + package io.flutter.plugins.videoplayer; class VideoPlayerOptions { diff --git a/packages/video_player/video_player/example/android/app/src/test/java/io/flutter/plugins/videoplayerexample/FlutterActivityTest.java b/packages/video_player/video_player/example/android/app/src/test/java/io/flutter/plugins/videoplayerexample/FlutterActivityTest.java index 0286237cf7ea..e62e70cd54ad 100644 --- a/packages/video_player/video_player/example/android/app/src/test/java/io/flutter/plugins/videoplayerexample/FlutterActivityTest.java +++ b/packages/video_player/video_player/example/android/app/src/test/java/io/flutter/plugins/videoplayerexample/FlutterActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.videoplayerexample; import static org.mockito.Mockito.mock; diff --git a/packages/video_player/video_player/example/integration_test/video_player_test.dart b/packages/video_player/video_player/example/integration_test/video_player_test.dart index 9e273e02dc4d..b39bb087a21c 100644 --- a/packages/video_player/video_player/example/integration_test/video_player_test.dart +++ b/packages/video_player/video_player/example/integration_test/video_player_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. // TODO(amirh): Remove this once flutter_driver supports null safety. // https://github.com/flutter/flutter/issues/71379 diff --git a/packages/video_player/video_player/example/test_driver/integration_test.dart b/packages/video_player/video_player/example/test_driver/integration_test.dart index 7873abae2996..ca76cd86091a 100644 --- a/packages/video_player/video_player/example/test_driver/integration_test.dart +++ b/packages/video_player/video_player/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. // TODO(egarciad): Remove once Flutter driver is migrated to null safety. // @dart = 2.9 diff --git a/packages/video_player/video_player/example/test_driver/video_player.dart b/packages/video_player/video_player/example/test_driver/video_player.dart index c1ced19e9b7e..b942d20c17ba 100644 --- a/packages/video_player/video_player/example/test_driver/video_player.dart +++ b/packages/video_player/video_player/example/test_driver/video_player.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. // TODO(egarciad): Remove once Flutter driver is migrated to null safety. // @dart = 2.9 diff --git a/packages/video_player/video_player/example/test_driver/video_player_test.dart b/packages/video_player/video_player/example/test_driver/video_player_test.dart index fcbdbb274f7a..232a88d89926 100644 --- a/packages/video_player/video_player/example/test_driver/video_player_test.dart +++ b/packages/video_player/video_player/example/test_driver/video_player_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. // TODO(egarciad): Remove once Flutter driver is migrated to null safety. // @dart = 2.9 diff --git a/packages/video_player/video_player/example/web/index.html b/packages/video_player/video_player/example/web/index.html index b1c45bdcd57f..763ea662e8e3 100644 --- a/packages/video_player/video_player/example/web/index.html +++ b/packages/video_player/video_player/example/web/index.html @@ -1,4 +1,7 @@ + diff --git a/packages/video_player/video_player/ios/Classes/messages.h b/packages/video_player/video_player/ios/Classes/messages.h index 80137c9d61f5..8e2ae130643f 100644 --- a/packages/video_player/video_player/ios/Classes/messages.h +++ b/packages/video_player/video_player/ios/Classes/messages.h @@ -1,3 +1,7 @@ +// 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. + // Autogenerated from Pigeon (v0.1.19), do not edit directly. // See also: https://pub.dev/packages/pigeon #import diff --git a/packages/video_player/video_player/ios/Classes/messages.m b/packages/video_player/video_player/ios/Classes/messages.m index 3f787fcdf92d..368601b9d6cb 100644 --- a/packages/video_player/video_player/ios/Classes/messages.m +++ b/packages/video_player/video_player/ios/Classes/messages.m @@ -1,3 +1,7 @@ +// 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. + // Autogenerated from Pigeon (v0.1.19), do not edit directly. // See also: https://pub.dev/packages/pigeon #import "messages.h" diff --git a/packages/video_player/video_player/pigeons/messages.dart b/packages/video_player/video_player/pigeons/messages.dart index ebef9e526b6a..33ca12e7969e 100644 --- a/packages/video_player/video_player/pigeons/messages.dart +++ b/packages/video_player/video_player/pigeons/messages.dart @@ -1,3 +1,7 @@ +// 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:pigeon/pigeon_lib.dart'; diff --git a/packages/video_player/video_player_platform_interface/lib/messages.dart b/packages/video_player/video_player_platform_interface/lib/messages.dart index dc5237f2e151..96ff20ea907f 100644 --- a/packages/video_player/video_player_platform_interface/lib/messages.dart +++ b/packages/video_player/video_player_platform_interface/lib/messages.dart @@ -1,3 +1,7 @@ +// 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. + // 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 diff --git a/packages/video_player/video_player_platform_interface/lib/test.dart b/packages/video_player/video_player_platform_interface/lib/test.dart index 457a838e8d24..7365f6dfb391 100644 --- a/packages/video_player/video_player_platform_interface/lib/test.dart +++ b/packages/video_player/video_player_platform_interface/lib/test.dart @@ -1,3 +1,7 @@ +// 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. + // 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 diff --git a/packages/video_player/video_player_web/lib/video_player_web.dart b/packages/video_player/video_player_web/lib/video_player_web.dart index 18f9e5e58cd6..d22c8f4f983c 100644 --- a/packages/video_player/video_player_web/lib/video_player_web.dart +++ b/packages/video_player/video_player_web/lib/video_player_web.dart @@ -1,3 +1,7 @@ +// 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. + import 'dart:async'; import 'dart:html'; import 'src/shims/dart_ui.dart' as ui; diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/DisplayListenerProxy.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/DisplayListenerProxy.java index 1273e7349620..e98c2b0fc4da 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/DisplayListenerProxy.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/DisplayListenerProxy.java @@ -1,3 +1,7 @@ +// Copyright 2018 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. + package io.flutter.plugins.webviewflutter; import static android.hardware.display.DisplayManager.DisplayListener; diff --git a/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1ActivityTest.java b/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1ActivityTest.java index 07f9bf2f7802..aebeb6d0a3b0 100644 --- a/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1ActivityTest.java +++ b/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1ActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.webviewflutterexample; import androidx.test.rule.ActivityTestRule; diff --git a/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/MainActivityTest.java b/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/MainActivityTest.java index a9b1a9412cbd..e3d794e52dcc 100644 --- a/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/MainActivityTest.java +++ b/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/MainActivityTest.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.webviewflutterexample; import androidx.test.rule.ActivityTestRule; 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 d91ccc53b231..20391f70d2ff 100644 --- a/packages/webview_flutter/example/integration_test/webview_flutter_test.dart +++ b/packages/webview_flutter/example/integration_test/webview_flutter_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/webview_flutter/example/test_driver/integration_test.dart b/packages/webview_flutter/example/test_driver/integration_test.dart index a8a56aa90f6a..c62ef5dba800 100644 --- a/packages/webview_flutter/example/test_driver/integration_test.dart +++ b/packages/webview_flutter/example/test_driver/integration_test.dart @@ -1,6 +1,6 @@ -// 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. +// Copyright 2019, the Chromium project 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 diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/android/app/src/main/java/io/flutter/plugins/wifi_info_flutter_example/MainActivity.java b/packages/wifi_info_flutter/wifi_info_flutter/example/android/app/src/main/java/io/flutter/plugins/wifi_info_flutter_example/MainActivity.java index 87e41d0dea51..f3747669929d 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/android/app/src/main/java/io/flutter/plugins/wifi_info_flutter_example/MainActivity.java +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/android/app/src/main/java/io/flutter/plugins/wifi_info_flutter_example/MainActivity.java @@ -1,3 +1,7 @@ +// Copyright 2017 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. + package io.flutter.plugins.wifi_info_flutter_example; import io.flutter.embedding.android.FlutterActivity; diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/AppDelegate.h b/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/AppDelegate.h index 36e21bbf9cf4..31fc381e7066 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/AppDelegate.h +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/AppDelegate.h @@ -1,3 +1,7 @@ +// Copyright 2017 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 #import diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/AppDelegate.m b/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/AppDelegate.m index 70e83933db14..558d1adc9a4a 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/AppDelegate.m +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/AppDelegate.m @@ -1,3 +1,7 @@ +// Copyright 2017 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 "AppDelegate.h" #import "GeneratedPluginRegistrant.h" diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/main.m b/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/main.m index dff6597e4513..f451b14cb751 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/main.m +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/main.m @@ -1,3 +1,7 @@ +// Copyright 2017 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 #import #import "AppDelegate.h" diff --git a/script/build_all_plugins_app.sh b/script/build_all_plugins_app.sh index 27726bd53426..cfd783e64d1e 100755 --- a/script/build_all_plugins_app.sh +++ b/script/build_all_plugins_app.sh @@ -1,4 +1,7 @@ #!/bin/bash +# 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. # Usage: # diff --git a/script/check_publish.sh b/script/check_publish.sh index c92de4be2e08..ead4aa3b2b34 100755 --- a/script/check_publish.sh +++ b/script/check_publish.sh @@ -1,4 +1,8 @@ #!/bin/bash +# 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. + set -e # This script checks to make sure that each of the plugins *could* be published. diff --git a/script/common.sh b/script/common.sh index 28c37540af88..9668688f50b2 100644 --- a/script/common.sh +++ b/script/common.sh @@ -1,4 +1,7 @@ #!/bin/bash +# 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. function error() { echo "$@" 1>&2 diff --git a/script/incremental_build.sh b/script/incremental_build.sh index 38a4d2d8edc7..b46f500ae414 100755 --- a/script/incremental_build.sh +++ b/script/incremental_build.sh @@ -1,4 +1,8 @@ #!/bin/bash +# 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. + set -e readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" diff --git a/script/tool/lib/src/license_check_command.dart b/script/tool/lib/src/license_check_command.dart new file mode 100644 index 000000000000..4e0e5931d3ee --- /dev/null +++ b/script/tool/lib/src/license_check_command.dart @@ -0,0 +1,209 @@ +// 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. + +import 'dart:async'; + +import 'package:file/file.dart'; +import 'package:path/path.dart' as p; + +import 'common.dart'; + +const Set _codeFileExtensions = { + '.c', + '.cc', + '.cpp', + '.dart', + '.h', + '.html', + '.java', + '.m', + '.mm', + '.swift', + '.sh', +}; + +// Basenames without extensions of files to ignore. +const Set _ignoreBasenameList = { + 'flutter_export_environment', + 'GeneratedPluginRegistrant', + 'generated_plugin_registrant', +}; + +// File suffixes that otherwise match _codeFileExtensions to ignore. +const Set _ignoreSuffixList = { + '.g.dart', // Generated API code. + '.mocks.dart', // Generated by Mockito. +}; + +// Full basenames of files to ignore. +const Set _ignoredFullBasenameList = { + 'resource.h', // Generated by VS. +}; + +// Copyright and license regexes. +// +// These are intentionally very simple, since almost all source in this +// repository should be using the same license text, comment style, etc., so +// they shouldn't need to be very flexible. Complexity can be added as-needed +// on a case-by-case basis. +final RegExp _copyrightRegex = + RegExp(r'^(?://|#|'), + }; + + for (final File file in codeFiles) { + _print('Checking ${file.path}'); + final String content = await file.readAsString(); + + final RegExpMatch copyright = _copyrightRegex.firstMatch(content); + if (copyright == null) { + filesWithoutDetectedCopyright.add(file); + continue; + } + final String author = copyright.group(1); + if (!_firstPartyAuthors.contains(author) && + !p.split(file.path).contains('third_party')) { + misplacedThirdPartyFiles.add(file); + } + + final String bsdLicense = + bsdLicenseBlockByExtension[p.extension(file.path)] ?? + defaultBsdLicenseBlock; + if (!content.contains(bsdLicense) && + !_workivaLicenseRegex.hasMatch(content)) { + filesWithoutDetectedLicense.add(file); + } + } + _print('\n\n'); + + // Sort by path for more usable output. + final pathCompare = (File a, File b) => a.path.compareTo(b.path); + filesWithoutDetectedCopyright.sort(pathCompare); + filesWithoutDetectedLicense.sort(pathCompare); + misplacedThirdPartyFiles.sort(pathCompare); + + if (filesWithoutDetectedCopyright.isNotEmpty) { + _print('No copyright line was found for the following files:'); + for (final File file in filesWithoutDetectedCopyright) { + _print(' ${file.path}'); + } + _print('Please check that they have a copyright and license block. ' + 'If they do, the license check may need to be updated to recognize its ' + 'format.\n'); + } + + if (filesWithoutDetectedLicense.isNotEmpty) { + _print('No recognized license was found for the following files:'); + for (final File file in filesWithoutDetectedLicense) { + _print(' ${file.path}'); + } + _print('Please check that they have a license at the top of the file. ' + 'If they do, the license check may need to be updated to recognize ' + 'either the license or the specific format of the license ' + 'block.\n'); + } + + if (misplacedThirdPartyFiles.isNotEmpty) { + _print('The following files do not have a recognized first-party author ' + 'but are not in a "third_party/" directory:'); + for (final File file in misplacedThirdPartyFiles) { + _print(' ${file.path}'); + } + _print('Please move these files to "third_party/".\n'); + } + + bool succeeded = filesWithoutDetectedCopyright.isEmpty && + filesWithoutDetectedLicense.isEmpty && + misplacedThirdPartyFiles.isEmpty; + if (succeeded) { + _print('All files passed validation!'); + } + return succeeded; + } + + bool _shouldIgnoreFile(File file) { + final String path = file.path; + return _ignoreBasenameList.contains(p.basenameWithoutExtension(path)) || + _ignoreSuffixList.any((String suffix) => + path.endsWith(suffix) || + _ignoredFullBasenameList.contains(p.basename(path))); + } + + Future> _getAllFiles() => packagesDir.parent + .list(recursive: true, followLinks: false) + .where((FileSystemEntity entity) => entity is File) + .map((FileSystemEntity file) => file as File) + .toList(); +} diff --git a/script/tool/lib/src/main.dart b/script/tool/lib/src/main.dart index fa81597237d7..329112931251 100644 --- a/script/tool/lib/src/main.dart +++ b/script/tool/lib/src/main.dart @@ -19,6 +19,7 @@ import 'drive_examples_command.dart'; import 'firebase_test_lab_command.dart'; import 'format_command.dart'; import 'java_test_command.dart'; +import 'license_check_command.dart'; import 'lint_podspecs_command.dart'; import 'list_command.dart'; import 'test_command.dart'; @@ -50,6 +51,7 @@ void main(List args) { ..addCommand(FirebaseTestLabCommand(packagesDir, fileSystem)) ..addCommand(FormatCommand(packagesDir, fileSystem)) ..addCommand(JavaTestCommand(packagesDir, fileSystem)) + ..addCommand(LicenseCheckCommand(packagesDir, fileSystem)) ..addCommand(LintPodspecsCommand(packagesDir, fileSystem)) ..addCommand(ListCommand(packagesDir, fileSystem)) ..addCommand(PublishCheckCommand(packagesDir, fileSystem)) diff --git a/script/tool/lib/src/publish_plugin_command.dart b/script/tool/lib/src/publish_plugin_command.dart index f7e3b5deeecf..f61a76947c9e 100644 --- a/script/tool/lib/src/publish_plugin_command.dart +++ b/script/tool/lib/src/publish_plugin_command.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'dart:async'; import 'dart:convert'; import 'dart:io'; diff --git a/script/tool/test/analyze_command_test.dart b/script/tool/test/analyze_command_test.dart index 9e7a42bbb680..63afb51c8595 100644 --- a/script/tool/test/analyze_command_test.dart +++ b/script/tool/test/analyze_command_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/analyze_command.dart'; diff --git a/script/tool/test/build_examples_command_test.dart b/script/tool/test/build_examples_command_test.dart index 65417525d710..e0213893db38 100644 --- a/script/tool/test/build_examples_command_test.dart +++ b/script/tool/test/build_examples_command_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/build_examples_command.dart'; diff --git a/script/tool/test/common_test.dart b/script/tool/test/common_test.dart index 0fb3ce74c373..a8deacc8e483 100644 --- a/script/tool/test/common_test.dart +++ b/script/tool/test/common_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'dart:io'; import 'package:args/command_runner.dart'; diff --git a/script/tool/test/drive_examples_command_test.dart b/script/tool/test/drive_examples_command_test.dart index f4bdd95c1664..7a8e9f3e9f95 100644 --- a/script/tool/test/drive_examples_command_test.dart +++ b/script/tool/test/drive_examples_command_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/common.dart'; diff --git a/script/tool/test/firebase_test_lab_test.dart b/script/tool/test/firebase_test_lab_test.dart index 97b977619d57..d11624671523 100644 --- a/script/tool/test/firebase_test_lab_test.dart +++ b/script/tool/test/firebase_test_lab_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'dart:io'; import 'package:args/command_runner.dart'; diff --git a/script/tool/test/license_check_command_test.dart b/script/tool/test/license_check_command_test.dart new file mode 100644 index 000000000000..524e72712360 --- /dev/null +++ b/script/tool/test/license_check_command_test.dart @@ -0,0 +1,306 @@ +// Copyright 2019 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. + +import 'package:args/command_runner.dart'; +import 'package:file/file.dart'; +import 'package:file/memory.dart'; +import 'package:flutter_plugin_tools/src/common.dart'; +import 'package:flutter_plugin_tools/src/license_check_command.dart'; +import 'package:test/test.dart'; + +void main() { + group('$LicenseCheckCommand', () { + CommandRunner runner; + FileSystem fileSystem; + List printedMessages; + Directory root; + + setUp(() { + fileSystem = MemoryFileSystem(); + final Directory packagesDir = + fileSystem.currentDirectory.childDirectory('packages'); + root = packagesDir.parent; + + printedMessages = []; + final LicenseCheckCommand command = LicenseCheckCommand( + packagesDir, + fileSystem, + print: (Object message) => printedMessages.add(message.toString()), + ); + runner = + CommandRunner('license_test', 'Test for $LicenseCheckCommand'); + runner.addCommand(command); + }); + + /// Writes a copyright+license block to [file], defaulting to a standard + /// block for this repository. + /// + /// [commentString] is added to the start of each line. + /// [prefix] is added to the start of the entire block. + /// [suffix] is added to the end of the entire block. + void _writeLicense( + File file, { + String comment = '// ', + String prefix = '', + String suffix = '', + String copyright = + 'Copyright 2019 The Chromium Authors. All rights reserved.', + List license = const [ + 'Use of this source code is governed by a BSD-style license that can be', + 'found in the LICENSE file.', + ], + }) { + List lines = ['$prefix$comment$copyright']; + for (String line in license) { + lines.add('$comment$line'); + } + file.writeAsStringSync(lines.join('\n') + suffix + '\n'); + } + + test('looks at only expected extensions', () async { + Map extensions = { + 'c': true, + 'cc': true, + 'cpp': true, + 'dart': true, + 'h': true, + 'html': true, + 'java': true, + 'json': false, + 'm': true, + 'md': false, + 'mm': true, + 'png': false, + 'swift': true, + 'sh': true, + 'yaml': false, + }; + + const String filenameBase = 'a_file'; + for (final String fileExtension in extensions.keys) { + root.childFile('$filenameBase.$fileExtension').createSync(); + } + + try { + await runner.run(['license-check']); + } on ToolExit { + // Ignore failure; the files are empty so the check is expected to fail, + // but this test isn't for that behavior. + } + + extensions.forEach((String fileExtension, bool shouldCheck) { + final Matcher logLineMatcher = + contains('Checking $filenameBase.$fileExtension'); + expect(printedMessages, + shouldCheck ? logLineMatcher : isNot(logLineMatcher)); + }); + }); + + test('ignore list overrides extension matches', () async { + List ignoredFiles = [ + // Ignored base names. + 'flutter_export_environment.sh', + 'GeneratedPluginRegistrant.java', + 'GeneratedPluginRegistrant.m', + 'generated_plugin_registrant.cc', + 'generated_plugin_registrant.cpp', + // Ignored path suffixes. + 'foo.g.dart', + 'foo.mocks.dart', + // Ignored files. + 'resource.h', + ]; + + for (final String name in ignoredFiles) { + root.childFile(name).createSync(); + } + + await runner.run(['license-check']); + + for (final String name in ignoredFiles) { + expect(printedMessages, isNot(contains('Checking $name'))); + } + }); + + test('passes if all checked files have license blocks', () async { + File checked = root.childFile('checked.cc'); + checked.createSync(); + _writeLicense(checked); + File not_checked = root.childFile('not_checked.md'); + not_checked.createSync(); + + await runner.run(['license-check']); + + // Sanity check that the test did actually check a file. + expect(printedMessages, contains('Checking checked.cc')); + expect(printedMessages, contains('All files passed validation!')); + }); + + test('handles the comment styles for all supported languages', () async { + File file_a = root.childFile('file_a.cc'); + file_a.createSync(); + _writeLicense(file_a, comment: '// '); + File file_b = root.childFile('file_b.sh'); + file_b.createSync(); + _writeLicense(file_b, comment: '# '); + File file_c = root.childFile('file_c.html'); + file_c.createSync(); + _writeLicense(file_c, comment: '', prefix: ''); + + await runner.run(['license-check']); + + // Sanity check that the test did actually check the files. + expect(printedMessages, contains('Checking file_a.cc')); + expect(printedMessages, contains('Checking file_b.sh')); + expect(printedMessages, contains('Checking file_c.html')); + expect(printedMessages, contains('All files passed validation!')); + }); + + test('fails if any checked files are missing license blocks', () async { + File good_a = root.childFile('good.cc'); + good_a.createSync(); + _writeLicense(good_a); + File good_b = root.childFile('good.h'); + good_b.createSync(); + _writeLicense(good_b); + root.childFile('bad.cc').createSync(); + root.childFile('bad.h').createSync(); + + await expectLater(() => runner.run(['license-check']), + throwsA(const TypeMatcher())); + + // Failure should give information about the problematic files. + expect(printedMessages, + contains('No copyright line was found for the following files:')); + expect(printedMessages, contains(' bad.cc')); + expect(printedMessages, contains(' bad.h')); + // Failure shouldn't print the success message. + expect(printedMessages, isNot(contains('All files passed validation!'))); + }); + + test('fails if any checked files are missing just the copyright', () async { + File good = root.childFile('good.cc'); + good.createSync(); + _writeLicense(good); + File bad = root.childFile('bad.cc'); + bad.createSync(); + _writeLicense(bad, copyright: ''); + + await expectLater(() => runner.run(['license-check']), + throwsA(const TypeMatcher())); + + // Failure should give information about the problematic files. + expect(printedMessages, + contains('No copyright line was found for the following files:')); + expect(printedMessages, contains(' bad.cc')); + // Failure shouldn't print the success message. + expect(printedMessages, isNot(contains('All files passed validation!'))); + }); + + test('fails if any checked files are missing just the license', () async { + File good = root.childFile('good.cc'); + good.createSync(); + _writeLicense(good); + File bad = root.childFile('bad.cc'); + bad.createSync(); + _writeLicense(bad, license: []); + + await expectLater(() => runner.run(['license-check']), + throwsA(const TypeMatcher())); + + // Failure should give information about the problematic files. + expect(printedMessages, + contains('No recognized license was found for the following files:')); + expect(printedMessages, contains(' bad.cc')); + // Failure shouldn't print the success message. + expect(printedMessages, isNot(contains('All files passed validation!'))); + }); + + test('fails if any third-party code is not in a third_party directory', + () async { + File thirdPartyFile = root.childFile('third_party.cc'); + thirdPartyFile.createSync(); + _writeLicense(thirdPartyFile, copyright: 'Copyright 2017 Someone Else'); + + await expectLater(() => runner.run(['license-check']), + throwsA(const TypeMatcher())); + + // Failure should give information about the problematic files. + expect( + printedMessages, + contains( + 'The following files do not have a recognized first-party author ' + 'but are not in a "third_party/" directory:')); + expect(printedMessages, contains(' third_party.cc')); + // Failure shouldn't print the success message. + expect(printedMessages, isNot(contains('All files passed validation!'))); + }); + + test('succeeds for third-party code in a third_party directory', () async { + File thirdPartyFile = root + .childDirectory('a_plugin') + .childDirectory('lib') + .childDirectory('src') + .childDirectory('third_party') + .childFile('file.cc'); + thirdPartyFile.createSync(recursive: true); + _writeLicense(thirdPartyFile, copyright: 'Copyright 2017 Someone Else'); + + await runner.run(['license-check']); + + // Sanity check that the test did actually check the file. + expect(printedMessages, + contains('Checking a_plugin/lib/src/third_party/file.cc')); + expect(printedMessages, contains('All files passed validation!')); + }); + + test('fails for licenses that the tool does not expect', () async { + File good = root.childFile('good.cc'); + good.createSync(); + _writeLicense(good); + File bad = root.childDirectory('third_party').childFile('bad.cc'); + bad.createSync(recursive: true); + _writeLicense(bad, license: [ + 'This program is free software: you can redistribute it and/or modify', + 'it under the terms of the GNU General Public License', + ]); + + await expectLater(() => runner.run(['license-check']), + throwsA(const TypeMatcher())); + + // Failure should give information about the problematic files. + expect(printedMessages, + contains('No recognized license was found for the following files:')); + expect(printedMessages, contains(' third_party/bad.cc')); + // Failure shouldn't print the success message. + expect(printedMessages, isNot(contains('All files passed validation!'))); + }); + + test('Apache is not recognized for new authors without validation changes', + () async { + File good = root.childFile('good.cc'); + good.createSync(); + _writeLicense(good); + File bad = root.childDirectory('third_party').childFile('bad.cc'); + bad.createSync(recursive: true); + _writeLicense( + bad, + copyright: 'Copyright 2017 Some New Authors', + license: [ + 'Licensed under the Apache License, Version 2.0', + ], + ); + + await expectLater(() => runner.run(['license-check']), + throwsA(const TypeMatcher())); + + // Failure should give information about the problematic files. + expect(printedMessages, + contains('No recognized license was found for the following files:')); + expect(printedMessages, contains(' third_party/bad.cc')); + // Failure shouldn't print the success message. + expect(printedMessages, isNot(contains('All files passed validation!'))); + }); + }); +} diff --git a/script/tool/test/lint_podspecs_command_test.dart b/script/tool/test/lint_podspecs_command_test.dart index 1c59d2d7e55a..2a3e60853d08 100644 --- a/script/tool/test/lint_podspecs_command_test.dart +++ b/script/tool/test/lint_podspecs_command_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'dart:io'; import 'package:args/command_runner.dart'; diff --git a/script/tool/test/list_command_test.dart b/script/tool/test/list_command_test.dart index 478625283dd0..d06f6d2ca464 100644 --- a/script/tool/test/list_command_test.dart +++ b/script/tool/test/list_command_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/list_command.dart'; diff --git a/script/tool/test/mocks.dart b/script/tool/test/mocks.dart index 3e17ff8efd32..35a4eb7cbacb 100644 --- a/script/tool/test/mocks.dart +++ b/script/tool/test/mocks.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'dart:async'; import 'dart:io' as io; diff --git a/script/tool/test/publish_plugin_command_test.dart b/script/tool/test/publish_plugin_command_test.dart index ada4bf08fd72..4f770b2054f9 100644 --- a/script/tool/test/publish_plugin_command_test.dart +++ b/script/tool/test/publish_plugin_command_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'dart:async'; import 'dart:convert'; import 'dart:io' as io; diff --git a/script/tool/test/test_command_test.dart b/script/tool/test/test_command_test.dart index 514e4c27190a..520f4c316f5c 100644 --- a/script/tool/test/test_command_test.dart +++ b/script/tool/test/test_command_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/test_command.dart'; diff --git a/script/tool/test/util.dart b/script/tool/test/util.dart index 1538d9b554e8..63cd5defbb27 100644 --- a/script/tool/test/util.dart +++ b/script/tool/test/util.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'dart:async'; import 'dart:io' as io; diff --git a/script/tool/test/version_check_test.dart b/script/tool/test/version_check_test.dart index ac0d378c2a26..400d4263357c 100644 --- a/script/tool/test/version_check_test.dart +++ b/script/tool/test/version_check_test.dart @@ -1,3 +1,7 @@ +// Copyright 2019 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. + import 'dart:async'; import 'dart:io'; From 3222a3e4458b659d98714722f3ad9577d07c5903 Mon Sep 17 00:00:00 2001 From: Balvinder Singh Gambhir Date: Wed, 17 Mar 2021 04:27:49 +0530 Subject: [PATCH 0274/1565] [image_picker] Endorse image_picker_for_web (#3717) --- packages/image_picker/image_picker/CHANGELOG.md | 4 ++++ packages/image_picker/image_picker/pubspec.yaml | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md index 4f2a054f1520..fc3d5c156a17 100644 --- a/packages/image_picker/image_picker/CHANGELOG.md +++ b/packages/image_picker/image_picker/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.3 + +* Endorse image_picker_for_web + ## 0.7.2+1 * Android: fixes an issue where videos could be wrongly picked with `.jpg` extension. diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index 9ea8e5ddcbd4..cd4089e58798 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker description: Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker -version: 0.7.2+1 +version: 0.7.3 flutter: plugin: @@ -12,12 +12,15 @@ flutter: pluginClass: ImagePickerPlugin ios: pluginClass: FLTImagePickerPlugin + web: + default_package: image_picker_for_web dependencies: flutter: sdk: flutter flutter_plugin_android_lifecycle: ^2.0.0 image_picker_platform_interface: ^2.0.0 + image_picker_for_web: ^2.0.0 dev_dependencies: flutter_test: From d7125cdb91c0ea6781bfc9ca8c570070592aa851 Mon Sep 17 00:00:00 2001 From: Guy Kogus Date: Wed, 17 Mar 2021 21:23:52 +0100 Subject: [PATCH 0275/1565] [google_maps_flutter_platform_interface] Mark constructors as const for ids (#3718) --- .../CHANGELOG.md | 4 ++ .../method_channel_google_maps_flutter.dart | 6 +- .../lib/src/types/camera.dart | 6 +- .../lib/src/types/circle.dart | 2 +- .../lib/src/types/maps_object.dart | 2 +- .../lib/src/types/marker.dart | 2 +- .../lib/src/types/polygon.dart | 4 +- .../lib/src/types/polyline.dart | 2 +- .../lib/src/types/tile_overlay.dart | 5 +- .../pubspec.yaml | 2 +- .../test/types/camera_test.dart | 3 +- .../test/types/maps_object_test.dart | 24 ++++---- .../test/types/maps_object_updates_test.dart | 60 ++++++++++--------- .../test/types/test_maps_object.dart | 5 +- .../test/types/tile_overlay_test.dart | 25 ++++---- .../test/types/tile_overlay_updates_test.dart | 57 +++++++++--------- .../test/types/tile_test.dart | 3 +- 17 files changed, 111 insertions(+), 101 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md index b0ad668c8ddc..e8b12f79220d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.2 + +* Mark constructors for CameraUpdate, CircleId, MapsObjectId, MarkerId, PolygonId, PolylineId and TileOverlayId as const + ## 2.0.1 * Update platform_plugin_interface version requirement. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart index 3d16127ab7a9..9d447701fdd8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart @@ -5,13 +5,13 @@ import 'dart:async'; import 'dart:typed_data'; -import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; import 'package:flutter/gestures.dart'; - +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; import 'package:stream_transform/stream_transform.dart'; + import '../types/tile_overlay_updates.dart'; import '../types/utils/tile_overlay.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart index 28acf35962b6..f15254104b0e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart @@ -109,7 +109,7 @@ class CameraPosition { /// Defines a camera move, supporting absolute moves as well as moves relative /// the current position. class CameraUpdate { - CameraUpdate._(this._json); + const CameraUpdate._(this._json); /// Returns a camera update that moves the camera to the specified position. static CameraUpdate newCameraPosition(CameraPosition cameraPosition) { @@ -176,7 +176,7 @@ class CameraUpdate { /// /// Equivalent to the result of calling `zoomBy(1.0)`. static CameraUpdate zoomIn() { - return CameraUpdate._(['zoomIn']); + return const CameraUpdate._(['zoomIn']); } /// Returns a camera update that zooms the camera out, bringing the camera @@ -184,7 +184,7 @@ class CameraUpdate { /// /// Equivalent to the result of calling `zoomBy(-1.0)`. static CameraUpdate zoomOut() { - return CameraUpdate._(['zoomOut']); + return const CameraUpdate._(['zoomOut']); } /// Returns a camera update that sets the camera zoom level. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart index e3198dfd6512..daf7c918f67a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart @@ -14,7 +14,7 @@ import 'types.dart'; @immutable class CircleId extends MapsObjectId { /// Creates an immutable identifier for a [Circle]. - CircleId(String value) : super(value); + const CircleId(String value) : super(value); } /// Draws a circle on the map. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart index 545d46272215..1e7932c7cde2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart @@ -14,7 +14,7 @@ class MapsObjectId { /// Creates an immutable object representing a [T] among [GoogleMap] Ts. /// /// An [AssertionError] will be thrown if [value] is null. - MapsObjectId(this.value) : assert(value != null); + const MapsObjectId(this.value) : assert(value != null); /// The value of the id. final String value; diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart index 15351d58168b..e493d6cec8cc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart @@ -104,7 +104,7 @@ class InfoWindow { @immutable class MarkerId extends MapsObjectId { /// Creates an immutable identifier for a [Marker]. - MarkerId(String value) : super(value); + const MarkerId(String value) : super(value); } /// Marks a geographical location on the map. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart index 4e5e9bf13d84..57438287a156 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart @@ -15,7 +15,7 @@ import 'types.dart'; @immutable class PolygonId extends MapsObjectId { /// Creates an immutable identifier for a [Polygon]. - PolygonId(String value) : super(value); + const PolygonId(String value) : super(value); } /// Draws a polygon through geographical locations on the map. @@ -167,7 +167,7 @@ class Polygon implements MapsObject { fillColor == typedOther.fillColor && geodesic == typedOther.geodesic && listEquals(points, typedOther.points) && - DeepCollectionEquality().equals(holes, typedOther.holes) && + const DeepCollectionEquality().equals(holes, typedOther.holes) && visible == typedOther.visible && strokeColor == typedOther.strokeColor && strokeWidth == typedOther.strokeWidth && diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart index 3f87395164f6..6738bbf2f079 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart @@ -16,7 +16,7 @@ class PolylineId extends MapsObjectId { /// Creates an immutable object representing a [PolylineId] among [GoogleMap] polylines. /// /// An [AssertionError] will be thrown if [value] is null. - PolylineId(String value) : super(value); + const PolylineId(String value) : super(value); } /// Draws a line through geographical locations on the map. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart index e31bfb461fb4..7f7ef09123b0 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart @@ -3,16 +3,17 @@ // found in the LICENSE file. import 'dart:ui' show hashValues; + import 'package:flutter/foundation.dart'; +import 'package:meta/meta.dart' show immutable; import 'types.dart'; -import 'package:meta/meta.dart' show immutable; /// Uniquely identifies a [TileOverlay] among [GoogleMap] tile overlays. @immutable class TileOverlayId extends MapsObjectId { /// Creates an immutable identifier for a [TileOverlay]. - TileOverlayId(String value) : super(value); + const TileOverlayId(String value) : super(value); } /// A set of images which are displayed on top of the base map tiles. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml index 0796b71fbb62..9d419351e85f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the google_maps_flutter plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.1 +version: 2.0.2 dependencies: flutter: diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart index 3b6d237e05d4..4774311feb90 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart @@ -3,14 +3,13 @@ // found in the LICENSE file. import 'package:flutter_test/flutter_test.dart'; - import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); test('toMap / fromMap', () { - final cameraPosition = CameraPosition( + const cameraPosition = CameraPosition( target: LatLng(10.0, 15.0), bearing: 0.5, tilt: 30.0, zoom: 1.5); // Cast to to ensure that recreating from JSON, where // type information will have likely been lost, still works. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart index 65692bd2a385..2d1ae8314a94 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart @@ -12,12 +12,12 @@ void main() { TestWidgetsFlutterBinding.ensureInitialized(); test('keyByMapsObjectId', () async { - final MapsObjectId id1 = MapsObjectId('1'); - final MapsObjectId id2 = MapsObjectId('2'); - final MapsObjectId id3 = MapsObjectId('3'); - final TestMapsObject object1 = TestMapsObject(id1); - final TestMapsObject object2 = TestMapsObject(id2, data: 2); - final TestMapsObject object3 = TestMapsObject(id3); + const MapsObjectId id1 = MapsObjectId('1'); + const MapsObjectId id2 = MapsObjectId('2'); + const MapsObjectId id3 = MapsObjectId('3'); + const TestMapsObject object1 = TestMapsObject(id1); + const TestMapsObject object2 = TestMapsObject(id2, data: 2); + const TestMapsObject object3 = TestMapsObject(id3); expect( keyByMapsObjectId({object1, object2, object3}), , TestMapsObject>{ @@ -28,12 +28,12 @@ void main() { }); test('serializeMapsObjectSet', () async { - final MapsObjectId id1 = MapsObjectId('1'); - final MapsObjectId id2 = MapsObjectId('2'); - final MapsObjectId id3 = MapsObjectId('3'); - final TestMapsObject object1 = TestMapsObject(id1); - final TestMapsObject object2 = TestMapsObject(id2, data: 2); - final TestMapsObject object3 = TestMapsObject(id3); + const MapsObjectId id1 = MapsObjectId('1'); + const MapsObjectId id2 = MapsObjectId('2'); + const MapsObjectId id3 = MapsObjectId('3'); + const TestMapsObject object1 = TestMapsObject(id1); + const TestMapsObject object2 = TestMapsObject(id2, data: 2); + const TestMapsObject object3 = TestMapsObject(id3); expect( serializeMapsObjectSet({object1, object2, object3}), >[ diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart index 68f4c587c2f2..673b3c63c59e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart @@ -6,9 +6,9 @@ import 'dart:ui' show hashValues, hashList; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:google_maps_flutter_platform_interface/src/types/utils/maps_object.dart'; -import 'package:google_maps_flutter_platform_interface/src/types/maps_object_updates.dart'; import 'package:google_maps_flutter_platform_interface/src/types/maps_object.dart'; +import 'package:google_maps_flutter_platform_interface/src/types/maps_object_updates.dart'; +import 'package:google_maps_flutter_platform_interface/src/types/utils/maps_object.dart'; import 'test_maps_object.dart'; @@ -23,15 +23,15 @@ void main() { group('tile overlay updates tests', () { test('Correctly set toRemove, toAdd and toChange', () async { - final TestMapsObject to1 = + const TestMapsObject to1 = TestMapsObject(MapsObjectId('id1')); - final TestMapsObject to2 = + const TestMapsObject to2 = TestMapsObject(MapsObjectId('id2')); - final TestMapsObject to3 = + const TestMapsObject to3 = TestMapsObject(MapsObjectId('id3')); - final TestMapsObject to3Changed = + const TestMapsObject to3Changed = TestMapsObject(MapsObjectId('id3'), data: 2); - final TestMapsObject to4 = + const TestMapsObject to4 = TestMapsObject(MapsObjectId('id4')); final Set previous = Set.from([to1, to2, to3]); @@ -40,8 +40,10 @@ void main() { final TestMapsObjectUpdate updates = TestMapsObjectUpdate.from(previous, current); - final Set> toRemove = Set.from( - >[MapsObjectId('id1')]); + final Set> toRemove = + Set.from(>[ + const MapsObjectId('id1') + ]); expect(updates.objectIdsToRemove, toRemove); final Set toAdd = Set.from([to4]); @@ -53,15 +55,15 @@ void main() { }); test('toJson', () async { - final TestMapsObject to1 = + const TestMapsObject to1 = TestMapsObject(MapsObjectId('id1')); - final TestMapsObject to2 = + const TestMapsObject to2 = TestMapsObject(MapsObjectId('id2')); - final TestMapsObject to3 = + const TestMapsObject to3 = TestMapsObject(MapsObjectId('id3')); - final TestMapsObject to3Changed = + const TestMapsObject to3Changed = TestMapsObject(MapsObjectId('id3'), data: 2); - final TestMapsObject to4 = + const TestMapsObject to4 = TestMapsObject(MapsObjectId('id4')); final Set previous = Set.from([to1, to2, to3]); @@ -81,15 +83,15 @@ void main() { }); test('equality', () async { - final TestMapsObject to1 = + const TestMapsObject to1 = TestMapsObject(MapsObjectId('id1')); - final TestMapsObject to2 = + const TestMapsObject to2 = TestMapsObject(MapsObjectId('id2')); - final TestMapsObject to3 = + const TestMapsObject to3 = TestMapsObject(MapsObjectId('id3')); - final TestMapsObject to3Changed = + const TestMapsObject to3Changed = TestMapsObject(MapsObjectId('id3'), data: 2); - final TestMapsObject to4 = + const TestMapsObject to4 = TestMapsObject(MapsObjectId('id4')); final Set previous = Set.from([to1, to2, to3]); @@ -109,15 +111,15 @@ void main() { }); test('hashCode', () async { - final TestMapsObject to1 = + const TestMapsObject to1 = TestMapsObject(MapsObjectId('id1')); - final TestMapsObject to2 = + const TestMapsObject to2 = TestMapsObject(MapsObjectId('id2')); - final TestMapsObject to3 = + const TestMapsObject to3 = TestMapsObject(MapsObjectId('id3')); - final TestMapsObject to3Changed = + const TestMapsObject to3Changed = TestMapsObject(MapsObjectId('id3'), data: 2); - final TestMapsObject to4 = + const TestMapsObject to4 = TestMapsObject(MapsObjectId('id4')); final Set previous = Set.from([to1, to2, to3]); @@ -134,15 +136,15 @@ void main() { }); test('toString', () async { - final TestMapsObject to1 = + const TestMapsObject to1 = TestMapsObject(MapsObjectId('id1')); - final TestMapsObject to2 = + const TestMapsObject to2 = TestMapsObject(MapsObjectId('id2')); - final TestMapsObject to3 = + const TestMapsObject to3 = TestMapsObject(MapsObjectId('id3')); - final TestMapsObject to3Changed = + const TestMapsObject to3Changed = TestMapsObject(MapsObjectId('id3'), data: 2); - final TestMapsObject to4 = + const TestMapsObject to4 = TestMapsObject(MapsObjectId('id4')); final Set previous = Set.from([to1, to2, to3]); diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart index e15c73f08a54..360d86617754 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart @@ -3,13 +3,14 @@ // found in the LICENSE file. import 'dart:ui' show hashValues; + import 'package:flutter/rendering.dart'; -import 'package:google_maps_flutter_platform_interface/src/types/maps_object_updates.dart'; import 'package:google_maps_flutter_platform_interface/src/types/maps_object.dart'; +import 'package:google_maps_flutter_platform_interface/src/types/maps_object_updates.dart'; /// A trivial TestMapsObject implementation for testing updates with. class TestMapsObject implements MapsObject { - TestMapsObject(this.mapsId, {this.data = 1}); + const TestMapsObject(this.mapsId, {this.data = 1}); final MapsObjectId mapsId; diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart index 87380fdd651b..992438fafef1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'dart:ui' show hashValues; + import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; @@ -11,22 +12,22 @@ void main() { group('tile overlay id tests', () { test('equality', () async { - final TileOverlayId id1 = TileOverlayId('1'); - final TileOverlayId id2 = TileOverlayId('1'); - final TileOverlayId id3 = TileOverlayId('2'); + const TileOverlayId id1 = TileOverlayId('1'); + const TileOverlayId id2 = TileOverlayId('1'); + const TileOverlayId id3 = TileOverlayId('2'); expect(id1, id2); expect(id1, isNot(id3)); }); test('toString', () async { - final TileOverlayId id1 = TileOverlayId('1'); + const TileOverlayId id1 = TileOverlayId('1'); expect(id1.toString(), 'TileOverlayId(1)'); }); }); group('tile overlay tests', () { test('toJson returns correct format', () async { - final TileOverlay tileOverlay = TileOverlay( + const TileOverlay tileOverlay = TileOverlay( tileOverlayId: TileOverlayId('id'), fadeIn: false, tileProvider: null, @@ -48,16 +49,16 @@ void main() { test('invalid transparency throws', () async { expect( () => TileOverlay( - tileOverlayId: TileOverlayId('id1'), transparency: -0.1), + tileOverlayId: const TileOverlayId('id1'), transparency: -0.1), throwsAssertionError); expect( () => TileOverlay( - tileOverlayId: TileOverlayId('id2'), transparency: 1.2), + tileOverlayId: const TileOverlayId('id2'), transparency: 1.2), throwsAssertionError); }); test('equality', () async { - final TileOverlay tileOverlay1 = TileOverlay( + const TileOverlay tileOverlay1 = TileOverlay( tileOverlayId: TileOverlayId('id1'), fadeIn: false, tileProvider: null, @@ -65,7 +66,7 @@ void main() { zIndex: 1, visible: false, tileSize: 128); - final TileOverlay tileOverlay2 = TileOverlay( + const TileOverlay tileOverlay2 = TileOverlay( tileOverlayId: TileOverlayId('id1'), fadeIn: false, tileProvider: null, @@ -73,7 +74,7 @@ void main() { zIndex: 1, visible: false, tileSize: 128); - final TileOverlay tileOverlay3 = TileOverlay( + const TileOverlay tileOverlay3 = TileOverlay( tileOverlayId: TileOverlayId('id2'), fadeIn: false, tileProvider: null, @@ -86,8 +87,8 @@ void main() { }); test('hashCode', () async { - TileOverlayId id = TileOverlayId('id1'); - final TileOverlay tileOverlay = TileOverlay( + const TileOverlayId id = TileOverlayId('id1'); + const TileOverlay tileOverlay = TileOverlay( tileOverlayId: id, fadeIn: false, tileProvider: null, diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart index f622ca5213ef..0db7d9d33324 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart @@ -3,22 +3,23 @@ // found in the LICENSE file. import 'dart:ui' show hashValues, hashList; + import 'package:flutter_test/flutter_test.dart'; -import 'package:google_maps_flutter_platform_interface/src/types/utils/tile_overlay.dart'; -import 'package:google_maps_flutter_platform_interface/src/types/tile_overlay_updates.dart'; import 'package:google_maps_flutter_platform_interface/src/types/tile_overlay.dart'; +import 'package:google_maps_flutter_platform_interface/src/types/tile_overlay_updates.dart'; +import 'package:google_maps_flutter_platform_interface/src/types/utils/tile_overlay.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); group('tile overlay updates tests', () { test('Correctly set toRemove, toAdd and toChange', () async { - final TileOverlay to1 = TileOverlay(tileOverlayId: TileOverlayId('id1')); - final TileOverlay to2 = TileOverlay(tileOverlayId: TileOverlayId('id2')); - final TileOverlay to3 = TileOverlay(tileOverlayId: TileOverlayId('id3')); - final TileOverlay to3Changed = + const TileOverlay to1 = TileOverlay(tileOverlayId: TileOverlayId('id1')); + const TileOverlay to2 = TileOverlay(tileOverlayId: TileOverlayId('id2')); + const TileOverlay to3 = TileOverlay(tileOverlayId: TileOverlayId('id3')); + const TileOverlay to3Changed = TileOverlay(tileOverlayId: TileOverlayId('id3'), transparency: 0.5); - final TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4')); + const TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4')); final Set previous = Set.from([to1, to2, to3]); final Set current = Set.from([to2, to3Changed, to4]); @@ -26,7 +27,7 @@ void main() { TileOverlayUpdates.from(previous, current); final Set toRemove = - Set.from([TileOverlayId('id1')]); + Set.from([const TileOverlayId('id1')]); expect(updates.tileOverlayIdsToRemove, toRemove); final Set toAdd = Set.from([to4]); @@ -37,12 +38,12 @@ void main() { }); test('toJson', () async { - final TileOverlay to1 = TileOverlay(tileOverlayId: TileOverlayId('id1')); - final TileOverlay to2 = TileOverlay(tileOverlayId: TileOverlayId('id2')); - final TileOverlay to3 = TileOverlay(tileOverlayId: TileOverlayId('id3')); - final TileOverlay to3Changed = + const TileOverlay to1 = TileOverlay(tileOverlayId: TileOverlayId('id1')); + const TileOverlay to2 = TileOverlay(tileOverlayId: TileOverlayId('id2')); + const TileOverlay to3 = TileOverlay(tileOverlayId: TileOverlayId('id3')); + const TileOverlay to3Changed = TileOverlay(tileOverlayId: TileOverlayId('id3'), transparency: 0.5); - final TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4')); + const TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4')); final Set previous = Set.from([to1, to2, to3]); final Set current = Set.from([to2, to3Changed, to4]); @@ -61,12 +62,12 @@ void main() { }); test('equality', () async { - final TileOverlay to1 = TileOverlay(tileOverlayId: TileOverlayId('id1')); - final TileOverlay to2 = TileOverlay(tileOverlayId: TileOverlayId('id2')); - final TileOverlay to3 = TileOverlay(tileOverlayId: TileOverlayId('id3')); - final TileOverlay to3Changed = + const TileOverlay to1 = TileOverlay(tileOverlayId: TileOverlayId('id1')); + const TileOverlay to2 = TileOverlay(tileOverlayId: TileOverlayId('id2')); + const TileOverlay to3 = TileOverlay(tileOverlayId: TileOverlayId('id3')); + const TileOverlay to3Changed = TileOverlay(tileOverlayId: TileOverlayId('id3'), transparency: 0.5); - final TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4')); + const TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4')); final Set previous = Set.from([to1, to2, to3]); final Set current1 = Set.from([to2, to3Changed, to4]); @@ -84,12 +85,12 @@ void main() { }); test('hashCode', () async { - final TileOverlay to1 = TileOverlay(tileOverlayId: TileOverlayId('id1')); - final TileOverlay to2 = TileOverlay(tileOverlayId: TileOverlayId('id2')); - final TileOverlay to3 = TileOverlay(tileOverlayId: TileOverlayId('id3')); - final TileOverlay to3Changed = + const TileOverlay to1 = TileOverlay(tileOverlayId: TileOverlayId('id1')); + const TileOverlay to2 = TileOverlay(tileOverlayId: TileOverlayId('id2')); + const TileOverlay to3 = TileOverlay(tileOverlayId: TileOverlayId('id3')); + const TileOverlay to3Changed = TileOverlay(tileOverlayId: TileOverlayId('id3'), transparency: 0.5); - final TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4')); + const TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4')); final Set previous = Set.from([to1, to2, to3]); final Set current = Set.from([to2, to3Changed, to4]); @@ -104,12 +105,12 @@ void main() { }); test('toString', () async { - final TileOverlay to1 = TileOverlay(tileOverlayId: TileOverlayId('id1')); - final TileOverlay to2 = TileOverlay(tileOverlayId: TileOverlayId('id2')); - final TileOverlay to3 = TileOverlay(tileOverlayId: TileOverlayId('id3')); - final TileOverlay to3Changed = + const TileOverlay to1 = TileOverlay(tileOverlayId: TileOverlayId('id1')); + const TileOverlay to2 = TileOverlay(tileOverlayId: TileOverlayId('id2')); + const TileOverlay to3 = TileOverlay(tileOverlayId: TileOverlayId('id3')); + const TileOverlay to3Changed = TileOverlay(tileOverlayId: TileOverlayId('id3'), transparency: 0.5); - final TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4')); + const TileOverlay to4 = TileOverlay(tileOverlayId: TileOverlayId('id4')); final Set previous = Set.from([to1, to2, to3]); final Set current = Set.from([to2, to3Changed, to4]); diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart index 3e0fe99ec18c..d985ac30136e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'dart:typed_data'; + import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; @@ -22,7 +23,7 @@ void main() { }); test('toJson handles null data', () async { - final Tile tile = Tile(0, 0, null); + const Tile tile = Tile(0, 0, null); final Object json = tile.toJson(); expect(json, { 'width': 0, From d443a59b14ec654692b82bd5b05e75f45ca2cf55 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Wed, 17 Mar 2021 16:25:28 -0400 Subject: [PATCH 0276/1565] Prep for alignment with Flutter analysis options (#3703) Renames the old analysis_options.yaml to analysis_options_legacy.yaml, replacing it with a slightly modified copy of flutter/flutter's analysis options. Each plugins has a temporary local analysis_options.yaml that points to the legacy version. This allows for inceremental conversion on a per-plugin basis, which should make the problem more tractable. Since this hasn't yet been enabled for any packages, it's likely that as it is we'll find a few local modification we need to make to the root analysis_options (e.g., things that conflict with 'dart format'). Part of https://github.com/flutter/flutter/issues/76229 --- analysis_options.yaml | 242 +++++++++++++++++- analysis_options_legacy.yaml | 13 + .../analysis_options.yaml | 1 + packages/android_intent/analysis_options.yaml | 1 + packages/battery/analysis_options.yaml | 1 + packages/camera/analysis_options.yaml | 1 + packages/connectivity/analysis_options.yaml | 1 + packages/cross_file/analysis_options.yaml | 1 + packages/device_info/analysis_options.yaml | 1 + packages/e2e/analysis_options.yaml | 1 + packages/espresso/analysis_options.yaml | 1 + packages/file_selector/analysis_options.yaml | 1 + .../analysis_options.yaml | 1 + .../google_maps_flutter/analysis_options.yaml | 1 + packages/google_sign_in/analysis_options.yaml | 1 + packages/image_picker/analysis_options.yaml | 1 + .../in_app_purchase/analysis_options.yaml | 1 + .../integration_test/analysis_options.yaml | 1 + .../ios_platform_images/analysis_options.yaml | 1 + packages/local_auth/analysis_options.yaml | 1 + packages/package_info/analysis_options.yaml | 1 + packages/path_provider/analysis_options.yaml | 1 + .../analysis_options.yaml | 1 + packages/quick_actions/analysis_options.yaml | 1 + packages/sensors/analysis_options.yaml | 1 + packages/share/analysis_options.yaml | 1 + .../shared_preferences/analysis_options.yaml | 1 + packages/url_launcher/analysis_options.yaml | 1 + packages/video_player/analysis_options.yaml | 1 + .../webview_flutter/analysis_options.yaml | 1 + .../wifi_info_flutter/analysis_options.yaml | 1 + script/tool/analysis_options.yaml | 1 + 32 files changed, 280 insertions(+), 5 deletions(-) create mode 100644 analysis_options_legacy.yaml create mode 100644 packages/android_alarm_manager/analysis_options.yaml create mode 100644 packages/android_intent/analysis_options.yaml create mode 100644 packages/battery/analysis_options.yaml create mode 100644 packages/camera/analysis_options.yaml create mode 100644 packages/connectivity/analysis_options.yaml create mode 100644 packages/cross_file/analysis_options.yaml create mode 100644 packages/device_info/analysis_options.yaml create mode 100644 packages/e2e/analysis_options.yaml create mode 100644 packages/espresso/analysis_options.yaml create mode 100644 packages/file_selector/analysis_options.yaml create mode 100644 packages/flutter_plugin_android_lifecycle/analysis_options.yaml create mode 100644 packages/google_maps_flutter/analysis_options.yaml create mode 100644 packages/google_sign_in/analysis_options.yaml create mode 100644 packages/image_picker/analysis_options.yaml create mode 100644 packages/in_app_purchase/analysis_options.yaml create mode 100644 packages/integration_test/analysis_options.yaml create mode 100644 packages/ios_platform_images/analysis_options.yaml create mode 100644 packages/local_auth/analysis_options.yaml create mode 100644 packages/package_info/analysis_options.yaml create mode 100644 packages/path_provider/analysis_options.yaml create mode 100644 packages/plugin_platform_interface/analysis_options.yaml create mode 100644 packages/quick_actions/analysis_options.yaml create mode 100644 packages/sensors/analysis_options.yaml create mode 100644 packages/share/analysis_options.yaml create mode 100644 packages/shared_preferences/analysis_options.yaml create mode 100644 packages/url_launcher/analysis_options.yaml create mode 100644 packages/video_player/analysis_options.yaml create mode 100644 packages/webview_flutter/analysis_options.yaml create mode 100644 packages/wifi_info_flutter/analysis_options.yaml create mode 100644 script/tool/analysis_options.yaml diff --git a/analysis_options.yaml b/analysis_options.yaml index 2b62a6a9e2b9..858560e41e8a 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,13 +1,245 @@ -include: package:pedantic/analysis_options.1.8.0.yaml +# This is a copy (as of March 2021) of flutter/flutter's analysis_options file, +# with minimal changes for this repository. The goal is to move toward using a +# shared set of analysis options as much as possible, and eventually a shared +# file. +# +# Plugins that have not yet switched from the previous set of options have a +# local analysis_options.yaml that points to analysis_options_legacy.yaml +# instead. + +# Specify analysis options. +# +# Until there are meta linter rules, each desired lint must be explicitly enabled. +# See: https://github.com/dart-lang/linter/issues/288 +# +# For a list of lints, see: http://dart-lang.github.io/linter/lints/ +# See the configuration guide for more +# https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer +# +# There are other similar analysis options files in the flutter repos, +# which should be kept in sync with this file: +# +# - analysis_options.yaml (this file) +# - packages/flutter/lib/analysis_options_user.yaml +# - https://github.com/flutter/plugins/blob/master/analysis_options.yaml +# - https://github.com/flutter/engine/blob/master/analysis_options.yaml +# +# This file contains the analysis options used by Flutter tools, such as IntelliJ, +# Android Studio, and the `flutter analyze` command. + analyzer: + strong-mode: + implicit-casts: false + implicit-dynamic: false + errors: + # treat missing required parameters as a warning (not a hint) + missing_required_param: warning + # treat missing returns as a warning (not a hint) + missing_return: warning + # allow having TODOs in the code + todo: ignore + # allow self-reference to deprecated members (we do this because otherwise we have + # to annotate every member in every test, assert, etc, when we deprecate something) + deprecated_member_use_from_same_package: ignore + # Ignore analyzer hints for updating pubspecs when using Future or + # Stream and not importing dart:async + # Please see https://github.com/flutter/flutter/pull/24528 for details. + sdk_version_async_exported_from_core: ignore + ### Local flutter/plugins changes ### + # Allow null checks for as long as mixed mode is officially supported. + unnecessary_null_comparison: false + always_require_non_null_named_parameters: false # not needed with nnbd exclude: # Ignore generated files - '**/*.g.dart' - 'lib/src/generated/*.dart' - '**/*.mocks.dart' # Mockito @GenerateMocks - errors: - always_require_non_null_named_parameters: false # not needed with nnbd - unnecessary_null_comparison: false # Turned as long as nnbd mix-mode is supported. + linter: rules: - - public_member_api_docs + # these rules are documented on and in the same order as + # the Dart Lint rules page to make maintenance easier + # https://github.com/dart-lang/linter/blob/master/example/all.yaml + - always_declare_return_types + - always_put_control_body_on_new_line + # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 + - always_require_non_null_named_parameters + - always_specify_types + # - always_use_package_imports # we do this commonly + - annotate_overrides + # - avoid_annotating_with_dynamic # conflicts with always_specify_types + # - avoid_as # required for implicit-casts: true + - avoid_bool_literals_in_conditional_expressions + # - avoid_catches_without_on_clauses # we do this commonly + # - avoid_catching_errors # we do this commonly + - avoid_classes_with_only_static_members + # - avoid_double_and_int_checks # only useful when targeting JS runtime + - avoid_empty_else + - avoid_equals_and_hash_code_on_mutable_classes + # - avoid_escaping_inner_quotes # not yet tested + - avoid_field_initializers_in_const_classes + - avoid_function_literals_in_foreach_calls + # - avoid_implementing_value_types # not yet tested + - avoid_init_to_null + # - avoid_js_rounded_ints # only useful when targeting JS runtime + - avoid_null_checks_in_equality_operators + # - avoid_positional_boolean_parameters # not yet tested + # - avoid_print # not yet tested + # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) + # - avoid_redundant_argument_values # not yet tested + - avoid_relative_lib_imports + - avoid_renaming_method_parameters + - avoid_return_types_on_setters + # - avoid_returning_null # there are plenty of valid reasons to return null + # - avoid_returning_null_for_future # not yet tested + - avoid_returning_null_for_void + # - avoid_returning_this # there are plenty of valid reasons to return this + # - avoid_setters_without_getters # not yet tested + - avoid_shadowing_type_parameters + - avoid_single_cascade_in_expression_statements + - avoid_slow_async_io + # - avoid_type_to_string # we do this commonly + - avoid_types_as_parameter_names + # - avoid_types_on_closure_parameters # conflicts with always_specify_types + # - avoid_unnecessary_containers # not yet tested + - avoid_unused_constructor_parameters + - avoid_void_async + # - avoid_web_libraries_in_flutter # not yet tested + - await_only_futures + - camel_case_extensions + - camel_case_types + - cancel_subscriptions + # - cascade_invocations # not yet tested + - cast_nullable_to_non_nullable + # - close_sinks # not reliable enough + # - comment_references # blocked on https://github.com/flutter/flutter/issues/20765 + # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 + - control_flow_in_finally + # - curly_braces_in_flow_control_structures # not required by flutter style + # - diagnostic_describe_all_properties # not yet tested + - directives_ordering + # - do_not_use_environment # we do this commonly + - empty_catches + - empty_constructor_bodies + - empty_statements + - exhaustive_cases + # - file_names # not yet tested + - flutter_style_todos + - hash_and_equals + - implementation_imports + # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 + - iterable_contains_unrelated_type + # - join_return_with_assignment # not required by flutter style + - leading_newlines_in_multiline_strings + - library_names + - library_prefixes + # - lines_longer_than_80_chars # not required by flutter style + - list_remove_unrelated_type + # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181 + # - missing_whitespace_between_adjacent_strings # not yet tested + - no_adjacent_strings_in_list + # - no_default_cases # too many false positives + - no_duplicate_case_values + - no_logic_in_create_state + # - no_runtimeType_toString # ok in tests; we enable this only in packages/ + - non_constant_identifier_names + - null_check_on_nullable_type_parameter + # - null_closures # not required by flutter style + # - omit_local_variable_types # opposite of always_specify_types + # - one_member_abstracts # too many false positives + # - only_throw_errors # https://github.com/flutter/flutter/issues/5792 + - overridden_fields + - package_api_docs + # - package_names # non conforming packages in sdk + - package_prefixed_library_names + # - parameter_assignments # we do this commonly + - prefer_adjacent_string_concatenation + - prefer_asserts_in_initializer_lists + # - prefer_asserts_with_message # not required by flutter style + - prefer_collection_literals + - prefer_conditional_assignment + - prefer_const_constructors + - prefer_const_constructors_in_immutables + - prefer_const_declarations + - prefer_const_literals_to_create_immutables + # - prefer_constructors_over_static_methods # far too many false positives + - prefer_contains + # - prefer_double_quotes # opposite of prefer_single_quotes + - prefer_equal_for_default_values + # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods + - prefer_final_fields + - prefer_final_in_for_each + - prefer_final_locals + - prefer_for_elements_to_map_fromIterable + - prefer_foreach + # - prefer_function_declarations_over_variables # not yet tested + - prefer_generic_function_type_aliases + - prefer_if_elements_to_conditional_expressions + - prefer_if_null_operators + - prefer_initializing_formals + - prefer_inlined_adds + # - prefer_int_literals # not yet tested + # - prefer_interpolation_to_compose_strings # not yet tested + - prefer_is_empty + - prefer_is_not_empty + - prefer_is_not_operator + - prefer_iterable_whereType + # - prefer_mixin # https://github.com/dart-lang/language/issues/32 + # - prefer_null_aware_operators # disable until NNBD, see https://github.com/flutter/flutter/pull/32711#issuecomment-492930932 + # - prefer_relative_imports # not yet tested + - prefer_single_quotes + - prefer_spread_collections + - prefer_typing_uninitialized_variables + - prefer_void_to_null + # - provide_deprecation_message # not yet tested + # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml + - recursive_getters + # - sized_box_for_whitespace # not yet tested + - slash_for_doc_comments + # - sort_child_properties_last # not yet tested + - sort_constructors_first + # - sort_pub_dependencies # prevents separating pinned transitive dependencies + - sort_unnamed_constructors_first + - test_types_in_equals + - throw_in_finally + - tighten_type_of_initializing_formals + # - type_annotate_public_apis # subset of always_specify_types + - type_init_formals + # - unawaited_futures # too many false positives + # - unnecessary_await_in_return # not yet tested + - unnecessary_brace_in_string_interps + - unnecessary_const + # - unnecessary_final # conflicts with prefer_final_locals + - unnecessary_getters_setters + # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 + - unnecessary_new + - unnecessary_null_aware_assignments + # - unnecessary_null_checks # not yet tested + - unnecessary_null_in_if_null_operators + - unnecessary_nullable_for_final_variable_declarations + - unnecessary_overrides + - unnecessary_parenthesis + # - unnecessary_raw_strings # not yet tested + - unnecessary_statements + - unnecessary_string_escapes + - unnecessary_string_interpolations + - unnecessary_this + - unrelated_type_equality_checks + # - unsafe_html # not yet tested + - use_full_hex_values_for_flutter_colors + # - use_function_type_syntax_for_parameters # not yet tested + - use_is_even_rather_than_modulo + # - use_key_in_widget_constructors # not yet tested + - use_late_for_private_fields_and_variables + - use_raw_strings + - use_rethrow_when_possible + # - use_setters_to_change_properties # not yet tested + # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 + # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review + - valid_regexps + - void_checks + ### Local flutter/plugins changes ### + # These are from flutter/flutter/packages, so will need to be preserved + # separately when moving to a shared file. + - no_runtimeType_toString # use objectRuntimeType from package:foundation + - public_member_api_docs # see https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#documentation-dartdocs-javadocs-etc diff --git a/analysis_options_legacy.yaml b/analysis_options_legacy.yaml new file mode 100644 index 000000000000..2b62a6a9e2b9 --- /dev/null +++ b/analysis_options_legacy.yaml @@ -0,0 +1,13 @@ +include: package:pedantic/analysis_options.1.8.0.yaml +analyzer: + exclude: + # Ignore generated files + - '**/*.g.dart' + - 'lib/src/generated/*.dart' + - '**/*.mocks.dart' # Mockito @GenerateMocks + errors: + always_require_non_null_named_parameters: false # not needed with nnbd + unnecessary_null_comparison: false # Turned as long as nnbd mix-mode is supported. +linter: + rules: + - public_member_api_docs diff --git a/packages/android_alarm_manager/analysis_options.yaml b/packages/android_alarm_manager/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/android_alarm_manager/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/android_intent/analysis_options.yaml b/packages/android_intent/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/android_intent/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/battery/analysis_options.yaml b/packages/battery/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/battery/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/camera/analysis_options.yaml b/packages/camera/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/camera/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/connectivity/analysis_options.yaml b/packages/connectivity/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/connectivity/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/cross_file/analysis_options.yaml b/packages/cross_file/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/cross_file/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/device_info/analysis_options.yaml b/packages/device_info/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/device_info/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/e2e/analysis_options.yaml b/packages/e2e/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/e2e/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/espresso/analysis_options.yaml b/packages/espresso/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/espresso/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/file_selector/analysis_options.yaml b/packages/file_selector/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/file_selector/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/flutter_plugin_android_lifecycle/analysis_options.yaml b/packages/flutter_plugin_android_lifecycle/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/flutter_plugin_android_lifecycle/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/google_maps_flutter/analysis_options.yaml b/packages/google_maps_flutter/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/google_maps_flutter/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/google_sign_in/analysis_options.yaml b/packages/google_sign_in/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/google_sign_in/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/image_picker/analysis_options.yaml b/packages/image_picker/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/image_picker/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/in_app_purchase/analysis_options.yaml b/packages/in_app_purchase/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/in_app_purchase/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/integration_test/analysis_options.yaml b/packages/integration_test/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/integration_test/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/ios_platform_images/analysis_options.yaml b/packages/ios_platform_images/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/ios_platform_images/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/local_auth/analysis_options.yaml b/packages/local_auth/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/local_auth/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/package_info/analysis_options.yaml b/packages/package_info/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/package_info/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/path_provider/analysis_options.yaml b/packages/path_provider/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/path_provider/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/plugin_platform_interface/analysis_options.yaml b/packages/plugin_platform_interface/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/plugin_platform_interface/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/quick_actions/analysis_options.yaml b/packages/quick_actions/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/quick_actions/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/sensors/analysis_options.yaml b/packages/sensors/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/sensors/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/share/analysis_options.yaml b/packages/share/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/share/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/shared_preferences/analysis_options.yaml b/packages/shared_preferences/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/shared_preferences/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/url_launcher/analysis_options.yaml b/packages/url_launcher/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/url_launcher/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/video_player/analysis_options.yaml b/packages/video_player/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/video_player/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/webview_flutter/analysis_options.yaml b/packages/webview_flutter/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/webview_flutter/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/packages/wifi_info_flutter/analysis_options.yaml b/packages/wifi_info_flutter/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/packages/wifi_info_flutter/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml diff --git a/script/tool/analysis_options.yaml b/script/tool/analysis_options.yaml new file mode 100644 index 000000000000..cda4f6e153e6 --- /dev/null +++ b/script/tool/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../analysis_options_legacy.yaml From a8551330e9939da054b24db03f15337cae9af753 Mon Sep 17 00:00:00 2001 From: Guilherme Girotto Date: Thu, 18 Mar 2021 13:06:03 -0300 Subject: [PATCH 0277/1565] [google_sign_in] Adds support to send `clientId` as a parameter (#3640) --- .../google_sign_in/CHANGELOG.md | 5 +++++ .../googlesignin/GoogleSignInPlugin.java | 20 +++++++++++++++---- .../google_sign_in/example/lib/main.dart | 2 ++ .../ios/Classes/FLTGoogleSignInPlugin.m | 10 +++++++++- .../google_sign_in/pubspec.yaml | 4 ++-- .../test/google_sign_in_test.dart | 19 ++++++++++++++++++ 6 files changed, 53 insertions(+), 7 deletions(-) diff --git a/packages/google_sign_in/google_sign_in/CHANGELOG.md b/packages/google_sign_in/google_sign_in/CHANGELOG.md index 57d1c9be3743..429b07b47472 100644 --- a/packages/google_sign_in/google_sign_in/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in/CHANGELOG.md @@ -1,3 +1,8 @@ +## 5.0.1 + +* Update platforms `init` function to prioritize `clientId` property when available; +* Updates `google_sign_in_platform_interface` version. + ## 5.0.0 * Migrate to null safety. diff --git a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java index f6673e5d5978..eb3a3d0d91ec 100755 --- a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java +++ b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java @@ -136,7 +136,8 @@ public void onMethodCall(MethodCall call, Result result) { String signInOption = call.argument("signInOption"); List requestedScopes = call.argument("scopes"); String hostedDomain = call.argument("hostedDomain"); - delegate.init(result, signInOption, requestedScopes, hostedDomain); + String clientId = call.argument("clientId"); + delegate.init(result, signInOption, requestedScopes, hostedDomain, clientId); break; case METHOD_SIGN_IN_SILENTLY: @@ -188,7 +189,11 @@ public void onMethodCall(MethodCall call, Result result) { public interface IDelegate { /** Initializes this delegate so that it is ready to perform other operations. */ public void init( - Result result, String signInOption, List requestedScopes, String hostedDomain); + Result result, + String signInOption, + List requestedScopes, + String hostedDomain, + String clientId); /** * Returns the account information for the user who is signed in to this app. If no user is @@ -309,7 +314,11 @@ private void checkAndSetPendingOperation(String method, Result result, Object da */ @Override public void init( - Result result, String signInOption, List requestedScopes, String hostedDomain) { + Result result, + String signInOption, + List requestedScopes, + String hostedDomain, + String clientId) { try { GoogleSignInOptions.Builder optionsBuilder; @@ -334,7 +343,10 @@ public void init( context .getResources() .getIdentifier("default_web_client_id", "string", context.getPackageName()); - if (clientIdIdentifier != 0) { + if (!Strings.isNullOrEmpty(clientId)) { + optionsBuilder.requestIdToken(clientId); + optionsBuilder.requestServerAuthCode(clientId); + } else if (clientIdIdentifier != 0) { optionsBuilder.requestIdToken(context.getString(clientIdIdentifier)); optionsBuilder.requestServerAuthCode(context.getString(clientIdIdentifier)); } diff --git a/packages/google_sign_in/google_sign_in/example/lib/main.dart b/packages/google_sign_in/google_sign_in/example/lib/main.dart index e003225af5cc..c87063297373 100755 --- a/packages/google_sign_in/google_sign_in/example/lib/main.dart +++ b/packages/google_sign_in/google_sign_in/example/lib/main.dart @@ -12,6 +12,8 @@ import 'package:flutter/material.dart'; import 'package:google_sign_in/google_sign_in.dart'; GoogleSignIn _googleSignIn = GoogleSignIn( + // Optional clientId + // clientId: '479882132969-9i9aqik3jfjd7qhci1nqf0bm2g71rm1u.apps.googleusercontent.com', scopes: [ 'email', 'https://www.googleapis.com/auth/contacts.readonly', diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m index 660a32272f84..fdc6e31e9291 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m @@ -77,7 +77,15 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result ofType:@"plist"]; if (path) { NSMutableDictionary *plist = [[NSMutableDictionary alloc] initWithContentsOfFile:path]; - [GIDSignIn sharedInstance].clientID = plist[kClientIdKey]; + BOOL hasDynamicClientId = + [[call.arguments valueForKey:@"clientId"] isKindOfClass:[NSString class]]; + + if (hasDynamicClientId) { + [GIDSignIn sharedInstance].clientID = [call.arguments valueForKey:@"clientId"]; + } else { + [GIDSignIn sharedInstance].clientID = plist[kClientIdKey]; + } + [GIDSignIn sharedInstance].serverClientID = plist[kServerClientIdKey]; [GIDSignIn sharedInstance].scopes = call.arguments[@"scopes"]; [GIDSignIn sharedInstance].hostedDomain = call.arguments[@"hostedDomain"]; diff --git a/packages/google_sign_in/google_sign_in/pubspec.yaml b/packages/google_sign_in/google_sign_in/pubspec.yaml index 06fa12c0f4c0..23f2588c8f90 100644 --- a/packages/google_sign_in/google_sign_in/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/pubspec.yaml @@ -2,7 +2,7 @@ name: google_sign_in description: Flutter plugin for Google Sign-In, a secure authentication system for signing in with a Google account on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in -version: 5.0.0 +version: 5.0.1 flutter: plugin: @@ -16,7 +16,7 @@ flutter: default_package: google_sign_in_web dependencies: - google_sign_in_platform_interface: ^2.0.0 + google_sign_in_platform_interface: ^2.0.1 google_sign_in_web: ^0.10.0 flutter: sdk: flutter diff --git a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart index 79fa74ad1be1..4eb45a5dc38e 100755 --- a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart +++ b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart @@ -82,6 +82,25 @@ void main() { ); }); + test('signIn prioritize clientId parameter when available', () async { + final fakeClientId = 'fakeClientId'; + googleSignIn = GoogleSignIn(clientId: fakeClientId); + await googleSignIn.signIn(); + expect(googleSignIn.currentUser, isNotNull); + expect( + log, + [ + isMethodCall('init', arguments: { + 'signInOption': 'SignInOption.standard', + 'scopes': [], + 'hostedDomain': null, + 'clientId': fakeClientId, + }), + isMethodCall('signIn', arguments: null), + ], + ); + }); + test('signOut', () async { await googleSignIn.signOut(); expect(googleSignIn.currentUser, isNull); From c870bbb97057bb2a95a9d905d9a7d34fe5ca46ba Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Thu, 18 Mar 2021 13:00:10 -0400 Subject: [PATCH 0278/1565] Add an AUTHORS file to each plugin (#3725) This ensures that the AUTHORS list is distributed with the plugins whose copyright blocks refer to the project authors, for ease of reference. This is currently a copy of the top-level authors list, but over time they are expected to diverge as people contribute to specific plugins. This does not bump plugin versions or CHANGLELOGs, since it has no effect on the plugin itself; it will be picked up over time as we ship new versions of plugins. Part of https://github.com/flutter/flutter/issues/78448 --- CONTRIBUTING.md | 5 +- packages/android_alarm_manager/AUTHORS | 65 +++++++++++++++++++ packages/android_intent/AUTHORS | 65 +++++++++++++++++++ packages/battery/battery/AUTHORS | 65 +++++++++++++++++++ .../battery_platform_interface/AUTHORS | 65 +++++++++++++++++++ packages/camera/camera/AUTHORS | 65 +++++++++++++++++++ .../camera/camera_platform_interface/AUTHORS | 65 +++++++++++++++++++ packages/connectivity/connectivity/AUTHORS | 65 +++++++++++++++++++ .../connectivity/connectivity_for_web/AUTHORS | 65 +++++++++++++++++++ .../connectivity/connectivity_macos/AUTHORS | 65 +++++++++++++++++++ .../connectivity_platform_interface/AUTHORS | 65 +++++++++++++++++++ packages/device_info/device_info/AUTHORS | 65 +++++++++++++++++++ .../device_info_platform_interface/AUTHORS | 65 +++++++++++++++++++ packages/espresso/AUTHORS | 65 +++++++++++++++++++ packages/file_selector/file_selector/AUTHORS | 65 +++++++++++++++++++ .../file_selector_platform_interface/AUTHORS | 65 +++++++++++++++++++ .../file_selector/file_selector_web/AUTHORS | 65 +++++++++++++++++++ .../flutter_plugin_android_lifecycle/AUTHORS | 65 +++++++++++++++++++ .../google_maps_flutter/AUTHORS | 65 +++++++++++++++++++ .../AUTHORS | 65 +++++++++++++++++++ .../google_maps_flutter_web/AUTHORS | 65 +++++++++++++++++++ .../google_sign_in/google_sign_in/AUTHORS | 65 +++++++++++++++++++ .../google_sign_in_platform_interface/AUTHORS | 65 +++++++++++++++++++ .../google_sign_in/google_sign_in_web/AUTHORS | 65 +++++++++++++++++++ packages/image_picker/image_picker/AUTHORS | 65 +++++++++++++++++++ .../image_picker/image_picker_for_web/AUTHORS | 65 +++++++++++++++++++ .../image_picker_platform_interface/AUTHORS | 65 +++++++++++++++++++ packages/in_app_purchase/AUTHORS | 65 +++++++++++++++++++ packages/integration_test/AUTHORS | 65 +++++++++++++++++++ packages/ios_platform_images/AUTHORS | 65 +++++++++++++++++++ packages/local_auth/AUTHORS | 65 +++++++++++++++++++ packages/package_info/AUTHORS | 65 +++++++++++++++++++ packages/path_provider/path_provider/AUTHORS | 65 +++++++++++++++++++ .../path_provider/path_provider_linux/AUTHORS | 65 +++++++++++++++++++ .../path_provider/path_provider_macos/AUTHORS | 65 +++++++++++++++++++ .../path_provider_platform_interface/AUTHORS | 65 +++++++++++++++++++ .../path_provider_windows/AUTHORS | 65 +++++++++++++++++++ packages/plugin_platform_interface/AUTHORS | 65 +++++++++++++++++++ packages/quick_actions/AUTHORS | 65 +++++++++++++++++++ packages/sensors/AUTHORS | 65 +++++++++++++++++++ packages/share/AUTHORS | 65 +++++++++++++++++++ .../shared_preferences/AUTHORS | 65 +++++++++++++++++++ .../shared_preferences_linux/AUTHORS | 65 +++++++++++++++++++ .../shared_preferences_macos/AUTHORS | 65 +++++++++++++++++++ .../AUTHORS | 65 +++++++++++++++++++ .../shared_preferences_web/AUTHORS | 65 +++++++++++++++++++ .../shared_preferences_windows/AUTHORS | 65 +++++++++++++++++++ .../example/AUTHORS | 65 +++++++++++++++++++ packages/url_launcher/url_launcher/AUTHORS | 65 +++++++++++++++++++ .../url_launcher/url_launcher_linux/AUTHORS | 65 +++++++++++++++++++ .../url_launcher/url_launcher_macos/AUTHORS | 65 +++++++++++++++++++ .../url_launcher_platform_interface/AUTHORS | 65 +++++++++++++++++++ .../url_launcher/url_launcher_web/AUTHORS | 65 +++++++++++++++++++ .../src/third_party/platform_detect/AUTHORS | 65 +++++++++++++++++++ .../url_launcher/url_launcher_windows/AUTHORS | 65 +++++++++++++++++++ packages/video_player/video_player/AUTHORS | 65 +++++++++++++++++++ .../video_player_platform_interface/AUTHORS | 65 +++++++++++++++++++ .../video_player/video_player_web/AUTHORS | 65 +++++++++++++++++++ packages/webview_flutter/AUTHORS | 65 +++++++++++++++++++ .../wifi_info_flutter/AUTHORS | 65 +++++++++++++++++++ .../AUTHORS | 65 +++++++++++++++++++ 61 files changed, 3903 insertions(+), 2 deletions(-) create mode 100644 packages/android_alarm_manager/AUTHORS create mode 100644 packages/android_intent/AUTHORS create mode 100644 packages/battery/battery/AUTHORS create mode 100644 packages/battery/battery_platform_interface/AUTHORS create mode 100644 packages/camera/camera/AUTHORS create mode 100644 packages/camera/camera_platform_interface/AUTHORS create mode 100644 packages/connectivity/connectivity/AUTHORS create mode 100644 packages/connectivity/connectivity_for_web/AUTHORS create mode 100644 packages/connectivity/connectivity_macos/AUTHORS create mode 100644 packages/connectivity/connectivity_platform_interface/AUTHORS create mode 100644 packages/device_info/device_info/AUTHORS create mode 100644 packages/device_info/device_info_platform_interface/AUTHORS create mode 100644 packages/espresso/AUTHORS create mode 100644 packages/file_selector/file_selector/AUTHORS create mode 100644 packages/file_selector/file_selector_platform_interface/AUTHORS create mode 100644 packages/file_selector/file_selector_web/AUTHORS create mode 100644 packages/flutter_plugin_android_lifecycle/AUTHORS create mode 100644 packages/google_maps_flutter/google_maps_flutter/AUTHORS create mode 100644 packages/google_maps_flutter/google_maps_flutter_platform_interface/AUTHORS create mode 100644 packages/google_maps_flutter/google_maps_flutter_web/AUTHORS create mode 100644 packages/google_sign_in/google_sign_in/AUTHORS create mode 100644 packages/google_sign_in/google_sign_in_platform_interface/AUTHORS create mode 100644 packages/google_sign_in/google_sign_in_web/AUTHORS create mode 100644 packages/image_picker/image_picker/AUTHORS create mode 100644 packages/image_picker/image_picker_for_web/AUTHORS create mode 100644 packages/image_picker/image_picker_platform_interface/AUTHORS create mode 100644 packages/in_app_purchase/AUTHORS create mode 100644 packages/integration_test/AUTHORS create mode 100644 packages/ios_platform_images/AUTHORS create mode 100644 packages/local_auth/AUTHORS create mode 100644 packages/package_info/AUTHORS create mode 100644 packages/path_provider/path_provider/AUTHORS create mode 100644 packages/path_provider/path_provider_linux/AUTHORS create mode 100644 packages/path_provider/path_provider_macos/AUTHORS create mode 100644 packages/path_provider/path_provider_platform_interface/AUTHORS create mode 100644 packages/path_provider/path_provider_windows/AUTHORS create mode 100644 packages/plugin_platform_interface/AUTHORS create mode 100644 packages/quick_actions/AUTHORS create mode 100644 packages/sensors/AUTHORS create mode 100644 packages/share/AUTHORS create mode 100644 packages/shared_preferences/shared_preferences/AUTHORS create mode 100644 packages/shared_preferences/shared_preferences_linux/AUTHORS create mode 100644 packages/shared_preferences/shared_preferences_macos/AUTHORS create mode 100644 packages/shared_preferences/shared_preferences_platform_interface/AUTHORS create mode 100644 packages/shared_preferences/shared_preferences_web/AUTHORS create mode 100644 packages/shared_preferences/shared_preferences_windows/AUTHORS create mode 100644 packages/shared_preferences/shared_preferences_windows/example/AUTHORS create mode 100644 packages/url_launcher/url_launcher/AUTHORS create mode 100644 packages/url_launcher/url_launcher_linux/AUTHORS create mode 100644 packages/url_launcher/url_launcher_macos/AUTHORS create mode 100644 packages/url_launcher/url_launcher_platform_interface/AUTHORS create mode 100644 packages/url_launcher/url_launcher_web/AUTHORS create mode 100644 packages/url_launcher/url_launcher_web/lib/src/third_party/platform_detect/AUTHORS create mode 100644 packages/url_launcher/url_launcher_windows/AUTHORS create mode 100644 packages/video_player/video_player/AUTHORS create mode 100644 packages/video_player/video_player_platform_interface/AUTHORS create mode 100644 packages/video_player/video_player_web/AUTHORS create mode 100644 packages/webview_flutter/AUTHORS create mode 100644 packages/wifi_info_flutter/wifi_info_flutter/AUTHORS create mode 100644 packages/wifi_info_flutter/wifi_info_flutter_platform_interface/AUTHORS diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5a8a9ec5522f..d5ea4766b363 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -188,8 +188,9 @@ to merge the pull request and `pub submit` any affected packages. You must complete the [Contributor License Agreement](https://cla.developers.google.com/clas). You can do this online, and it only takes a minute. -If you've never submitted code before, you must add your (or your -organization's) name and contact info to the [AUTHORS](AUTHORS) file. +If you've never submitted code for that plugin before, you may also add your (or +your organization's) name and contact info to the AUTHORS file for the plugin. +You may also add it to the AUTHORS file for [the repository](AUTHORS). ### The review process diff --git a/packages/android_alarm_manager/AUTHORS b/packages/android_alarm_manager/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/android_alarm_manager/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/android_intent/AUTHORS b/packages/android_intent/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/android_intent/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/battery/battery/AUTHORS b/packages/battery/battery/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/battery/battery/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/battery/battery_platform_interface/AUTHORS b/packages/battery/battery_platform_interface/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/battery/battery_platform_interface/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/camera/camera/AUTHORS b/packages/camera/camera/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/camera/camera/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/camera/camera_platform_interface/AUTHORS b/packages/camera/camera_platform_interface/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/camera/camera_platform_interface/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/connectivity/connectivity/AUTHORS b/packages/connectivity/connectivity/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/connectivity/connectivity/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/connectivity/connectivity_for_web/AUTHORS b/packages/connectivity/connectivity_for_web/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/connectivity/connectivity_for_web/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/connectivity/connectivity_macos/AUTHORS b/packages/connectivity/connectivity_macos/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/connectivity/connectivity_macos/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/connectivity/connectivity_platform_interface/AUTHORS b/packages/connectivity/connectivity_platform_interface/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/connectivity/connectivity_platform_interface/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/device_info/device_info/AUTHORS b/packages/device_info/device_info/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/device_info/device_info/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/device_info/device_info_platform_interface/AUTHORS b/packages/device_info/device_info_platform_interface/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/device_info/device_info_platform_interface/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/espresso/AUTHORS b/packages/espresso/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/espresso/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/file_selector/file_selector/AUTHORS b/packages/file_selector/file_selector/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/file_selector/file_selector/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/file_selector/file_selector_platform_interface/AUTHORS b/packages/file_selector/file_selector_platform_interface/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/file_selector/file_selector_platform_interface/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/file_selector/file_selector_web/AUTHORS b/packages/file_selector/file_selector_web/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/file_selector/file_selector_web/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/flutter_plugin_android_lifecycle/AUTHORS b/packages/flutter_plugin_android_lifecycle/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/flutter_plugin_android_lifecycle/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/google_maps_flutter/google_maps_flutter/AUTHORS b/packages/google_maps_flutter/google_maps_flutter/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/AUTHORS b/packages/google_maps_flutter/google_maps_flutter_platform_interface/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/google_maps_flutter/google_maps_flutter_web/AUTHORS b/packages/google_maps_flutter/google_maps_flutter_web/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/google_sign_in/google_sign_in/AUTHORS b/packages/google_sign_in/google_sign_in/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/google_sign_in/google_sign_in/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/google_sign_in/google_sign_in_platform_interface/AUTHORS b/packages/google_sign_in/google_sign_in_platform_interface/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/google_sign_in/google_sign_in_platform_interface/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/google_sign_in/google_sign_in_web/AUTHORS b/packages/google_sign_in/google_sign_in_web/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/google_sign_in/google_sign_in_web/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/image_picker/image_picker/AUTHORS b/packages/image_picker/image_picker/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/image_picker/image_picker/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/image_picker/image_picker_for_web/AUTHORS b/packages/image_picker/image_picker_for_web/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/image_picker/image_picker_for_web/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/image_picker/image_picker_platform_interface/AUTHORS b/packages/image_picker/image_picker_platform_interface/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/image_picker/image_picker_platform_interface/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/in_app_purchase/AUTHORS b/packages/in_app_purchase/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/in_app_purchase/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/integration_test/AUTHORS b/packages/integration_test/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/integration_test/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/ios_platform_images/AUTHORS b/packages/ios_platform_images/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/ios_platform_images/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/local_auth/AUTHORS b/packages/local_auth/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/local_auth/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/package_info/AUTHORS b/packages/package_info/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/package_info/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/path_provider/path_provider/AUTHORS b/packages/path_provider/path_provider/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/path_provider/path_provider/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/path_provider/path_provider_linux/AUTHORS b/packages/path_provider/path_provider_linux/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/path_provider/path_provider_linux/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/path_provider/path_provider_macos/AUTHORS b/packages/path_provider/path_provider_macos/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/path_provider/path_provider_macos/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/path_provider/path_provider_platform_interface/AUTHORS b/packages/path_provider/path_provider_platform_interface/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/path_provider/path_provider_platform_interface/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/path_provider/path_provider_windows/AUTHORS b/packages/path_provider/path_provider_windows/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/path_provider/path_provider_windows/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/plugin_platform_interface/AUTHORS b/packages/plugin_platform_interface/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/plugin_platform_interface/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/quick_actions/AUTHORS b/packages/quick_actions/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/quick_actions/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/sensors/AUTHORS b/packages/sensors/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/sensors/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/share/AUTHORS b/packages/share/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/share/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/shared_preferences/shared_preferences/AUTHORS b/packages/shared_preferences/shared_preferences/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/shared_preferences/shared_preferences/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/shared_preferences/shared_preferences_linux/AUTHORS b/packages/shared_preferences/shared_preferences_linux/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/shared_preferences/shared_preferences_linux/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/shared_preferences/shared_preferences_macos/AUTHORS b/packages/shared_preferences/shared_preferences_macos/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/shared_preferences/shared_preferences_macos/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/shared_preferences/shared_preferences_platform_interface/AUTHORS b/packages/shared_preferences/shared_preferences_platform_interface/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/shared_preferences/shared_preferences_platform_interface/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/shared_preferences/shared_preferences_web/AUTHORS b/packages/shared_preferences/shared_preferences_web/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/shared_preferences/shared_preferences_web/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/shared_preferences/shared_preferences_windows/AUTHORS b/packages/shared_preferences/shared_preferences_windows/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/shared_preferences/shared_preferences_windows/example/AUTHORS b/packages/shared_preferences/shared_preferences_windows/example/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/example/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/url_launcher/url_launcher/AUTHORS b/packages/url_launcher/url_launcher/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/url_launcher/url_launcher/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/url_launcher/url_launcher_linux/AUTHORS b/packages/url_launcher/url_launcher_linux/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/url_launcher/url_launcher_linux/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/url_launcher/url_launcher_macos/AUTHORS b/packages/url_launcher/url_launcher_macos/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/url_launcher/url_launcher_macos/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/url_launcher/url_launcher_platform_interface/AUTHORS b/packages/url_launcher/url_launcher_platform_interface/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/url_launcher/url_launcher_platform_interface/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/url_launcher/url_launcher_web/AUTHORS b/packages/url_launcher/url_launcher_web/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/url_launcher/url_launcher_web/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/url_launcher/url_launcher_web/lib/src/third_party/platform_detect/AUTHORS b/packages/url_launcher/url_launcher_web/lib/src/third_party/platform_detect/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/url_launcher/url_launcher_web/lib/src/third_party/platform_detect/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/url_launcher/url_launcher_windows/AUTHORS b/packages/url_launcher/url_launcher_windows/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/url_launcher/url_launcher_windows/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/video_player/video_player/AUTHORS b/packages/video_player/video_player/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/video_player/video_player/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/video_player/video_player_platform_interface/AUTHORS b/packages/video_player/video_player_platform_interface/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/video_player/video_player_platform_interface/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/video_player/video_player_web/AUTHORS b/packages/video_player/video_player_web/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/video_player/video_player_web/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/webview_flutter/AUTHORS b/packages/webview_flutter/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/webview_flutter/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/wifi_info_flutter/wifi_info_flutter/AUTHORS b/packages/wifi_info_flutter/wifi_info_flutter/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/wifi_info_flutter/wifi_info_flutter/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/AUTHORS b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/AUTHORS new file mode 100644 index 000000000000..dbf9d190931b --- /dev/null +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/AUTHORS @@ -0,0 +1,65 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> From 6047b3f1bbb970d748bd5b213f5d0c206a0c2da8 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Thu, 18 Mar 2021 13:28:44 -0700 Subject: [PATCH 0279/1565] Fix cosmetic variations in copyrights and license files (#3730) - Replaces "the Flutter project authors" with the repo-standard version "The Flutter Authors" - Updates the license check not to allow "the Flutter project authors" in the future - Fixes a few minor cosmetic variations that had crept back into LICENSE files since my mass-standardization of those files. - Updates the license check to validate those to prevent such drift in the future. --- .../connectivity/connectivity_for_web/LICENSE | 2 +- packages/file_selector/file_selector/LICENSE | 2 +- .../file_selector_platform_interface/LICENSE | 2 +- .../file_selector/file_selector_web/LICENSE | 2 +- .../google_maps_flutter_web/LICENSE | 2 +- .../google_sign_in/google_sign_in/LICENSE | 2 +- .../googlesignin/BackgroundTaskRunner.java | 2 +- .../plugins/googlesignin/Executors.java | 2 +- .../googlesignin/GoogleSignInPlugin.java | 2 +- .../googlesignin/GoogleSignInWrapper.java | 2 +- .../integration_test/google_sign_in_test.dart | 2 +- .../ios/Classes/FLTGoogleSignInPlugin.h | 2 +- .../ios/Classes/FLTGoogleSignInPlugin.m | 2 +- .../google_sign_in/lib/google_sign_in.dart | 2 +- .../google_sign_in/lib/src/common.dart | 2 +- .../google_sign_in/lib/widgets.dart | 2 +- .../google_sign_in/google_sign_in_web/LICENSE | 2 +- .../test/tests_exist_elsewhere_test.dart | 2 +- packages/image_picker/image_picker/LICENSE | 2 +- packages/path_provider/path_provider/LICENSE | 2 +- packages/share/LICENSE | 2 +- .../shared_preferences_macos/LICENSE | 2 +- .../shared_preferences_windows/LICENSE | 52 ++++---- .../example/LICENSE | 52 ++++---- .../tool/lib/src/license_check_command.dart | 86 ++++++++++-- .../tool/test/license_check_command_test.dart | 123 ++++++++++++++++-- 26 files changed, 263 insertions(+), 94 deletions(-) diff --git a/packages/connectivity/connectivity_for_web/LICENSE b/packages/connectivity/connectivity_for_web/LICENSE index 26351460d9de..1d7bbaf70add 100644 --- a/packages/connectivity/connectivity_for_web/LICENSE +++ b/packages/connectivity/connectivity_for_web/LICENSE @@ -1,4 +1,4 @@ -Copyright 2016, the Flutter project authors. All rights reserved. +Copyright 2016 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/file_selector/file_selector/LICENSE b/packages/file_selector/file_selector/LICENSE index 2c91f1438173..67c7e2c52e46 100644 --- a/packages/file_selector/file_selector/LICENSE +++ b/packages/file_selector/file_selector/LICENSE @@ -22,4 +22,4 @@ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/file_selector/file_selector_platform_interface/LICENSE b/packages/file_selector/file_selector_platform_interface/LICENSE index 2c91f1438173..67c7e2c52e46 100644 --- a/packages/file_selector/file_selector_platform_interface/LICENSE +++ b/packages/file_selector/file_selector_platform_interface/LICENSE @@ -22,4 +22,4 @@ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/file_selector/file_selector_web/LICENSE b/packages/file_selector/file_selector_web/LICENSE index 2c91f1438173..67c7e2c52e46 100644 --- a/packages/file_selector/file_selector_web/LICENSE +++ b/packages/file_selector/file_selector_web/LICENSE @@ -22,4 +22,4 @@ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/LICENSE b/packages/google_maps_flutter/google_maps_flutter_web/LICENSE index 447867e0637e..bb6f2c07756f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/LICENSE +++ b/packages/google_maps_flutter/google_maps_flutter_web/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017, the Flutter project authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/google_sign_in/google_sign_in/LICENSE b/packages/google_sign_in/google_sign_in/LICENSE index 26351460d9de..1d7bbaf70add 100644 --- a/packages/google_sign_in/google_sign_in/LICENSE +++ b/packages/google_sign_in/google_sign_in/LICENSE @@ -1,4 +1,4 @@ -Copyright 2016, the Flutter project authors. All rights reserved. +Copyright 2016 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/BackgroundTaskRunner.java b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/BackgroundTaskRunner.java index e667be2aa0f9..95bc0153e41a 100755 --- a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/BackgroundTaskRunner.java +++ b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/BackgroundTaskRunner.java @@ -1,4 +1,4 @@ -// Copyright 2017, the Flutter project authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/Executors.java b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/Executors.java index 80b9d187d939..008a33c30052 100755 --- a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/Executors.java +++ b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/Executors.java @@ -1,4 +1,4 @@ -// Copyright 2017, the Flutter project authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java index eb3a3d0d91ec..351ed731cccd 100755 --- a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java +++ b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017, the Flutter project authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInWrapper.java b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInWrapper.java index 100069080bb4..3c84968f986c 100644 --- a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInWrapper.java +++ b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInWrapper.java @@ -1,4 +1,4 @@ -// Copyright 2020, the Flutter project authors. All rights reserved. +// 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. diff --git a/packages/google_sign_in/google_sign_in/integration_test/google_sign_in_test.dart b/packages/google_sign_in/google_sign_in/integration_test/google_sign_in_test.dart index 86423507fffc..d3896b57174c 100644 --- a/packages/google_sign_in/google_sign_in/integration_test/google_sign_in_test.dart +++ b/packages/google_sign_in/google_sign_in/integration_test/google_sign_in_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017, the Flutter project authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.h b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.h index f9d7f322a2e3..6447e9243483 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.h +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017, the Flutter project authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m index fdc6e31e9291..23584fd36922 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017, the Flutter project authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart b/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart index f803f96f85ed..2e094a8b1575 100644 --- a/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart +++ b/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart @@ -1,4 +1,4 @@ -// Copyright 2017, the Flutter project authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in/lib/src/common.dart b/packages/google_sign_in/google_sign_in/lib/src/common.dart index f9aaf199b899..e341a27a740d 100644 --- a/packages/google_sign_in/google_sign_in/lib/src/common.dart +++ b/packages/google_sign_in/google_sign_in/lib/src/common.dart @@ -1,4 +1,4 @@ -// Copyright 2017, the Flutter project authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in/lib/widgets.dart b/packages/google_sign_in/google_sign_in/lib/widgets.dart index f47e78fde2b2..c3537ab90394 100644 --- a/packages/google_sign_in/google_sign_in/lib/widgets.dart +++ b/packages/google_sign_in/google_sign_in/lib/widgets.dart @@ -1,4 +1,4 @@ -// Copyright 2017, the Flutter project authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in_web/LICENSE b/packages/google_sign_in/google_sign_in_web/LICENSE index 26351460d9de..1d7bbaf70add 100644 --- a/packages/google_sign_in/google_sign_in_web/LICENSE +++ b/packages/google_sign_in/google_sign_in_web/LICENSE @@ -1,4 +1,4 @@ -Copyright 2016, the Flutter project authors. All rights reserved. +Copyright 2016 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/google_sign_in/google_sign_in_web/test/tests_exist_elsewhere_test.dart b/packages/google_sign_in/google_sign_in_web/test/tests_exist_elsewhere_test.dart index d6a165667707..64d8e547e485 100644 --- a/packages/google_sign_in/google_sign_in_web/test/tests_exist_elsewhere_test.dart +++ b/packages/google_sign_in/google_sign_in_web/test/tests_exist_elsewhere_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Flutter project authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/image_picker/image_picker/LICENSE b/packages/image_picker/image_picker/LICENSE index c4e4de2acfcd..7cd0a6f3b98f 100644 --- a/packages/image_picker/image_picker/LICENSE +++ b/packages/image_picker/image_picker/LICENSE @@ -1,6 +1,6 @@ image_picker -Copyright 2017, the Flutter project authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/path_provider/path_provider/LICENSE b/packages/path_provider/path_provider/LICENSE index 447867e0637e..bb6f2c07756f 100644 --- a/packages/path_provider/path_provider/LICENSE +++ b/packages/path_provider/path_provider/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017, the Flutter project authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/share/LICENSE b/packages/share/LICENSE index 447867e0637e..bb6f2c07756f 100644 --- a/packages/share/LICENSE +++ b/packages/share/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017, the Flutter project authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/shared_preferences/shared_preferences_macos/LICENSE b/packages/shared_preferences/shared_preferences_macos/LICENSE index 447867e0637e..bb6f2c07756f 100644 --- a/packages/shared_preferences/shared_preferences_macos/LICENSE +++ b/packages/shared_preferences/shared_preferences_macos/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017, the Flutter project authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/shared_preferences/shared_preferences_windows/LICENSE b/packages/shared_preferences/shared_preferences_windows/LICENSE index c89293372cf3..a6d6c0749818 100644 --- a/packages/shared_preferences/shared_preferences_windows/LICENSE +++ b/packages/shared_preferences/shared_preferences_windows/LICENSE @@ -1,27 +1,25 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Copyright 2017 The Chromium Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/shared_preferences/shared_preferences_windows/example/LICENSE b/packages/shared_preferences/shared_preferences_windows/example/LICENSE index c89293372cf3..a6d6c0749818 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/LICENSE +++ b/packages/shared_preferences/shared_preferences_windows/example/LICENSE @@ -1,27 +1,25 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Copyright 2017 The Chromium Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/script/tool/lib/src/license_check_command.dart b/script/tool/lib/src/license_check_command.dart index 4e0e5931d3ee..e70e60b154d9 100644 --- a/script/tool/lib/src/license_check_command.dart +++ b/script/tool/lib/src/license_check_command.dart @@ -66,9 +66,40 @@ final List _firstPartyAuthors = [ 'The Chromium Authors', 'the Chromium project authors', 'The Flutter Authors', - 'the Flutter project authors', ]; +// The exact format of the BSD license that our license files should contain. +// Slight variants are not accepted because they may prevent consolidation in +// tools that assemble all licenses used in distributed applications. +// +// TODO(stuartmorgan): Add the copyright string here once that's completely +// standardized. +final String _fullBsdLicenseText = ''' +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +'''; + /// Validates that code files have copyright and license blocks. class LicenseCheckCommand extends PluginCommand { /// Creates a new license check command for [packagesDir]. @@ -90,13 +121,19 @@ class LicenseCheckCommand extends PluginCommand { @override Future run() async { - Iterable codeFiles = (await _getAllFiles()).where((File file) => + final Iterable codeFiles = (await _getAllFiles()).where((File file) => _codeFileExtensions.contains(p.extension(file.path)) && !_shouldIgnoreFile(file)); + final Iterable firstPartyLicenseFiles = (await _getAllFiles()).where( + (File file) => + p.basename(file.basename) == 'LICENSE' && !_isThirdParty(file)); - bool succeeded = await _checkLicenses(codeFiles); + final bool copyrightCheckSucceeded = await _checkCodeLicenses(codeFiles); + print('\n=======================================\n'); + final bool licenseCheckSucceeded = + await _checkLicenseFiles(firstPartyLicenseFiles); - if (!succeeded) { + if (!copyrightCheckSucceeded || !licenseCheckSucceeded) { throw ToolExit(1); } } @@ -110,7 +147,7 @@ class LicenseCheckCommand extends PluginCommand { // Checks all license blocks for [codeFiles], returning false if any of them // fail validation. - Future _checkLicenses(Iterable codeFiles) async { + Future _checkCodeLicenses(Iterable codeFiles) async { final List filesWithoutDetectedCopyright = []; final List filesWithoutDetectedLicense = []; final List misplacedThirdPartyFiles = []; @@ -133,8 +170,7 @@ class LicenseCheckCommand extends PluginCommand { continue; } final String author = copyright.group(1); - if (!_firstPartyAuthors.contains(author) && - !p.split(file.path).contains('third_party')) { + if (!_firstPartyAuthors.contains(author) && !_isThirdParty(file)) { misplacedThirdPartyFiles.add(file); } @@ -146,7 +182,7 @@ class LicenseCheckCommand extends PluginCommand { filesWithoutDetectedLicense.add(file); } } - _print('\n\n'); + _print('\n'); // Sort by path for more usable output. final pathCompare = (File a, File b) => a.path.compareTo(b.path); @@ -188,7 +224,35 @@ class LicenseCheckCommand extends PluginCommand { filesWithoutDetectedLicense.isEmpty && misplacedThirdPartyFiles.isEmpty; if (succeeded) { - _print('All files passed validation!'); + _print('All source files passed validation!'); + } + return succeeded; + } + + // Checks all provide LICENSE files, returning false if any of them + // fail validation. + Future _checkLicenseFiles(Iterable files) async { + final List incorrectLicenseFiles = []; + + for (final File file in files) { + _print('Checking ${file.path}'); + if (!file.readAsStringSync().contains(_fullBsdLicenseText)) { + incorrectLicenseFiles.add(file); + } + } + _print('\n'); + + if (incorrectLicenseFiles.isNotEmpty) { + _print('The following LICENSE files do not follow the expected format:'); + for (final File file in incorrectLicenseFiles) { + _print(' ${file.path}'); + } + _print('Please ensure that they use the exact format used in this repository".\n'); + } + + bool succeeded = incorrectLicenseFiles.isEmpty; + if (succeeded) { + _print('All LICENSE files passed validation!'); } return succeeded; } @@ -201,6 +265,10 @@ class LicenseCheckCommand extends PluginCommand { _ignoredFullBasenameList.contains(p.basename(path))); } + bool _isThirdParty(File file) { + return p.split(file.path).contains('third_party'); + } + Future> _getAllFiles() => packagesDir.parent .list(recursive: true, followLinks: false) .where((FileSystemEntity entity) => entity is File) diff --git a/script/tool/test/license_check_command_test.dart b/script/tool/test/license_check_command_test.dart index 524e72712360..8ae956740d72 100644 --- a/script/tool/test/license_check_command_test.dart +++ b/script/tool/test/license_check_command_test.dart @@ -134,7 +134,7 @@ void main() { // Sanity check that the test did actually check a file. expect(printedMessages, contains('Checking checked.cc')); - expect(printedMessages, contains('All files passed validation!')); + expect(printedMessages, contains('All source files passed validation!')); }); test('handles the comment styles for all supported languages', () async { @@ -154,7 +154,7 @@ void main() { expect(printedMessages, contains('Checking file_a.cc')); expect(printedMessages, contains('Checking file_b.sh')); expect(printedMessages, contains('Checking file_c.html')); - expect(printedMessages, contains('All files passed validation!')); + expect(printedMessages, contains('All source files passed validation!')); }); test('fails if any checked files are missing license blocks', () async { @@ -176,7 +176,8 @@ void main() { expect(printedMessages, contains(' bad.cc')); expect(printedMessages, contains(' bad.h')); // Failure shouldn't print the success message. - expect(printedMessages, isNot(contains('All files passed validation!'))); + expect(printedMessages, + isNot(contains('All source files passed validation!'))); }); test('fails if any checked files are missing just the copyright', () async { @@ -195,7 +196,8 @@ void main() { contains('No copyright line was found for the following files:')); expect(printedMessages, contains(' bad.cc')); // Failure shouldn't print the success message. - expect(printedMessages, isNot(contains('All files passed validation!'))); + expect(printedMessages, + isNot(contains('All source files passed validation!'))); }); test('fails if any checked files are missing just the license', () async { @@ -214,7 +216,8 @@ void main() { contains('No recognized license was found for the following files:')); expect(printedMessages, contains(' bad.cc')); // Failure shouldn't print the success message. - expect(printedMessages, isNot(contains('All files passed validation!'))); + expect(printedMessages, + isNot(contains('All source files passed validation!'))); }); test('fails if any third-party code is not in a third_party directory', @@ -234,7 +237,8 @@ void main() { 'but are not in a "third_party/" directory:')); expect(printedMessages, contains(' third_party.cc')); // Failure shouldn't print the success message. - expect(printedMessages, isNot(contains('All files passed validation!'))); + expect(printedMessages, + isNot(contains('All source files passed validation!'))); }); test('succeeds for third-party code in a third_party directory', () async { @@ -252,7 +256,7 @@ void main() { // Sanity check that the test did actually check the file. expect(printedMessages, contains('Checking a_plugin/lib/src/third_party/file.cc')); - expect(printedMessages, contains('All files passed validation!')); + expect(printedMessages, contains('All source files passed validation!')); }); test('fails for licenses that the tool does not expect', () async { @@ -274,7 +278,8 @@ void main() { contains('No recognized license was found for the following files:')); expect(printedMessages, contains(' third_party/bad.cc')); // Failure shouldn't print the success message. - expect(printedMessages, isNot(contains('All files passed validation!'))); + expect(printedMessages, + isNot(contains('All source files passed validation!'))); }); test('Apache is not recognized for new authors without validation changes', @@ -300,7 +305,107 @@ void main() { contains('No recognized license was found for the following files:')); expect(printedMessages, contains(' third_party/bad.cc')); // Failure shouldn't print the success message. - expect(printedMessages, isNot(contains('All files passed validation!'))); + expect(printedMessages, + isNot(contains('All source files passed validation!'))); + }); + + test('passes if all first-party LICENSE files are correctly formatted', + () async { + File license = root.childFile('LICENSE'); + license.createSync(); + license.writeAsStringSync(_correctLicenseFileText); + + await runner.run(['license-check']); + + // Sanity check that the test did actually check the file. + expect(printedMessages, contains('Checking LICENSE')); + expect(printedMessages, contains('All LICENSE files passed validation!')); + }); + + test('fails if any first-party LICENSE files are incorrectly formatted', + () async { + File license = root.childFile('LICENSE'); + license.createSync(); + license.writeAsStringSync(_incorrectLicenseFileText); + + await expectLater(() => runner.run(['license-check']), + throwsA(const TypeMatcher())); + + expect(printedMessages, + isNot(contains('All LICENSE files passed validation!'))); + }); + + test('ignores third-party LICENSE format', + () async { + File license = root.childDirectory('third_party').childFile('LICENSE'); + license.createSync(recursive: true); + license.writeAsStringSync(_incorrectLicenseFileText); + + await runner.run(['license-check']); + + // The file shouldn't be checked. + expect(printedMessages, isNot(contains('Checking third_party/LICENSE'))); + expect(printedMessages, contains('All LICENSE files passed validation!')); }); }); } + +const String _correctLicenseFileText = + '''Copyright 2017 The Flutter Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +'''; + +// A common incorrect version created by copying text intended for a code file, +// with comment markers. +const String _incorrectLicenseFileText = + '''// Copyright 2017 The Flutter Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +'''; From 089a88739745442f248fbf022c80a6711d6a56a6 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Thu, 18 Mar 2021 16:05:33 -0700 Subject: [PATCH 0280/1565] Standardize Copyrights: Chromium->Flutter (#2996) In all copyright messages (and in the Xcode project organization name) standardize on "The Flutter Authors", adding "The Chromium Authors" to the Flutter AUTHORS list. This reduces inconsistency in the copyright lines in this repository, moving closer to a single consistent copyright+license (as in flutter/engine and flutter/flutter) Updates the validation script to no longer accept "The Chromium Authors" or "the Chromium project authors" in first-party code. --- AUTHORS | 1 + LICENSE | 2 +- packages/android_alarm_manager/AUTHORS | 1 + packages/android_alarm_manager/LICENSE | 2 +- .../AlarmBroadcastReceiver.java | 2 +- .../plugins/androidalarmmanager/AlarmService.java | 2 +- .../AndroidAlarmManagerPlugin.java | 2 +- .../FlutterBackgroundExecutor.java | 2 +- .../PluginRegistrantException.java | 2 +- .../RebootBroadcastReceiver.java | 2 +- .../BackgroundExecutionTest.java | 2 +- .../DriverExtensionActivity.java | 2 +- .../androidalarmmanager/MainActivityTest.java | 2 +- .../EmbeddingV1Activity.java | 2 +- .../android_alarm_manager_test.dart | 2 +- .../android_alarm_manager/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../lib/android_alarm_manager.dart | 2 +- .../test/android_alarm_manager_test.dart | 2 +- packages/android_intent/AUTHORS | 1 + packages/android_intent/LICENSE | 2 +- .../plugins/androidintent/AndroidIntentPlugin.java | 2 +- .../plugins/androidintent/IntentSender.java | 2 +- .../androidintent/MethodCallHandlerImpl.java | 2 +- .../androidintent/MethodCallHandlerImplTest.java | 2 +- .../androidintentexample/EmbeddingV1Activity.java | 2 +- .../integration_test/android_intent_test.dart | 2 +- packages/android_intent/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- packages/android_intent/lib/android_intent.dart | 2 +- packages/android_intent/lib/flag.dart | 2 +- packages/battery/battery/AUTHORS | 1 + packages/battery/battery/LICENSE | 2 +- .../io/flutter/plugins/battery/BatteryPlugin.java | 2 +- .../plugins/battery/EmbedderV1ActivityTest.java | 2 +- .../plugins/battery/FlutterActivityTest.java | 2 +- .../plugins/batteryexample/EmbedderV1Activity.java | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../battery/example/ios/Runner/AppDelegate.h | 2 +- .../battery/example/ios/Runner/AppDelegate.m | 2 +- packages/battery/battery/example/ios/Runner/main.m | 2 +- packages/battery/battery/example/lib/main.dart | 2 +- .../battery/integration_test/battery_test.dart | 2 +- .../battery/battery/ios/Classes/FLTBatteryPlugin.h | 2 +- .../battery/battery/ios/Classes/FLTBatteryPlugin.m | 2 +- packages/battery/battery/lib/battery.dart | 2 +- packages/battery/battery/test/battery_test.dart | 2 +- .../battery/battery_platform_interface/AUTHORS | 1 + .../battery/battery_platform_interface/LICENSE | 2 +- .../lib/battery_platform_interface.dart | 2 +- .../lib/enums/battery_state.dart | 2 +- .../lib/method_channel/method_channel_battery.dart | 2 +- .../test/method_channel_battery_test.dart | 2 +- packages/camera/camera/AUTHORS | 1 + packages/camera/camera/LICENSE | 2 +- .../java/io/flutter/plugins/camera/Camera.java | 2 +- .../flutter/plugins/camera/CameraPermissions.java | 2 +- .../io/flutter/plugins/camera/CameraPlugin.java | 2 +- .../io/flutter/plugins/camera/CameraRegions.java | 2 +- .../io/flutter/plugins/camera/CameraUtils.java | 2 +- .../java/io/flutter/plugins/camera/CameraZoom.java | 2 +- .../io/flutter/plugins/camera/DartMessenger.java | 2 +- .../plugins/camera/DeviceOrientationManager.java | 2 +- .../plugins/camera/MethodCallHandlerImpl.java | 2 +- .../plugins/camera/PictureCaptureRequest.java | 2 +- .../plugins/camera/media/MediaRecorderBuilder.java | 2 +- .../flutter/plugins/camera/types/ExposureMode.java | 2 +- .../io/flutter/plugins/camera/types/FlashMode.java | 2 +- .../io/flutter/plugins/camera/types/FocusMode.java | 2 +- .../plugins/camera/types/ResolutionPreset.java | 2 +- .../plugins/camera/CameraPermissionsTest.java | 2 +- .../flutter/plugins/camera/CameraRegionsTest.java | 2 +- .../io/flutter/plugins/camera/CameraUtilsTest.java | 2 +- .../io/flutter/plugins/camera/CameraZoomTest.java | 2 +- .../flutter/plugins/camera/DartMessengerTest.java | 2 +- .../plugins/camera/PictureCaptureRequestTest.java | 2 +- .../camera/media/MediaRecorderBuilderTest.java | 2 +- .../plugins/camera/types/ExposureModeTest.java | 2 +- .../plugins/camera/types/FlashModeTest.java | 2 +- .../plugins/camera/types/FocusModeTest.java | 2 +- .../example/integration_test/camera_test.dart | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- packages/camera/camera/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- packages/camera/camera/ios/Classes/CameraPlugin.h | 2 +- packages/camera/camera/ios/Classes/CameraPlugin.m | 2 +- .../camera/camera/ios/Tests/CameraPluginTests.m | 2 +- packages/camera/camera/lib/camera.dart | 2 +- .../camera/camera/lib/src/camera_controller.dart | 2 +- packages/camera/camera/lib/src/camera_image.dart | 2 +- packages/camera/camera/lib/src/camera_preview.dart | 2 +- .../camera/test/camera_image_stream_test.dart | 2 +- packages/camera/camera/test/camera_image_test.dart | 2 +- packages/camera/camera/test/camera_test.dart | 2 +- packages/camera/camera/test/camera_value_test.dart | 2 +- .../camera/test/utils/method_channel_mock.dart | 2 +- packages/camera/camera_platform_interface/AUTHORS | 1 + packages/camera/camera_platform_interface/LICENSE | 2 +- .../lib/camera_platform_interface.dart | 2 +- .../lib/src/events/camera_event.dart | 2 +- .../lib/src/events/device_event.dart | 2 +- .../src/method_channel/method_channel_camera.dart | 2 +- .../src/platform_interface/camera_platform.dart | 2 +- .../lib/src/types/camera_description.dart | 2 +- .../lib/src/types/camera_exception.dart | 2 +- .../lib/src/types/exposure_mode.dart | 2 +- .../lib/src/types/flash_mode.dart | 2 +- .../lib/src/types/focus_mode.dart | 2 +- .../lib/src/types/image_format_group.dart | 2 +- .../lib/src/types/resolution_preset.dart | 2 +- .../lib/src/types/types.dart | 2 +- .../lib/src/utils/utils.dart | 2 +- .../test/camera_platform_interface_test.dart | 2 +- .../test/events/camera_event_test.dart | 2 +- .../test/events/device_event_test.dart | 2 +- .../method_channel/method_channel_camera_test.dart | 2 +- .../test/types/camera_description_test.dart | 2 +- .../test/types/camera_exception_test.dart | 2 +- .../test/types/exposure_mode_test.dart | 2 +- .../test/types/flash_mode_test.dart | 2 +- .../test/types/focus_mode_test.dart | 2 +- .../test/types/image_group_test.dart | 2 +- .../test/types/resolution_preset_test.dart | 2 +- .../test/utils/method_channel_mock.dart | 2 +- .../test/utils/utils_test.dart | 2 +- packages/connectivity/connectivity/AUTHORS | 1 + packages/connectivity/connectivity/LICENSE | 2 +- .../flutter/plugins/connectivity/Connectivity.java | 2 +- .../ConnectivityBroadcastReceiver.java | 2 +- .../ConnectivityMethodChannelHandler.java | 2 +- .../plugins/connectivity/ConnectivityPlugin.java | 2 +- .../connectivityexample/EmbeddingV1Activity.java | 2 +- .../EmbeddingV1ActivityTest.java | 2 +- .../connectivityexample/FlutterActivityTest.java | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../connectivity/example/ios/Runner/AppDelegate.h | 2 +- .../connectivity/example/ios/Runner/AppDelegate.m | 2 +- .../connectivity/example/ios/Runner/main.m | 2 +- .../connectivity/example/lib/main.dart | 2 +- .../integration_test/connectivity_test.dart | 2 +- .../example/test_driver/test/integration_test.dart | 2 +- .../integration_test/connectivity_test.dart | 2 +- .../ios/Classes/FLTConnectivityPlugin.h | 2 +- .../ios/Classes/FLTConnectivityPlugin.m | 2 +- .../connectivity/lib/connectivity.dart | 2 +- .../connectivity/test/connectivity_test.dart | 2 +- packages/connectivity/connectivity_for_web/AUTHORS | 1 + .../example/test_driver/integration_driver.dart | 2 +- packages/connectivity/connectivity_macos/AUTHORS | 1 + packages/connectivity/connectivity_macos/LICENSE | 2 +- .../connectivity_macos/example/lib/main.dart | 2 +- .../integration_test/connectivity_test.dart | 2 +- .../example/test_driver/test/integration_test.dart | 2 +- .../macos/Classes/ConnectivityPlugin.swift | 2 +- .../connectivity_macos/macos/Classes/IPHelper.h | 2 +- .../connectivity_platform_interface/AUTHORS | 1 + .../connectivity_platform_interface/LICENSE | 2 +- .../lib/connectivity_platform_interface.dart | 2 +- .../lib/src/enums.dart | 2 +- .../lib/src/method_channel_connectivity.dart | 2 +- .../lib/src/utils.dart | 2 +- .../test/method_channel_connectivity_test.dart | 2 +- packages/device_info/device_info/AUTHORS | 1 + packages/device_info/device_info/LICENSE | 2 +- .../plugins/deviceinfo/DeviceInfoPlugin.java | 2 +- .../plugins/deviceinfo/MethodCallHandlerImpl.java | 2 +- .../deviceinfoexample/EmbeddingV1Activity.java | 2 +- .../example/integration_test/device_info_test.dart | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../device_info/example/ios/Runner/AppDelegate.h | 2 +- .../device_info/example/ios/Runner/AppDelegate.m | 2 +- .../device_info/example/ios/Runner/main.m | 2 +- .../device_info/device_info/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../device_info/ios/Classes/FLTDeviceInfoPlugin.h | 2 +- .../device_info/ios/Classes/FLTDeviceInfoPlugin.m | 2 +- .../device_info/device_info/lib/device_info.dart | 2 +- .../device_info_platform_interface/AUTHORS | 1 + .../device_info_platform_interface/LICENSE | 2 +- .../lib/device_info_platform_interface.dart | 2 +- .../method_channel/method_channel_device_info.dart | 2 +- .../lib/model/android_device_info.dart | 2 +- .../lib/model/ios_device_info.dart | 2 +- .../test/method_channel_device_info_test.dart | 2 +- packages/espresso/AUTHORS | 1 + packages/espresso/LICENSE | 2 +- .../test/espresso/flutter/EspressoFlutter.java | 2 +- .../test/espresso/flutter/action/ActionUtil.java | 2 +- .../test/espresso/flutter/action/ClickAction.java | 2 +- .../espresso/flutter/action/FlutterActions.java | 2 +- .../flutter/action/FlutterScrollToAction.java | 2 +- .../flutter/action/FlutterTypeTextAction.java | 2 +- .../espresso/flutter/action/FlutterViewAction.java | 2 +- .../flutter/action/SyntheticClickAction.java | 2 +- .../flutter/action/WaitUntilIdleAction.java | 2 +- .../action/WidgetCoordinatesCalculator.java | 2 +- .../espresso/flutter/action/WidgetInfoFetcher.java | 2 +- .../test/espresso/flutter/api/FlutterAction.java | 2 +- .../flutter/api/FlutterTestingProtocol.java | 2 +- .../test/espresso/flutter/api/SyntheticAction.java | 2 +- .../test/espresso/flutter/api/WidgetAction.java | 2 +- .../test/espresso/flutter/api/WidgetAssertion.java | 2 +- .../test/espresso/flutter/api/WidgetMatcher.java | 2 +- .../flutter/assertion/FlutterAssertions.java | 2 +- .../flutter/assertion/FlutterViewAssertion.java | 2 +- .../test/espresso/flutter/common/Constants.java | 2 +- .../test/espresso/flutter/common/Duration.java | 2 +- .../exception/AmbiguousWidgetMatcherException.java | 2 +- .../exception/InvalidFlutterViewException.java | 2 +- .../exception/NoMatchingWidgetException.java | 2 +- .../flutter/internal/idgenerator/IdException.java | 2 +- .../flutter/internal/idgenerator/IdGenerator.java | 2 +- .../flutter/internal/idgenerator/IdGenerators.java | 2 +- .../flutter/internal/jsonrpc/JsonRpcClient.java | 2 +- .../internal/jsonrpc/message/ErrorObject.java | 2 +- .../internal/jsonrpc/message/JsonRpcRequest.java | 2 +- .../internal/jsonrpc/message/JsonRpcResponse.java | 2 +- .../internal/protocol/impl/DartVmService.java | 2 +- .../internal/protocol/impl/DartVmServiceUtil.java | 2 +- .../protocol/impl/FlutterProtocolException.java | 2 +- .../internal/protocol/impl/GetOffsetAction.java | 2 +- .../internal/protocol/impl/GetOffsetResponse.java | 2 +- .../internal/protocol/impl/GetVmResponse.java | 2 +- .../protocol/impl/GetWidgetDiagnosticsAction.java | 2 +- .../impl/GetWidgetDiagnosticsResponse.java | 2 +- .../protocol/impl/NoPendingFrameCondition.java | 2 +- .../impl/NoPendingPlatformMessagesCondition.java | 2 +- .../impl/NoTransientCallbacksCondition.java | 2 +- .../internal/protocol/impl/WaitCondition.java | 2 +- .../protocol/impl/WaitForConditionAction.java | 2 +- .../internal/protocol/impl/WidgetInfoFactory.java | 2 +- .../espresso/flutter/matcher/FlutterMatchers.java | 2 +- .../flutter/matcher/IsDescendantOfMatcher.java | 2 +- .../flutter/matcher/IsExistingMatcher.java | 2 +- .../espresso/flutter/matcher/WithTextMatcher.java | 2 +- .../flutter/matcher/WithTooltipMatcher.java | 2 +- .../espresso/flutter/matcher/WithTypeMatcher.java | 2 +- .../flutter/matcher/WithValueKeyMatcher.java | 2 +- .../test/espresso/flutter/model/WidgetInfo.java | 2 +- .../espresso/flutter/model/WidgetInfoBuilder.java | 2 +- .../java/com/example/MainActivityTest.java | 2 +- packages/flutter_plugin_android_lifecycle/AUTHORS | 1 + packages/flutter_plugin_android_lifecycle/LICENSE | 2 +- .../plugins/lifecycle/FlutterLifecycleAdapter.java | 2 +- .../FlutterAndroidLifecyclePlugin.java | 2 +- .../lifecycle/FlutterLifecycleAdapterTest.java | 2 +- .../EmbeddingV1ActivityTest.java | 2 +- .../MainActivityTest.java | 2 +- .../MainActivity.java | 2 +- .../flutter_plugin_android_lifecycle_test.dart | 2 +- .../example/lib/main.dart | 2 +- .../lib/flutter_plugin_android_lifecycle.dart | 2 +- .../google_maps_flutter/AUTHORS | 1 + .../google_maps_flutter/LICENSE | 2 +- .../flutter/plugins/googlemaps/CircleBuilder.java | 2 +- .../plugins/googlemaps/CircleController.java | 2 +- .../plugins/googlemaps/CircleOptionsSink.java | 2 +- .../plugins/googlemaps/CirclesController.java | 2 +- .../io/flutter/plugins/googlemaps/Convert.java | 2 +- .../plugins/googlemaps/GoogleMapBuilder.java | 2 +- .../plugins/googlemaps/GoogleMapController.java | 2 +- .../plugins/googlemaps/GoogleMapFactory.java | 2 +- .../plugins/googlemaps/GoogleMapListener.java | 2 +- .../plugins/googlemaps/GoogleMapOptionsSink.java | 2 +- .../plugins/googlemaps/GoogleMapsPlugin.java | 2 +- .../plugins/googlemaps/LifecycleProvider.java | 2 +- .../flutter/plugins/googlemaps/MarkerBuilder.java | 2 +- .../plugins/googlemaps/MarkerController.java | 2 +- .../plugins/googlemaps/MarkerOptionsSink.java | 2 +- .../plugins/googlemaps/MarkersController.java | 2 +- .../flutter/plugins/googlemaps/PolygonBuilder.java | 2 +- .../plugins/googlemaps/PolygonController.java | 2 +- .../plugins/googlemaps/PolygonOptionsSink.java | 2 +- .../plugins/googlemaps/PolygonsController.java | 2 +- .../plugins/googlemaps/PolylineBuilder.java | 2 +- .../plugins/googlemaps/PolylineController.java | 2 +- .../plugins/googlemaps/PolylineOptionsSink.java | 2 +- .../plugins/googlemaps/PolylinesController.java | 2 +- .../plugins/googlemaps/TileOverlayBuilder.java | 2 +- .../plugins/googlemaps/TileOverlayController.java | 2 +- .../plugins/googlemaps/TileOverlaySink.java | 2 +- .../plugins/googlemaps/TileOverlaysController.java | 2 +- .../plugins/googlemaps/TileProviderController.java | 2 +- .../plugins/googlemaps/CircleBuilderTest.java | 2 +- .../plugins/googlemaps/CircleControllerTest.java | 2 +- .../plugins/googlemaps/PolygonBuilderTest.java | 2 +- .../plugins/googlemaps/PolygonControllerTest.java | 2 +- .../plugins/googlemaps/PolylineBuilderTest.java | 2 +- .../plugins/googlemaps/PolylineControllerTest.java | 2 +- .../integration_test/google_map_inspector.dart | 2 +- .../example/integration_test/google_maps_test.dart | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../example/lib/animate_camera.dart | 2 +- .../google_maps_flutter/example/lib/lite_mode.dart | 2 +- .../google_maps_flutter/example/lib/main.dart | 2 +- .../google_maps_flutter/example/lib/map_click.dart | 2 +- .../example/lib/map_coordinates.dart | 2 +- .../google_maps_flutter/example/lib/map_ui.dart | 2 +- .../example/lib/marker_icons.dart | 2 +- .../example/lib/move_camera.dart | 2 +- .../google_maps_flutter/example/lib/padding.dart | 2 +- .../google_maps_flutter/example/lib/page.dart | 2 +- .../example/lib/place_circle.dart | 2 +- .../example/lib/place_marker.dart | 2 +- .../example/lib/place_polygon.dart | 2 +- .../example/lib/place_polyline.dart | 2 +- .../example/lib/scrolling_map.dart | 2 +- .../google_maps_flutter/example/lib/snapshot.dart | 2 +- .../example/lib/tile_overlay.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../Classes/FLTGoogleMapTileOverlayController.h | 2 +- .../Classes/FLTGoogleMapTileOverlayController.m | 2 +- .../ios/Classes/FLTGoogleMapsPlugin.h | 2 +- .../ios/Classes/FLTGoogleMapsPlugin.m | 2 +- .../ios/Classes/GoogleMapCircleController.h | 2 +- .../ios/Classes/GoogleMapCircleController.m | 2 +- .../ios/Classes/GoogleMapController.h | 2 +- .../ios/Classes/GoogleMapController.m | 2 +- .../ios/Classes/GoogleMapMarkerController.h | 4 ++-- .../ios/Classes/GoogleMapMarkerController.m | 2 +- .../ios/Classes/GoogleMapPolygonController.h | 2 +- .../ios/Classes/GoogleMapPolygonController.m | 2 +- .../ios/Classes/GoogleMapPolylineController.h | 2 +- .../ios/Classes/GoogleMapPolylineController.m | 2 +- .../ios/Classes/JsonConversions.h | 2 +- .../ios/Classes/JsonConversions.m | 2 +- .../lib/google_maps_flutter.dart | 2 +- .../google_maps_flutter/lib/src/controller.dart | 2 +- .../google_maps_flutter/lib/src/google_map.dart | 2 +- .../test/android_google_map_test.dart | 2 +- .../test/circle_updates_test.dart | 2 +- .../test/fake_maps_controllers.dart | 2 +- .../google_maps_flutter/test/google_map_test.dart | 2 +- .../test/map_creation_test.dart | 2 +- .../test/marker_updates_test.dart | 2 +- .../test/polygon_updates_test.dart | 2 +- .../test/polyline_updates_test.dart | 2 +- .../test/tile_overlay_updates_test.dart | 2 +- .../google_maps_flutter_platform_interface/AUTHORS | 1 + .../google_maps_flutter_platform_interface/LICENSE | 2 +- .../google_maps_flutter_platform_interface.dart | 2 +- .../lib/src/events/map_event.dart | 2 +- .../method_channel_google_maps_flutter.dart | 2 +- .../google_maps_flutter_platform.dart | 2 +- .../lib/src/types/bitmap.dart | 2 +- .../lib/src/types/callbacks.dart | 2 +- .../lib/src/types/camera.dart | 2 +- .../lib/src/types/cap.dart | 2 +- .../lib/src/types/circle.dart | 2 +- .../lib/src/types/circle_updates.dart | 2 +- .../lib/src/types/joint_type.dart | 2 +- .../lib/src/types/location.dart | 2 +- .../lib/src/types/maps_object.dart | 2 +- .../lib/src/types/maps_object_updates.dart | 2 +- .../lib/src/types/marker.dart | 2 +- .../lib/src/types/marker_updates.dart | 2 +- .../lib/src/types/pattern_item.dart | 2 +- .../lib/src/types/polygon.dart | 2 +- .../lib/src/types/polygon_updates.dart | 2 +- .../lib/src/types/polyline.dart | 2 +- .../lib/src/types/polyline_updates.dart | 2 +- .../lib/src/types/screen_coordinate.dart | 2 +- .../lib/src/types/tile.dart | 2 +- .../lib/src/types/tile_overlay.dart | 2 +- .../lib/src/types/tile_overlay_updates.dart | 2 +- .../lib/src/types/tile_provider.dart | 2 +- .../lib/src/types/types.dart | 2 +- .../lib/src/types/ui.dart | 2 +- .../lib/src/types/utils/circle.dart | 2 +- .../lib/src/types/utils/maps_object.dart | 2 +- .../lib/src/types/utils/marker.dart | 2 +- .../lib/src/types/utils/polygon.dart | 2 +- .../lib/src/types/utils/polyline.dart | 2 +- .../lib/src/types/utils/tile_overlay.dart | 2 +- .../google_maps_flutter_platform_test.dart | 2 +- .../test/types/bitmap_test.dart | 2 +- .../test/types/camera_test.dart | 2 +- .../test/types/maps_object_test.dart | 2 +- .../test/types/maps_object_updates_test.dart | 2 +- .../test/types/test_maps_object.dart | 2 +- .../test/types/tile_overlay_test.dart | 2 +- .../test/types/tile_overlay_updates_test.dart | 2 +- .../test/types/tile_test.dart | 2 +- .../google_maps_flutter_web/AUTHORS | 1 + .../google_maps_controller_test.dart | 2 +- .../integration_test/google_maps_plugin_test.dart | 2 +- .../example/integration_test/marker_test.dart | 2 +- .../example/integration_test/markers_test.dart | 2 +- .../example/integration_test/shape_test.dart | 2 +- .../example/integration_test/shapes_test.dart | 2 +- .../example/test_driver/integration_driver.dart | 2 +- .../lib/google_maps_flutter_web.dart | 2 +- .../google_maps_flutter_web/lib/src/circle.dart | 2 +- .../google_maps_flutter_web/lib/src/circles.dart | 2 +- .../google_maps_flutter_web/lib/src/convert.dart | 2 +- .../lib/src/google_maps_controller.dart | 2 +- .../lib/src/google_maps_flutter_web.dart | 2 +- .../google_maps_flutter_web/lib/src/marker.dart | 2 +- .../google_maps_flutter_web/lib/src/markers.dart | 2 +- .../google_maps_flutter_web/lib/src/polygon.dart | 2 +- .../google_maps_flutter_web/lib/src/polygons.dart | 2 +- .../google_maps_flutter_web/lib/src/polyline.dart | 2 +- .../google_maps_flutter_web/lib/src/polylines.dart | 2 +- .../lib/src/shims/dart_ui.dart | 2 +- .../lib/src/shims/dart_ui_fake.dart | 2 +- .../lib/src/shims/dart_ui_real.dart | 2 +- .../google_maps_flutter_web/lib/src/types.dart | 2 +- .../test/tests_exist_elsewhere_test.dart | 2 +- packages/google_sign_in/google_sign_in/AUTHORS | 1 + .../googlesigninexample/EmbeddingV1Activity.java | 2 +- .../EmbeddingV1ActivityTest.java | 2 +- .../googlesigninexample/FlutterActivityTest.java | 2 +- .../googlesignin/GoogleSignInPluginTests.java | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- .../google_sign_in/example/ios/Runner/main.m | 2 +- .../ios/Tests/GoogleSignInPluginTest.m | 2 +- .../test_driver/integration_test.dart | 2 +- .../google_sign_in_platform_interface/AUTHORS | 1 + .../google_sign_in_platform_interface/LICENSE | 2 +- .../lib/google_sign_in_platform_interface.dart | 2 +- .../lib/src/method_channel_google_sign_in.dart | 2 +- .../lib/src/types.dart | 2 +- .../lib/src/utils.dart | 2 +- .../google_sign_in_platform_interface_test.dart | 2 +- .../test/method_channel_google_sign_in_test.dart | 2 +- packages/google_sign_in/google_sign_in_web/AUTHORS | 1 + .../example/integration_test/auth2_test.dart | 2 +- .../example/integration_test/gapi_load_test.dart | 2 +- .../integration_test/gapi_mocks/gapi_mocks.dart | 2 +- .../gapi_mocks/src/auth2_init.dart | 2 +- .../integration_test/gapi_mocks/src/gapi.dart | 2 +- .../gapi_mocks/src/google_user.dart | 2 +- .../integration_test/gapi_mocks/src/test_iife.dart | 2 +- .../example/integration_test/gapi_utils_test.dart | 2 +- .../example/integration_test/src/test_utils.dart | 2 +- .../example/test_driver/integration_driver.dart | 2 +- .../google_sign_in_web/lib/google_sign_in_web.dart | 2 +- .../google_sign_in_web/lib/src/generated/gapi.dart | 2 +- .../lib/src/generated/gapiauth2.dart | 2 +- .../google_sign_in_web/lib/src/load_gapi.dart | 2 +- .../google_sign_in_web/lib/src/utils.dart | 2 +- packages/image_picker/image_picker/AUTHORS | 1 + .../imagepickerexample/EmbeddingV1Activity.java | 2 +- .../EmbeddingV1ActivityTest.java | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../image_picker/example/ios/Runner/AppDelegate.h | 2 +- .../image_picker/example/ios/Runner/AppDelegate.m | 2 +- .../image_picker/example/ios/Runner/main.m | 2 +- .../RunnerUITests/ImagePickerFromGalleryUITests.m | 2 +- .../example/test_driver/test/integration_test.dart | 2 +- .../ios/Tests/ImagePickerPluginTests.m | 2 +- .../image_picker/ios/Tests/ImagePickerTestImages.h | 2 +- .../image_picker/ios/Tests/ImagePickerTestImages.m | 2 +- .../image_picker/ios/Tests/ImageUtilTests.m | 2 +- .../image_picker/ios/Tests/MetaDataUtilTests.m | 2 +- .../image_picker/ios/Tests/PhotoAssetUtilTests.m | 2 +- packages/image_picker/image_picker_for_web/AUTHORS | 1 + packages/image_picker/image_picker_for_web/LICENSE | 2 +- .../lib/image_picker_for_web.dart | 2 +- .../test/image_picker_for_web_test.dart | 2 +- .../image_picker_platform_interface/AUTHORS | 1 + .../image_picker_platform_interface/LICENSE | 2 +- .../lib/image_picker_platform_interface.dart | 2 +- .../method_channel_image_picker.dart | 2 +- .../platform_interface/image_picker_platform.dart | 2 +- .../lib/src/types/camera_device.dart | 2 +- .../lib/src/types/image_source.dart | 2 +- .../lib/src/types/picked_file/base.dart | 2 +- .../lib/src/types/picked_file/html.dart | 2 +- .../lib/src/types/picked_file/io.dart | 2 +- .../lib/src/types/picked_file/lost_data.dart | 2 +- .../lib/src/types/picked_file/picked_file.dart | 2 +- .../lib/src/types/picked_file/unsupported.dart | 2 +- .../lib/src/types/retrieve_type.dart | 2 +- .../lib/src/types/types.dart | 2 +- .../test/picked_file_html_test.dart | 2 +- .../test/picked_file_io_test.dart | 2 +- packages/in_app_purchase/AUTHORS | 1 + packages/in_app_purchase/LICENSE | 2 +- .../inapppurchase/BillingClientFactory.java | 2 +- .../inapppurchase/BillingClientFactoryImpl.java | 2 +- .../plugins/inapppurchase/InAppPurchasePlugin.java | 2 +- .../inapppurchase/MethodCallHandlerImpl.java | 2 +- .../inapppurchase/PluginPurchaseListener.java | 2 +- .../flutter/plugins/inapppurchase/Translator.java | 2 +- .../inapppurchaseexample/EmbeddingV1Activity.java | 2 +- .../EmbeddingV1ActivityTest.java | 2 +- .../inapppurchaseexample/FlutterActivityTest.java | 2 +- .../inapppurchase/InAppPurchasePluginTest.java | 2 +- .../plugins/inapppurchase/TranslatorTest.java | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../example/lib/consumable_store.dart | 2 +- packages/in_app_purchase/example/lib/main.dart | 2 +- .../example/test_driver/test/integration_test.dart | 2 +- .../integration_test/in_app_purchase_test.dart | 2 +- .../ios/Classes/FIAObjectTranslator.h | 2 +- .../ios/Classes/FIAObjectTranslator.m | 2 +- .../ios/Classes/FIAPReceiptManager.h | 2 +- .../ios/Classes/FIAPReceiptManager.m | 2 +- .../ios/Classes/FIAPRequestHandler.h | 2 +- .../ios/Classes/FIAPRequestHandler.m | 2 +- .../ios/Classes/FIAPaymentQueueHandler.h | 2 +- .../ios/Classes/FIAPaymentQueueHandler.m | 2 +- .../ios/Classes/InAppPurchasePlugin.h | 2 +- .../ios/Classes/InAppPurchasePlugin.m | 2 +- .../ios/Tests/InAppPurchasePluginTest.m | 2 +- .../in_app_purchase/ios/Tests/PaymentQueueTest.m | 2 +- .../ios/Tests/ProductRequestHandlerTest.m | 2 +- packages/in_app_purchase/ios/Tests/Stubs.h | 2 +- packages/in_app_purchase/ios/Tests/Stubs.m | 2 +- .../in_app_purchase/ios/Tests/TranslatorTest.m | 2 +- .../lib/billing_client_wrappers.dart | 2 +- packages/in_app_purchase/lib/in_app_purchase.dart | 2 +- .../billing_client_wrapper.dart | 2 +- .../billing_client_wrappers/enum_converters.dart | 2 +- .../billing_client_wrappers/purchase_wrapper.dart | 2 +- .../sku_details_wrapper.dart | 2 +- packages/in_app_purchase/lib/src/channel.dart | 2 +- .../src/in_app_purchase/app_store_connection.dart | 2 +- .../in_app_purchase/google_play_connection.dart | 2 +- .../in_app_purchase_connection.dart | 2 +- .../lib/src/in_app_purchase/product_details.dart | 2 +- .../lib/src/in_app_purchase/purchase_details.dart | 2 +- .../src/store_kit_wrappers/enum_converters.dart | 2 +- .../sk_payment_queue_wrapper.dart | 2 +- .../sk_payment_transaction_wrappers.dart | 2 +- .../src/store_kit_wrappers/sk_product_wrapper.dart | 2 +- .../src/store_kit_wrappers/sk_receipt_manager.dart | 2 +- .../src/store_kit_wrappers/sk_request_maker.dart | 2 +- .../in_app_purchase/lib/store_kit_wrappers.dart | 2 +- .../billing_client_wrapper_test.dart | 2 +- .../purchase_wrapper_test.dart | 2 +- .../sku_details_wrapper_test.dart | 2 +- .../app_store_connection_test.dart | 2 +- .../google_play_connection_test.dart | 2 +- .../sk_methodchannel_apis_test.dart | 2 +- .../test/store_kit_wrappers/sk_product_test.dart | 2 +- .../store_kit_wrappers/sk_test_stub_objects.dart | 2 +- .../test/stub_in_app_purchase_platform.dart | 2 +- packages/integration_test/AUTHORS | 1 + packages/integration_test/LICENSE | 2 +- .../integration_test/FlutterTestRunner.java | 2 +- .../integration_test/IntegrationTestPlugin.java | 2 +- .../example/e2e_example/EmbedderV1Activity.java | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- .../integration_test/example/ios/Runner/main.m | 2 +- .../example/test_driver/failure.dart | 2 +- .../ios/Classes/IntegrationTestIosTest.h | 2 +- .../ios/Classes/IntegrationTestIosTest.m | 2 +- .../ios/Classes/IntegrationTestPlugin.h | 2 +- .../ios/Classes/IntegrationTestPlugin.m | 2 +- packages/integration_test/lib/_callback_io.dart | 2 +- packages/integration_test/lib/_callback_web.dart | 2 +- packages/integration_test/lib/_extension_io.dart | 2 +- packages/integration_test/lib/_extension_web.dart | 2 +- packages/integration_test/lib/common.dart | 2 +- .../integration_test/lib/integration_test.dart | 2 +- .../lib/integration_test_driver_extended.dart | 2 +- .../integration_test/test/binding_fail_test.dart | 2 +- packages/integration_test/test/binding_test.dart | 2 +- .../test/data/fail_test_script.dart | 2 +- .../test/data/pass_test_script.dart | 2 +- .../test/data/pass_then_fail_test_script.dart | 2 +- .../test/response_serialization_test.dart | 2 +- packages/ios_platform_images/AUTHORS | 1 + packages/ios_platform_images/LICENSE | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../ios/Classes/IosPlatformImagesPlugin.h | 2 +- .../ios/Classes/IosPlatformImagesPlugin.m | 2 +- .../lib/ios_platform_images.dart | 2 +- .../test/ios_platform_images_test.dart | 2 +- packages/local_auth/AUTHORS | 1 + packages/local_auth/LICENSE | 2 +- .../plugins/localauth/AuthenticationHelper.java | 2 +- .../flutter/plugins/localauth/LocalAuthPlugin.java | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../local_auth/example/ios/Runner/AppDelegate.h | 2 +- .../local_auth/example/ios/Runner/AppDelegate.m | 2 +- packages/local_auth/example/lib/main.dart | 2 +- .../integration_test/local_auth_test.dart | 2 +- .../local_auth/ios/Classes/FLTLocalAuthPlugin.h | 2 +- .../local_auth/ios/Classes/FLTLocalAuthPlugin.m | 2 +- packages/local_auth/lib/auth_strings.dart | 2 +- packages/local_auth/lib/error_codes.dart | 2 +- packages/local_auth/lib/local_auth.dart | 2 +- packages/package_info/AUTHORS | 1 + packages/package_info/LICENSE | 2 +- .../plugins/packageinfo/PackageInfoPlugin.java | 2 +- .../darwin/Classes/FLTPackageInfoPlugin.m | 2 +- .../packageinfoexample/EmbedderV1ActivityTest.java | 2 +- .../packageinfoexample/MainActivityTest.java | 2 +- .../packageinfoexample/EmbedderV1Activity.java | 2 +- .../integration_test/package_info_test.dart | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../package_info/example/ios/Runner/AppDelegate.h | 2 +- .../package_info/example/ios/Runner/AppDelegate.m | 2 +- packages/package_info/example/ios/Runner/main.m | 2 +- packages/package_info/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../ios/Classes/FLTPackageInfoPlugin.h | 2 +- packages/package_info/lib/package_info.dart | 2 +- .../macos/Classes/FLTPackageInfoPlugin.h | 2 +- packages/path_provider/path_provider/AUTHORS | 1 + .../integration_test/path_provider_test.dart | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../path_provider/example/ios/Runner/AppDelegate.h | 2 +- .../path_provider/example/ios/Runner/AppDelegate.m | 2 +- .../path_provider/example/ios/Runner/main.m | 2 +- .../path_provider/example/linux/my_application.h | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../example/windows/runner/flutter_window.cpp | 2 +- packages/path_provider/path_provider_linux/AUTHORS | 1 + packages/path_provider/path_provider_linux/LICENSE | 2 +- .../integration_test/path_provider_test.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../lib/path_provider_linux.dart | 2 +- .../test/path_provider_linux_test.dart | 2 +- packages/path_provider/path_provider_macos/AUTHORS | 1 + packages/path_provider/path_provider_macos/LICENSE | 2 +- .../integration_test/path_provider_test.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../macos/Classes/PathProviderPlugin.swift | 2 +- .../path_provider_platform_interface/AUTHORS | 1 + .../path_provider_platform_interface/LICENSE | 2 +- .../lib/path_provider_platform_interface.dart | 2 +- .../lib/src/enums.dart | 2 +- .../lib/src/method_channel_path_provider.dart | 2 +- .../test/method_channel_path_provider_test.dart | 2 +- .../path_provider/path_provider_windows/AUTHORS | 1 + .../path_provider/path_provider_windows/LICENSE | 2 +- .../integration_test/path_provider_test.dart | 2 +- .../path_provider_windows/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../lib/path_provider_windows.dart | 2 +- .../path_provider_windows/lib/src/folders.dart | 2 +- .../lib/src/folders_stub.dart | 2 +- .../lib/src/path_provider_windows_real.dart | 2 +- .../lib/src/path_provider_windows_stub.dart | 2 +- .../test/path_provider_windows_test.dart | 2 +- packages/plugin_platform_interface/AUTHORS | 1 + packages/plugin_platform_interface/LICENSE | 2 +- .../lib/plugin_platform_interface.dart | 2 +- .../test/plugin_platform_interface_test.dart | 2 +- packages/quick_actions/AUTHORS | 1 + packages/quick_actions/LICENSE | 2 +- .../quickactions/MethodCallHandlerImpl.java | 2 +- .../plugins/quickactions/QuickActionsPlugin.java | 2 +- .../quickactionsexample/EmbeddingV1Activity.java | 2 +- .../EmbeddingV1ActivityTest.java | 2 +- .../quickactionsexample/FlutterActivityTest.java | 2 +- .../integration_test/quick_actions_test.dart | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../quick_actions/example/ios/Runner/AppDelegate.h | 2 +- .../quick_actions/example/ios/Runner/AppDelegate.m | 2 +- packages/quick_actions/example/ios/Runner/main.m | 2 +- .../example/ios/RunnerUITests/RunnerUITests.m | 2 +- packages/quick_actions/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../ios/Classes/FLTQuickActionsPlugin.h | 2 +- .../ios/Classes/FLTQuickActionsPlugin.m | 2 +- packages/quick_actions/lib/quick_actions.dart | 2 +- .../quick_actions/test/quick_actions_test.dart | 2 +- packages/sensors/AUTHORS | 1 + packages/sensors/LICENSE | 2 +- .../io/flutter/plugins/sensors/SensorsPlugin.java | 2 +- .../flutter/plugins/sensors/StreamHandlerImpl.java | 2 +- .../sensorsexample/EmbeddingV1Activity.java | 2 +- .../sensorsexample/FlutterActivityTest.java | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- packages/sensors/example/lib/main.dart | 2 +- packages/sensors/example/lib/snake.dart | 2 +- .../example/test_driver/test/integration_test.dart | 2 +- .../sensors/integration_test/sensors_test.dart | 2 +- packages/sensors/ios/Classes/FLTSensorsPlugin.h | 2 +- packages/sensors/ios/Classes/FLTSensorsPlugin.m | 2 +- packages/sensors/lib/sensors.dart | 2 +- packages/sensors/test/sensors_test.dart | 2 +- packages/share/AUTHORS | 1 + .../plugins/shareexample/EmbeddingV1Activity.java | 2 +- .../plugins/shareexample/FlutterActivityTest.java | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- packages/share/example/ios/Runner/AppDelegate.h | 2 +- packages/share/example/ios/Runner/AppDelegate.m | 2 +- packages/share/example/ios/Runner/main.m | 2 +- .../ios/RunnerUITests/FLTShareExampleUITests.m | 2 +- .../example/test_driver/test/integration_test.dart | 2 +- packages/share/integration_test/share_test.dart | 2 +- .../shared_preferences/shared_preferences/AUTHORS | 1 + .../shared_preferences/shared_preferences/LICENSE | 2 +- .../sharedpreferences/MethodCallHandlerImpl.java | 2 +- .../sharedpreferences/SharedPreferencesPlugin.java | 2 +- .../integration_test/shared_preferences_test.dart | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- .../example/ios/Runner/Runner-Bridging-Header.h | 2 +- .../shared_preferences/example/ios/Runner/main.m | 2 +- .../shared_preferences/example/lib/main.dart | 2 +- .../example/linux/my_application.h | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../example/windows/runner/flutter_window.cpp | 2 +- .../example/windows/runner/flutter_window.h | 2 +- .../example/windows/runner/main.cpp | 2 +- .../example/windows/runner/run_loop.cpp | 2 +- .../example/windows/runner/run_loop.h | 2 +- .../example/windows/runner/utils.cpp | 2 +- .../example/windows/runner/utils.h | 2 +- .../example/windows/runner/win32_window.cpp | 2 +- .../example/windows/runner/win32_window.h | 2 +- .../ios/Classes/FLTSharedPreferencesPlugin.h | 2 +- .../ios/Classes/FLTSharedPreferencesPlugin.m | 2 +- .../shared_preferences/lib/shared_preferences.dart | 2 +- .../test/shared_preferences_test.dart | 2 +- .../shared_preferences_linux/AUTHORS | 1 + .../shared_preferences_linux/LICENSE | 2 +- .../integration_test/shared_preferences_test.dart | 2 +- .../shared_preferences_linux/example/lib/main.dart | 2 +- .../example/linux/my_application.h | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../lib/shared_preferences_linux.dart | 2 +- .../test/shared_preferences_linux_test.dart | 2 +- .../shared_preferences_macos/AUTHORS | 1 + .../integration_test/shared_preferences_test.dart | 2 +- .../shared_preferences_macos/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../macos/Classes/SharedPreferencesPlugin.swift | 2 +- .../shared_preferences_platform_interface/AUTHORS | 1 + .../shared_preferences_platform_interface/LICENSE | 2 +- .../lib/method_channel_shared_preferences.dart | 2 +- .../lib/shared_preferences_platform_interface.dart | 2 +- .../method_channel_shared_preferences_test.dart | 2 +- ...shared_preferences_platform_interface_test.dart | 2 +- .../shared_preferences_web/LICENSE | 2 +- .../lib/shared_preferences_web.dart | 2 +- .../test/shared_preferences_web_test.dart | 2 +- .../shared_preferences_windows/AUTHORS | 1 + .../shared_preferences_windows/LICENSE | 2 +- .../shared_preferences_windows/example/LICENSE | 2 +- .../integration_test/shared_preferences_test.dart | 2 +- .../example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../example/windows/runner/flutter_window.cpp | 2 +- .../example/windows/runner/flutter_window.h | 2 +- .../example/windows/runner/main.cpp | 2 +- .../example/windows/runner/run_loop.cpp | 2 +- .../example/windows/runner/run_loop.h | 2 +- .../example/windows/runner/utils.cpp | 2 +- .../example/windows/runner/utils.h | 2 +- .../example/windows/runner/win32_window.cpp | 2 +- .../example/windows/runner/win32_window.h | 2 +- .../lib/shared_preferences_windows.dart | 2 +- .../test/shared_preferences_windows_test.dart | 2 +- packages/url_launcher/url_launcher/AUTHORS | 1 + packages/url_launcher/url_launcher/LICENSE | 2 +- .../plugins/urllauncher/MethodCallHandlerImpl.java | 2 +- .../flutter/plugins/urllauncher/UrlLauncher.java | 2 +- .../plugins/urllauncher/UrlLauncherPlugin.java | 2 +- .../plugins/urllauncher/WebViewActivity.java | 2 +- .../urllauncher/MethodCallHandlerImplTest.java | 2 +- .../urllauncherexample/EmbeddingV1Activity.java | 2 +- .../integration_test/url_launcher_test.dart | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../url_launcher/example/ios/Runner/AppDelegate.h | 2 +- .../url_launcher/example/ios/Runner/AppDelegate.m | 2 +- .../url_launcher/example/ios/Runner/main.m | 2 +- .../url_launcher/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../ios/Classes/FLTURLLauncherPlugin.h | 2 +- .../ios/Classes/FLTURLLauncherPlugin.m | 2 +- packages/url_launcher/url_launcher/lib/link.dart | 2 +- .../url_launcher/url_launcher/lib/src/link.dart | 2 +- .../url_launcher/lib/url_launcher.dart | 2 +- .../url_launcher/url_launcher/test/link_test.dart | 2 +- .../test/mock_url_launcher_platform.dart | 2 +- .../url_launcher/test/url_launcher_test.dart | 2 +- packages/url_launcher/url_launcher_linux/AUTHORS | 1 + packages/url_launcher/url_launcher_linux/LICENSE | 2 +- .../integration_test/url_launcher_test.dart | 2 +- .../url_launcher_linux/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../url_launcher_linux/url_launcher_plugin.h | 2 +- .../linux/url_launcher_plugin.cc | 2 +- packages/url_launcher/url_launcher_macos/AUTHORS | 1 + packages/url_launcher/url_launcher_macos/LICENSE | 2 +- .../integration_test/url_launcher_test.dart | 2 +- .../url_launcher_macos/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../macos/Classes/UrlLauncherPlugin.swift | 2 +- .../url_launcher_platform_interface/AUTHORS | 1 + .../url_launcher_platform_interface/LICENSE | 2 +- .../url_launcher_platform_interface/lib/link.dart | 2 +- .../lib/method_channel_url_launcher.dart | 2 +- .../lib/url_launcher_platform_interface.dart | 2 +- .../test/link_test.dart | 2 +- .../test/method_channel_url_launcher_test.dart | 2 +- packages/url_launcher/url_launcher_web/AUTHORS | 1 + packages/url_launcher/url_launcher_web/LICENSE | 2 +- .../example/integration_test/link_widget_test.dart | 2 +- .../integration_test/url_launcher_web_test.dart | 2 +- .../test_driver/integration_test_driver.dart | 2 +- .../url_launcher_web/lib/src/link.dart | 2 +- .../url_launcher_web/lib/src/shims/dart_ui.dart | 2 +- .../lib/src/shims/dart_ui_fake.dart | 2 +- .../lib/src/shims/dart_ui_real.dart | 2 +- .../url_launcher_web/lib/url_launcher_web.dart | 2 +- .../test/tests_exist_elsewhere_test.dart | 2 +- packages/url_launcher/url_launcher_windows/AUTHORS | 1 + packages/url_launcher/url_launcher_windows/LICENSE | 2 +- .../integration_test/url_launcher_test.dart | 2 +- .../url_launcher_windows/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../url_launcher_windows/url_launcher_plugin.h | 2 +- .../windows/url_launcher_plugin.cpp | 2 +- packages/video_player/video_player/AUTHORS | 1 + packages/video_player/video_player/LICENSE | 2 +- .../videoplayer/CustomSSLSocketFactory.java | 2 +- .../io/flutter/plugins/videoplayer/Messages.java | 2 +- .../plugins/videoplayer/QueuingEventSink.java | 2 +- .../flutter/plugins/videoplayer/VideoPlayer.java | 2 +- .../plugins/videoplayer/VideoPlayerOptions.java | 2 +- .../plugins/videoplayer/VideoPlayerPlugin.java | 2 +- .../videoplayerexample/EmbeddingV1Activity.java | 2 +- .../integration_test/video_player_test.dart | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../video_player/example/ios/Runner/AppDelegate.h | 2 +- .../video_player/example/ios/Runner/AppDelegate.m | 2 +- .../video_player/example/ios/Runner/main.m | 2 +- .../video_player/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../example/test_driver/video_player.dart | 2 +- .../example/test_driver/video_player_test.dart | 2 +- .../ios/Classes/FLTVideoPlayerPlugin.h | 2 +- .../ios/Classes/FLTVideoPlayerPlugin.m | 2 +- .../video_player/ios/Classes/messages.h | 2 +- .../video_player/ios/Classes/messages.m | 2 +- .../video_player/lib/src/closed_caption_file.dart | 2 +- .../video_player/video_player/lib/src/sub_rip.dart | 2 +- .../video_player/lib/video_player.dart | 2 +- .../video_player/pigeons/messages.dart | 2 +- .../test/closed_caption_file_test.dart | 2 +- .../video_player/test/sub_rip_file_test.dart | 2 +- .../test/video_player_initialization_test.dart | 2 +- .../video_player/test/video_player_test.dart | 2 +- .../video_player_platform_interface/AUTHORS | 1 + .../video_player_platform_interface/LICENSE | 2 +- .../lib/messages.dart | 2 +- .../lib/method_channel_video_player.dart | 2 +- .../video_player_platform_interface/lib/test.dart | 2 +- .../lib/video_player_platform_interface.dart | 2 +- .../test/method_channel_video_player_test.dart | 2 +- packages/video_player/video_player_web/AUTHORS | 1 + packages/video_player/video_player_web/LICENSE | 2 +- .../video_player_web/lib/src/shims/dart_ui.dart | 2 +- .../lib/src/shims/dart_ui_fake.dart | 2 +- .../lib/src/shims/dart_ui_real.dart | 2 +- .../video_player_web/lib/video_player_web.dart | 2 +- .../test/video_player_web_test.dart | 2 +- packages/webview_flutter/AUTHORS | 1 + packages/webview_flutter/LICENSE | 2 +- .../webviewflutter/DisplayListenerProxy.java | 2 +- .../webviewflutter/FlutterCookieManager.java | 2 +- .../plugins/webviewflutter/FlutterWebView.java | 2 +- .../webviewflutter/FlutterWebViewClient.java | 2 +- .../plugins/webviewflutter/InputAwareWebView.java | 2 +- .../plugins/webviewflutter/JavaScriptChannel.java | 2 +- .../ThreadedInputConnectionProxyAdapterView.java | 2 +- .../plugins/webviewflutter/WebViewFactory.java | 2 +- .../webviewflutter/WebViewFlutterPlugin.java | 2 +- .../webviewflutterexample/EmbeddingV1Activity.java | 2 +- .../integration_test/webview_flutter_test.dart | 2 +- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- packages/webview_flutter/example/ios/Runner/main.m | 2 +- packages/webview_flutter/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../webview_flutter/ios/Classes/FLTCookieManager.h | 2 +- .../webview_flutter/ios/Classes/FLTCookieManager.m | 2 +- .../ios/Classes/FLTWKNavigationDelegate.h | 2 +- .../ios/Classes/FLTWKNavigationDelegate.m | 2 +- .../ios/Classes/FLTWKProgressionDelegate.h | 2 +- .../ios/Classes/FLTWKProgressionDelegate.m | 2 +- .../ios/Classes/FLTWebViewFlutterPlugin.h | 2 +- .../ios/Classes/FLTWebViewFlutterPlugin.m | 2 +- .../webview_flutter/ios/Classes/FlutterWebView.h | 2 +- .../webview_flutter/ios/Classes/FlutterWebView.m | 2 +- .../ios/Classes/JavaScriptChannelHandler.h | 2 +- .../ios/Classes/JavaScriptChannelHandler.m | 2 +- .../ios/Tests/FLTWKNavigationDelegateTests.m | 2 +- .../webview_flutter/ios/Tests/FLTWebViewTests.m | 2 +- .../webview_flutter/lib/platform_interface.dart | 2 +- .../webview_flutter/lib/src/webview_android.dart | 2 +- .../webview_flutter/lib/src/webview_cupertino.dart | 2 +- .../lib/src/webview_method_channel.dart | 2 +- packages/webview_flutter/lib/webview_flutter.dart | 2 +- .../webview_flutter/test/webview_flutter_test.dart | 2 +- .../wifi_info_flutter/wifi_info_flutter/AUTHORS | 1 + .../wifi_info_flutter/wifi_info_flutter/LICENSE | 2 +- .../plugins/wifi_info_flutter/WifiInfoFlutter.java | 2 +- .../WifiInfoFlutterMethodChannelHandler.java | 2 +- .../wifi_info_flutter/WifiInfoFlutterPlugin.java | 2 +- .../wifi_info_flutter/example/lib/main.dart | 2 +- .../integration_test/wifi_info_test.dart | 2 +- .../example/test_driver/test/integration_test.dart | 2 +- .../integration_test/wifi_info_test.dart | 2 +- .../ios/Classes/FLTWifiInfoLocationHandler.h | 2 +- .../ios/Classes/FLTWifiInfoLocationHandler.m | 2 +- .../ios/Classes/WifiInfoFlutterPlugin.h | 2 +- .../ios/Classes/WifiInfoFlutterPlugin.m | 2 +- .../wifi_info_flutter/lib/wifi_info_flutter.dart | 2 +- .../test/wifi_info_flutter_test.dart | 2 +- .../wifi_info_flutter_platform_interface/AUTHORS | 1 + .../wifi_info_flutter_platform_interface/LICENSE | 2 +- .../lib/src/enums.dart | 2 +- .../lib/src/method_channel_wifi_info_flutter.dart | 2 +- .../lib/wifi_info_flutter_platform_interface.dart | 2 +- .../method_channel_wifi_info_flutter_test.dart | 2 +- script/build_all_plugins_app.sh | 2 +- script/check_publish.sh | 2 +- script/common.sh | 2 +- script/incremental_build.sh | 2 +- script/tool/lib/src/analyze_command.dart | 2 +- script/tool/lib/src/build_examples_command.dart | 2 +- script/tool/lib/src/common.dart | 2 +- .../lib/src/create_all_plugins_app_command.dart | 2 +- script/tool/lib/src/drive_examples_command.dart | 2 +- script/tool/lib/src/firebase_test_lab_command.dart | 2 +- script/tool/lib/src/format_command.dart | 2 +- script/tool/lib/src/java_test_command.dart | 2 +- script/tool/lib/src/license_check_command.dart | 14 ++++---------- script/tool/lib/src/lint_podspecs_command.dart | 2 +- script/tool/lib/src/list_command.dart | 2 +- script/tool/lib/src/main.dart | 2 +- script/tool/lib/src/publish_check_command.dart | 2 +- script/tool/lib/src/publish_plugin_command.dart | 2 +- script/tool/lib/src/test_command.dart | 2 +- script/tool/lib/src/version_check_command.dart | 2 +- script/tool/lib/src/xctest_command.dart | 2 +- script/tool/test/analyze_command_test.dart | 2 +- script/tool/test/build_examples_command_test.dart | 2 +- script/tool/test/common_test.dart | 2 +- script/tool/test/drive_examples_command_test.dart | 2 +- script/tool/test/firebase_test_lab_test.dart | 2 +- script/tool/test/license_check_command_test.dart | 4 ++-- script/tool/test/lint_podspecs_command_test.dart | 2 +- script/tool/test/list_command_test.dart | 2 +- script/tool/test/mocks.dart | 2 +- script/tool/test/publish_plugin_command_test.dart | 2 +- script/tool/test/test_command_test.dart | 2 +- script/tool/test/util.dart | 2 +- script/tool/test/version_check_test.dart | 4 ++-- script/tool/test/xctest_command_test.dart | 2 +- 956 files changed, 962 insertions(+), 913 deletions(-) diff --git a/AUTHORS b/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/LICENSE b/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/android_alarm_manager/AUTHORS b/packages/android_alarm_manager/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/android_alarm_manager/AUTHORS +++ b/packages/android_alarm_manager/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/android_alarm_manager/LICENSE b/packages/android_alarm_manager/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/android_alarm_manager/LICENSE +++ b/packages/android_alarm_manager/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmBroadcastReceiver.java b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmBroadcastReceiver.java index a8968a2095d9..0b8a1455f9ae 100644 --- a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmBroadcastReceiver.java +++ b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmBroadcastReceiver.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmService.java b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmService.java index 3287789f6c3d..5311911a3d7d 100644 --- a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmService.java +++ b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmService.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AndroidAlarmManagerPlugin.java b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AndroidAlarmManagerPlugin.java index 557913a626d5..1587bca71a80 100644 --- a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AndroidAlarmManagerPlugin.java +++ b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AndroidAlarmManagerPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/FlutterBackgroundExecutor.java b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/FlutterBackgroundExecutor.java index 86010ff3f089..fc438753f3cc 100644 --- a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/FlutterBackgroundExecutor.java +++ b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/FlutterBackgroundExecutor.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/PluginRegistrantException.java b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/PluginRegistrantException.java index debcd7ee7529..f38c2b8b0461 100644 --- a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/PluginRegistrantException.java +++ b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/PluginRegistrantException.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/RebootBroadcastReceiver.java b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/RebootBroadcastReceiver.java index b920afa1c1b7..5f5c5cacd86f 100644 --- a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/RebootBroadcastReceiver.java +++ b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/RebootBroadcastReceiver.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/BackgroundExecutionTest.java b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/BackgroundExecutionTest.java index ce34b25ec505..457599b0da91 100644 --- a/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/BackgroundExecutionTest.java +++ b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/BackgroundExecutionTest.java @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/DriverExtensionActivity.java b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/DriverExtensionActivity.java index 4f521a387bac..57c3f4122578 100644 --- a/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/DriverExtensionActivity.java +++ b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/DriverExtensionActivity.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/MainActivityTest.java b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/MainActivityTest.java index 373e770697d5..82503c9d54c5 100644 --- a/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/MainActivityTest.java +++ b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/MainActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/EmbeddingV1Activity.java b/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/EmbeddingV1Activity.java index 26a542be2598..8e77dbd1b46b 100644 --- a/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/EmbeddingV1Activity.java +++ b/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart b/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart index 68e35d581d89..67dcb520a3a2 100644 --- a/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart +++ b/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/android_alarm_manager/example/lib/main.dart b/packages/android_alarm_manager/example/lib/main.dart index dc3779c8cbe2..ff164a6275b3 100644 --- a/packages/android_alarm_manager/example/lib/main.dart +++ b/packages/android_alarm_manager/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/android_alarm_manager/example/test_driver/integration_test.dart b/packages/android_alarm_manager/example/test_driver/integration_test.dart index a2fa9e1147e1..88461d1c79a1 100644 --- a/packages/android_alarm_manager/example/test_driver/integration_test.dart +++ b/packages/android_alarm_manager/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/android_alarm_manager/lib/android_alarm_manager.dart b/packages/android_alarm_manager/lib/android_alarm_manager.dart index 218959bc4bcc..e074dfb3af36 100644 --- a/packages/android_alarm_manager/lib/android_alarm_manager.dart +++ b/packages/android_alarm_manager/lib/android_alarm_manager.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/android_alarm_manager/test/android_alarm_manager_test.dart b/packages/android_alarm_manager/test/android_alarm_manager_test.dart index 1f9d2856838e..4b340f563fd4 100644 --- a/packages/android_alarm_manager/test/android_alarm_manager_test.dart +++ b/packages/android_alarm_manager/test/android_alarm_manager_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/android_intent/AUTHORS b/packages/android_intent/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/android_intent/AUTHORS +++ b/packages/android_intent/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/android_intent/LICENSE b/packages/android_intent/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/android_intent/LICENSE +++ b/packages/android_intent/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java index 04df4d9f7c01..ff73b6de5485 100644 --- a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java +++ b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/IntentSender.java b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/IntentSender.java index 0d2ff0c829e5..1c9aa9ac6b02 100644 --- a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/IntentSender.java +++ b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/IntentSender.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/MethodCallHandlerImpl.java b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/MethodCallHandlerImpl.java index 2cce443fd182..9bdcbec08465 100644 --- a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/MethodCallHandlerImpl.java +++ b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/MethodCallHandlerImpl.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java b/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java index e36f4aab804d..bf3fdf976d9d 100644 --- a/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java +++ b/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/android_intent/example/android/app/src/main/java/io/flutter/plugins/androidintentexample/EmbeddingV1Activity.java b/packages/android_intent/example/android/app/src/main/java/io/flutter/plugins/androidintentexample/EmbeddingV1Activity.java index f64ae47a7656..87e822274f85 100644 --- a/packages/android_intent/example/android/app/src/main/java/io/flutter/plugins/androidintentexample/EmbeddingV1Activity.java +++ b/packages/android_intent/example/android/app/src/main/java/io/flutter/plugins/androidintentexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/android_intent/example/integration_test/android_intent_test.dart b/packages/android_intent/example/integration_test/android_intent_test.dart index e11a5e4e4898..28de6b785c70 100644 --- a/packages/android_intent/example/integration_test/android_intent_test.dart +++ b/packages/android_intent/example/integration_test/android_intent_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/android_intent/example/lib/main.dart b/packages/android_intent/example/lib/main.dart index 4fd2440285f3..99413c1d5701 100644 --- a/packages/android_intent/example/lib/main.dart +++ b/packages/android_intent/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/android_intent/example/test_driver/integration_test.dart b/packages/android_intent/example/test_driver/integration_test.dart index 0378ec31ee3c..993729f6ac3d 100644 --- a/packages/android_intent/example/test_driver/integration_test.dart +++ b/packages/android_intent/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/android_intent/lib/android_intent.dart b/packages/android_intent/lib/android_intent.dart index 0ab2d7bee420..698a584ce7ea 100644 --- a/packages/android_intent/lib/android_intent.dart +++ b/packages/android_intent/lib/android_intent.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/android_intent/lib/flag.dart b/packages/android_intent/lib/flag.dart index 990eed9db8fc..147c6a1d932c 100644 --- a/packages/android_intent/lib/flag.dart +++ b/packages/android_intent/lib/flag.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/battery/battery/AUTHORS b/packages/battery/battery/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/battery/battery/AUTHORS +++ b/packages/battery/battery/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/battery/battery/LICENSE b/packages/battery/battery/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/battery/battery/LICENSE +++ b/packages/battery/battery/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/battery/battery/android/src/main/java/io/flutter/plugins/battery/BatteryPlugin.java b/packages/battery/battery/android/src/main/java/io/flutter/plugins/battery/BatteryPlugin.java index f16d219291d1..92405a9900d3 100644 --- a/packages/battery/battery/android/src/main/java/io/flutter/plugins/battery/BatteryPlugin.java +++ b/packages/battery/battery/android/src/main/java/io/flutter/plugins/battery/BatteryPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/battery/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/EmbedderV1ActivityTest.java b/packages/battery/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/EmbedderV1ActivityTest.java index 1bd860eb147c..3c4eabeaf23f 100644 --- a/packages/battery/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/EmbedderV1ActivityTest.java +++ b/packages/battery/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/EmbedderV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/battery/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/FlutterActivityTest.java b/packages/battery/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/FlutterActivityTest.java index 636c716d7a91..2fec9365b756 100644 --- a/packages/battery/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/FlutterActivityTest.java +++ b/packages/battery/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/FlutterActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/battery/battery/example/android/app/src/main/java/io/flutter/plugins/batteryexample/EmbedderV1Activity.java b/packages/battery/battery/example/android/app/src/main/java/io/flutter/plugins/batteryexample/EmbedderV1Activity.java index 5fa885cdd9d8..6877a5013737 100644 --- a/packages/battery/battery/example/android/app/src/main/java/io/flutter/plugins/batteryexample/EmbedderV1Activity.java +++ b/packages/battery/battery/example/android/app/src/main/java/io/flutter/plugins/batteryexample/EmbedderV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/battery/battery/example/ios/Runner.xcodeproj/project.pbxproj b/packages/battery/battery/example/ios/Runner.xcodeproj/project.pbxproj index aa42a8509346..3abde6d9a3d0 100644 --- a/packages/battery/battery/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/battery/battery/example/ios/Runner.xcodeproj/project.pbxproj @@ -177,7 +177,7 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; diff --git a/packages/battery/battery/example/ios/Runner/AppDelegate.h b/packages/battery/battery/example/ios/Runner/AppDelegate.h index d9e18e990f2e..31fc381e7066 100644 --- a/packages/battery/battery/example/ios/Runner/AppDelegate.h +++ b/packages/battery/battery/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/battery/battery/example/ios/Runner/AppDelegate.m b/packages/battery/battery/example/ios/Runner/AppDelegate.m index a4b51c88eb60..abfe2106b092 100644 --- a/packages/battery/battery/example/ios/Runner/AppDelegate.m +++ b/packages/battery/battery/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/battery/battery/example/ios/Runner/main.m b/packages/battery/battery/example/ios/Runner/main.m index bec320c0bee0..f451b14cb751 100644 --- a/packages/battery/battery/example/ios/Runner/main.m +++ b/packages/battery/battery/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/battery/battery/example/lib/main.dart b/packages/battery/battery/example/lib/main.dart index 8482655771f2..8c0edec04f74 100644 --- a/packages/battery/battery/example/lib/main.dart +++ b/packages/battery/battery/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/battery/battery/integration_test/battery_test.dart b/packages/battery/battery/integration_test/battery_test.dart index 1732380919b2..4912f3f81fd3 100644 --- a/packages/battery/battery/integration_test/battery_test.dart +++ b/packages/battery/battery/integration_test/battery_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/battery/battery/ios/Classes/FLTBatteryPlugin.h b/packages/battery/battery/ios/Classes/FLTBatteryPlugin.h index 9743ca501208..b555de48ebf4 100644 --- a/packages/battery/battery/ios/Classes/FLTBatteryPlugin.h +++ b/packages/battery/battery/ios/Classes/FLTBatteryPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/battery/battery/ios/Classes/FLTBatteryPlugin.m b/packages/battery/battery/ios/Classes/FLTBatteryPlugin.m index f1e82a64eb1b..151dbda1ce32 100644 --- a/packages/battery/battery/ios/Classes/FLTBatteryPlugin.m +++ b/packages/battery/battery/ios/Classes/FLTBatteryPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/battery/battery/lib/battery.dart b/packages/battery/battery/lib/battery.dart index e3943e49599a..8781979a7eac 100644 --- a/packages/battery/battery/lib/battery.dart +++ b/packages/battery/battery/lib/battery.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/battery/battery/test/battery_test.dart b/packages/battery/battery/test/battery_test.dart index ff1bf1596250..5db0798d906e 100644 --- a/packages/battery/battery/test/battery_test.dart +++ b/packages/battery/battery/test/battery_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/battery/battery_platform_interface/AUTHORS b/packages/battery/battery_platform_interface/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/battery/battery_platform_interface/AUTHORS +++ b/packages/battery/battery_platform_interface/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/battery/battery_platform_interface/LICENSE b/packages/battery/battery_platform_interface/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/battery/battery_platform_interface/LICENSE +++ b/packages/battery/battery_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/battery/battery_platform_interface/lib/battery_platform_interface.dart b/packages/battery/battery_platform_interface/lib/battery_platform_interface.dart index f803c7aaa8fd..c839b02bc18d 100644 --- a/packages/battery/battery_platform_interface/lib/battery_platform_interface.dart +++ b/packages/battery/battery_platform_interface/lib/battery_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/battery/battery_platform_interface/lib/enums/battery_state.dart b/packages/battery/battery_platform_interface/lib/enums/battery_state.dart index 2ceb35128b4b..b8458224df4a 100644 --- a/packages/battery/battery_platform_interface/lib/enums/battery_state.dart +++ b/packages/battery/battery_platform_interface/lib/enums/battery_state.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/battery/battery_platform_interface/lib/method_channel/method_channel_battery.dart b/packages/battery/battery_platform_interface/lib/method_channel/method_channel_battery.dart index dbc561bf0e64..8f38b6616702 100644 --- a/packages/battery/battery_platform_interface/lib/method_channel/method_channel_battery.dart +++ b/packages/battery/battery_platform_interface/lib/method_channel/method_channel_battery.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/battery/battery_platform_interface/test/method_channel_battery_test.dart b/packages/battery/battery_platform_interface/test/method_channel_battery_test.dart index 2b17cf97e711..0e36e0a1fbba 100644 --- a/packages/battery/battery_platform_interface/test/method_channel_battery_test.dart +++ b/packages/battery/battery_platform_interface/test/method_channel_battery_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/camera/camera/AUTHORS b/packages/camera/camera/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/camera/camera/AUTHORS +++ b/packages/camera/camera/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/camera/camera/LICENSE b/packages/camera/camera/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/camera/camera/LICENSE +++ b/packages/camera/camera/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 5169a3babb74..4faedf3aa0c2 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPermissions.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPermissions.java index 3529e69a2b0b..4442fce9b2fd 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPermissions.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPermissions.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java index 93183bb7c0a7..849ca3ccc489 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegions.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegions.java index 04412a56631f..67030ebe9667 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegions.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegions.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java index 03993a3b51f9..4ad260f7347f 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraZoom.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraZoom.java index 5eed9f4734b7..ff3f04ade0fd 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraZoom.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraZoom.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java index 3892452892d9..8e7be0937000 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java index b2a504b629d6..af1a0c2082c5 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java index aa7483f55679..c1afd64febec 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java index 396f782a2a08..4a6fafff50c8 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/media/MediaRecorderBuilder.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/media/MediaRecorderBuilder.java index 4c3fb3add230..9873a3c12972 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/media/MediaRecorderBuilder.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/media/MediaRecorderBuilder.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ExposureMode.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ExposureMode.java index 595206fa2216..fd2475649b89 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ExposureMode.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ExposureMode.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java index c4f0998c418a..3880874779be 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FocusMode.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FocusMode.java index b0dba047f7eb..d4e8348ab8ed 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FocusMode.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FocusMode.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ResolutionPreset.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ResolutionPreset.java index 1508dcefb293..1c2ce8b0c8aa 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ResolutionPreset.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ResolutionPreset.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraPermissionsTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraPermissionsTest.java index 2b19b5dbb0d6..930b5ad08ab3 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraPermissionsTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraPermissionsTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionsTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionsTest.java index 99745e56a857..d0074d295ca2 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionsTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionsTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraUtilsTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraUtilsTest.java index 8026b6349aa1..aa89669459bb 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraUtilsTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraUtilsTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraZoomTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraZoomTest.java index 8f05da71b5c5..445174b3b357 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraZoomTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraZoomTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java index e835b08f441a..ff77b32cd1d0 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java index 3252b3e111c4..8542fc615c35 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/media/MediaRecorderBuilderTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/media/MediaRecorderBuilderTest.java index 823975803994..04eb3e031cca 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/media/MediaRecorderBuilderTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/media/MediaRecorderBuilderTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/ExposureModeTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/ExposureModeTest.java index 63810f0b5684..600c426063e2 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/ExposureModeTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/ExposureModeTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java index 1f5f0c6272ed..8b812b4b011d 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FocusModeTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FocusModeTest.java index 4aa6fadf776b..114aaa342e9b 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FocusModeTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FocusModeTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/example/integration_test/camera_test.dart b/packages/camera/camera/example/integration_test/camera_test.dart index f30734180b20..1b08200ed68d 100644 --- a/packages/camera/camera/example/integration_test/camera_test.dart +++ b/packages/camera/camera/example/integration_test/camera_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/camera/camera/example/ios/Runner.xcodeproj/project.pbxproj b/packages/camera/camera/example/ios/Runner.xcodeproj/project.pbxproj index 3f71bb69d6b6..c865799d6a02 100644 --- a/packages/camera/camera/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/camera/camera/example/ios/Runner.xcodeproj/project.pbxproj @@ -164,7 +164,7 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; diff --git a/packages/camera/camera/example/lib/main.dart b/packages/camera/camera/example/lib/main.dart index 5eebc9a379ca..0148ce41d725 100644 --- a/packages/camera/camera/example/lib/main.dart +++ b/packages/camera/camera/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/example/test_driver/integration_test.dart b/packages/camera/camera/example/test_driver/integration_test.dart index 8a35ec06803d..0ad951cb063d 100644 --- a/packages/camera/camera/example/test_driver/integration_test.dart +++ b/packages/camera/camera/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.h b/packages/camera/camera/ios/Classes/CameraPlugin.h index ae865e496a45..f42084125e6c 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.h +++ b/packages/camera/camera/ios/Classes/CameraPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index c1770ff6d40b..308ca886a45f 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/ios/Tests/CameraPluginTests.m b/packages/camera/camera/ios/Tests/CameraPluginTests.m index 8d9cbc2eb81a..3d8443901672 100644 --- a/packages/camera/camera/ios/Tests/CameraPluginTests.m +++ b/packages/camera/camera/ios/Tests/CameraPluginTests.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/lib/camera.dart b/packages/camera/camera/lib/camera.dart index d6e32affdd7a..daab70128ada 100644 --- a/packages/camera/camera/lib/camera.dart +++ b/packages/camera/camera/lib/camera.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index bb976d1c85fe..f7710d45c7fd 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/camera/camera/lib/src/camera_image.dart b/packages/camera/camera/lib/src/camera_image.dart index 46aa2a6e3091..fd551082bc83 100644 --- a/packages/camera/camera/lib/src/camera_image.dart +++ b/packages/camera/camera/lib/src/camera_image.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/camera/camera/lib/src/camera_preview.dart b/packages/camera/camera/lib/src/camera_preview.dart index f6d357b41b77..caa8c04885c7 100644 --- a/packages/camera/camera/lib/src/camera_preview.dart +++ b/packages/camera/camera/lib/src/camera_preview.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/camera/camera/test/camera_image_stream_test.dart b/packages/camera/camera/test/camera_image_stream_test.dart index 41faeb1fd4b0..6832466a25ba 100644 --- a/packages/camera/camera/test/camera_image_stream_test.dart +++ b/packages/camera/camera/test/camera_image_stream_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/test/camera_image_test.dart b/packages/camera/camera/test/camera_image_test.dart index c7f8e4320434..40d7194e36d1 100644 --- a/packages/camera/camera/test/camera_image_test.dart +++ b/packages/camera/camera/test/camera_image_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index 40ce29e363b1..272587e9955b 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/camera/camera/test/camera_value_test.dart b/packages/camera/camera/test/camera_value_test.dart index de7971d963c0..f1809fc61167 100644 --- a/packages/camera/camera/test/camera_value_test.dart +++ b/packages/camera/camera/test/camera_value_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera/test/utils/method_channel_mock.dart b/packages/camera/camera/test/utils/method_channel_mock.dart index c667bed76e89..6e0b28e224d8 100644 --- a/packages/camera/camera/test/utils/method_channel_mock.dart +++ b/packages/camera/camera/test/utils/method_channel_mock.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/AUTHORS b/packages/camera/camera_platform_interface/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/camera/camera_platform_interface/AUTHORS +++ b/packages/camera/camera_platform_interface/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/camera/camera_platform_interface/LICENSE b/packages/camera/camera_platform_interface/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/camera/camera_platform_interface/LICENSE +++ b/packages/camera/camera_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/camera/camera_platform_interface/lib/camera_platform_interface.dart b/packages/camera/camera_platform_interface/lib/camera_platform_interface.dart index d7e5fcd0834c..b7a7b2ff29b8 100644 --- a/packages/camera/camera_platform_interface/lib/camera_platform_interface.dart +++ b/packages/camera/camera_platform_interface/lib/camera_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart b/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart index 20aa41c5ce40..137a0002ef17 100644 --- a/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart +++ b/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/lib/src/events/device_event.dart b/packages/camera/camera_platform_interface/lib/src/events/device_event.dart index 82febcab2290..a4edbef0d317 100644 --- a/packages/camera/camera_platform_interface/lib/src/events/device_event.dart +++ b/packages/camera/camera_platform_interface/lib/src/events/device_event.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart index 9f7f723bcd79..321104e695e9 100644 --- a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart +++ b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart index 39a17e43dc0f..92e3587ee04b 100644 --- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart +++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/camera/camera_platform_interface/lib/src/types/camera_description.dart b/packages/camera/camera_platform_interface/lib/src/types/camera_description.dart index 9707bd34d0d2..dffb5d1bff01 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/camera_description.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/camera_description.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/camera/camera_platform_interface/lib/src/types/camera_exception.dart b/packages/camera/camera_platform_interface/lib/src/types/camera_exception.dart index 59f3e4e6647e..f8da81392b43 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/camera_exception.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/camera_exception.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart b/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart index 836f53826479..a1cfbfcc08a5 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/lib/src/types/flash_mode.dart b/packages/camera/camera_platform_interface/lib/src/types/flash_mode.dart index 7feb59caeab8..e851857a26d6 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/flash_mode.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/flash_mode.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/lib/src/types/focus_mode.dart b/packages/camera/camera_platform_interface/lib/src/types/focus_mode.dart index 8da2a90fa858..76d429463a29 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/focus_mode.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/focus_mode.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart index 61ccbfc2638a..3c07dfe0faca 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/lib/src/types/resolution_preset.dart b/packages/camera/camera_platform_interface/lib/src/types/resolution_preset.dart index ead592364131..cabeb6a0b9cc 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/resolution_preset.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/resolution_preset.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/lib/src/types/types.dart b/packages/camera/camera_platform_interface/lib/src/types/types.dart index 256558dff3e7..5b9999ece037 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/types.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/types.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/camera/camera_platform_interface/lib/src/utils/utils.dart b/packages/camera/camera_platform_interface/lib/src/utils/utils.dart index f4c21bfca6cc..b8703d603801 100644 --- a/packages/camera/camera_platform_interface/lib/src/utils/utils.dart +++ b/packages/camera/camera_platform_interface/lib/src/utils/utils.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart b/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart index f663db9776d1..b3d61a467373 100644 --- a/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart +++ b/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/test/events/camera_event_test.dart b/packages/camera/camera_platform_interface/test/events/camera_event_test.dart index f146b7e7e7bc..120cafc238c3 100644 --- a/packages/camera/camera_platform_interface/test/events/camera_event_test.dart +++ b/packages/camera/camera_platform_interface/test/events/camera_event_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/test/events/device_event_test.dart b/packages/camera/camera_platform_interface/test/events/device_event_test.dart index c2fef49be04f..950a12e21484 100644 --- a/packages/camera/camera_platform_interface/test/events/device_event_test.dart +++ b/packages/camera/camera_platform_interface/test/events/device_event_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart index 5248d34c46b9..ea7e9787a817 100644 --- a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart +++ b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/test/types/camera_description_test.dart b/packages/camera/camera_platform_interface/test/types/camera_description_test.dart index 03909dbafb97..a098df07b094 100644 --- a/packages/camera/camera_platform_interface/test/types/camera_description_test.dart +++ b/packages/camera/camera_platform_interface/test/types/camera_description_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/test/types/camera_exception_test.dart b/packages/camera/camera_platform_interface/test/types/camera_exception_test.dart index 17370e4561f5..338238e0bb75 100644 --- a/packages/camera/camera_platform_interface/test/types/camera_exception_test.dart +++ b/packages/camera/camera_platform_interface/test/types/camera_exception_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/test/types/exposure_mode_test.dart b/packages/camera/camera_platform_interface/test/types/exposure_mode_test.dart index c34c1d7b4157..b8e77fe5df80 100644 --- a/packages/camera/camera_platform_interface/test/types/exposure_mode_test.dart +++ b/packages/camera/camera_platform_interface/test/types/exposure_mode_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/test/types/flash_mode_test.dart b/packages/camera/camera_platform_interface/test/types/flash_mode_test.dart index c9df64152cef..8c6903087fdd 100644 --- a/packages/camera/camera_platform_interface/test/types/flash_mode_test.dart +++ b/packages/camera/camera_platform_interface/test/types/flash_mode_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/test/types/focus_mode_test.dart b/packages/camera/camera_platform_interface/test/types/focus_mode_test.dart index ca7ad902820a..5ce379400e37 100644 --- a/packages/camera/camera_platform_interface/test/types/focus_mode_test.dart +++ b/packages/camera/camera_platform_interface/test/types/focus_mode_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/test/types/image_group_test.dart b/packages/camera/camera_platform_interface/test/types/image_group_test.dart index ac975fa6e6ce..9ae4b9bb4c3c 100644 --- a/packages/camera/camera_platform_interface/test/types/image_group_test.dart +++ b/packages/camera/camera_platform_interface/test/types/image_group_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/test/types/resolution_preset_test.dart b/packages/camera/camera_platform_interface/test/types/resolution_preset_test.dart index aadf589f87c4..4da08cf2f0b7 100644 --- a/packages/camera/camera_platform_interface/test/types/resolution_preset_test.dart +++ b/packages/camera/camera_platform_interface/test/types/resolution_preset_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/test/utils/method_channel_mock.dart b/packages/camera/camera_platform_interface/test/utils/method_channel_mock.dart index c667bed76e89..6e0b28e224d8 100644 --- a/packages/camera/camera_platform_interface/test/utils/method_channel_mock.dart +++ b/packages/camera/camera_platform_interface/test/utils/method_channel_mock.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/camera/camera_platform_interface/test/utils/utils_test.dart b/packages/camera/camera_platform_interface/test/utils/utils_test.dart index 822798160439..d99f9ab01443 100644 --- a/packages/camera/camera_platform_interface/test/utils/utils_test.dart +++ b/packages/camera/camera_platform_interface/test/utils/utils_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/connectivity/connectivity/AUTHORS b/packages/connectivity/connectivity/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/connectivity/connectivity/AUTHORS +++ b/packages/connectivity/connectivity/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/connectivity/connectivity/LICENSE b/packages/connectivity/connectivity/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/connectivity/connectivity/LICENSE +++ b/packages/connectivity/connectivity/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/Connectivity.java b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/Connectivity.java index a8902fa62ef9..f2f16ae61629 100644 --- a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/Connectivity.java +++ b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/Connectivity.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java index dbf96bda9fe8..e44e7b4e8f5d 100644 --- a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java +++ b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityMethodChannelHandler.java b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityMethodChannelHandler.java index de1958a1f4f1..3f8541ed1c54 100644 --- a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityMethodChannelHandler.java +++ b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityMethodChannelHandler.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityPlugin.java b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityPlugin.java index 3de60f06c67e..91d00839145f 100644 --- a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityPlugin.java +++ b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1Activity.java b/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1Activity.java index 591f1ec604d7..89438471ace3 100644 --- a/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1Activity.java +++ b/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java b/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java index 2adc0c268bde..1667a7317c68 100644 --- a/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java +++ b/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/FlutterActivityTest.java b/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/FlutterActivityTest.java index 0f0dcf2555f3..8d7f9d0c460f 100644 --- a/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/FlutterActivityTest.java +++ b/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/FlutterActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/connectivity/connectivity/example/ios/Runner.xcodeproj/project.pbxproj b/packages/connectivity/connectivity/example/ios/Runner.xcodeproj/project.pbxproj index e497d093be56..e77d9f454116 100644 --- a/packages/connectivity/connectivity/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/connectivity/connectivity/example/ios/Runner.xcodeproj/project.pbxproj @@ -177,7 +177,7 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; diff --git a/packages/connectivity/connectivity/example/ios/Runner/AppDelegate.h b/packages/connectivity/connectivity/example/ios/Runner/AppDelegate.h index d9e18e990f2e..31fc381e7066 100644 --- a/packages/connectivity/connectivity/example/ios/Runner/AppDelegate.h +++ b/packages/connectivity/connectivity/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/connectivity/connectivity/example/ios/Runner/AppDelegate.m b/packages/connectivity/connectivity/example/ios/Runner/AppDelegate.m index f08675707182..2147d3d605ac 100644 --- a/packages/connectivity/connectivity/example/ios/Runner/AppDelegate.m +++ b/packages/connectivity/connectivity/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/connectivity/connectivity/example/ios/Runner/main.m b/packages/connectivity/connectivity/example/ios/Runner/main.m index bec320c0bee0..f451b14cb751 100644 --- a/packages/connectivity/connectivity/example/ios/Runner/main.m +++ b/packages/connectivity/connectivity/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/connectivity/connectivity/example/lib/main.dart b/packages/connectivity/connectivity/example/lib/main.dart index 19285ce889fd..6f6356f0fc2b 100644 --- a/packages/connectivity/connectivity/example/lib/main.dart +++ b/packages/connectivity/connectivity/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/connectivity/connectivity/example/test_driver/integration_test/connectivity_test.dart b/packages/connectivity/connectivity/example/test_driver/integration_test/connectivity_test.dart index 3177b66ea48a..13c9d4b5e8fb 100644 --- a/packages/connectivity/connectivity/example/test_driver/integration_test/connectivity_test.dart +++ b/packages/connectivity/connectivity/example/test_driver/integration_test/connectivity_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/connectivity/connectivity/example/test_driver/test/integration_test.dart b/packages/connectivity/connectivity/example/test_driver/test/integration_test.dart index 33421c335bdd..9887033fc5dd 100644 --- a/packages/connectivity/connectivity/example/test_driver/test/integration_test.dart +++ b/packages/connectivity/connectivity/example/test_driver/test/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/connectivity/connectivity/integration_test/connectivity_test.dart b/packages/connectivity/connectivity/integration_test/connectivity_test.dart index 3177b66ea48a..13c9d4b5e8fb 100644 --- a/packages/connectivity/connectivity/integration_test/connectivity_test.dart +++ b/packages/connectivity/connectivity/integration_test/connectivity_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/connectivity/connectivity/ios/Classes/FLTConnectivityPlugin.h b/packages/connectivity/connectivity/ios/Classes/FLTConnectivityPlugin.h index 5014624f2f69..bb0ff07dc712 100644 --- a/packages/connectivity/connectivity/ios/Classes/FLTConnectivityPlugin.h +++ b/packages/connectivity/connectivity/ios/Classes/FLTConnectivityPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/connectivity/connectivity/ios/Classes/FLTConnectivityPlugin.m b/packages/connectivity/connectivity/ios/Classes/FLTConnectivityPlugin.m index fb996c1b11ba..241d01c1b007 100644 --- a/packages/connectivity/connectivity/ios/Classes/FLTConnectivityPlugin.m +++ b/packages/connectivity/connectivity/ios/Classes/FLTConnectivityPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/connectivity/connectivity/lib/connectivity.dart b/packages/connectivity/connectivity/lib/connectivity.dart index 0f30a9347b74..e4199d55f699 100644 --- a/packages/connectivity/connectivity/lib/connectivity.dart +++ b/packages/connectivity/connectivity/lib/connectivity.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/connectivity/connectivity/test/connectivity_test.dart b/packages/connectivity/connectivity/test/connectivity_test.dart index c95d0862444f..cde833c9d71e 100644 --- a/packages/connectivity/connectivity/test/connectivity_test.dart +++ b/packages/connectivity/connectivity/test/connectivity_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/connectivity/connectivity_for_web/AUTHORS b/packages/connectivity/connectivity_for_web/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/connectivity/connectivity_for_web/AUTHORS +++ b/packages/connectivity/connectivity_for_web/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/connectivity/connectivity_for_web/example/test_driver/integration_driver.dart b/packages/connectivity/connectivity_for_web/example/test_driver/integration_driver.dart index 64e2248a4f9b..0dd5f694f16b 100644 --- a/packages/connectivity/connectivity_for_web/example/test_driver/integration_driver.dart +++ b/packages/connectivity/connectivity_for_web/example/test_driver/integration_driver.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/connectivity/connectivity_macos/AUTHORS b/packages/connectivity/connectivity_macos/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/connectivity/connectivity_macos/AUTHORS +++ b/packages/connectivity/connectivity_macos/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/connectivity/connectivity_macos/LICENSE b/packages/connectivity/connectivity_macos/LICENSE index 507569823f1b..b257ce7c224c 100644 --- a/packages/connectivity/connectivity_macos/LICENSE +++ b/packages/connectivity/connectivity_macos/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019 The Chromium Authors. All rights reserved. +Copyright 2019 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/connectivity/connectivity_macos/example/lib/main.dart b/packages/connectivity/connectivity_macos/example/lib/main.dart index 07746ed0f722..97baf2678fd3 100644 --- a/packages/connectivity/connectivity_macos/example/lib/main.dart +++ b/packages/connectivity/connectivity_macos/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/connectivity/connectivity_macos/example/test_driver/integration_test/connectivity_test.dart b/packages/connectivity/connectivity_macos/example/test_driver/integration_test/connectivity_test.dart index 3abe491d193b..d38614076190 100644 --- a/packages/connectivity/connectivity_macos/example/test_driver/integration_test/connectivity_test.dart +++ b/packages/connectivity/connectivity_macos/example/test_driver/integration_test/connectivity_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/connectivity/connectivity_macos/example/test_driver/test/integration_test.dart b/packages/connectivity/connectivity_macos/example/test_driver/test/integration_test.dart index 425dac924e7c..49af1cbb81a5 100644 --- a/packages/connectivity/connectivity_macos/example/test_driver/test/integration_test.dart +++ b/packages/connectivity/connectivity_macos/example/test_driver/test/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/connectivity/connectivity_macos/macos/Classes/ConnectivityPlugin.swift b/packages/connectivity/connectivity_macos/macos/Classes/ConnectivityPlugin.swift index 8eafbc3188cf..302c6d7d55e3 100644 --- a/packages/connectivity/connectivity_macos/macos/Classes/ConnectivityPlugin.swift +++ b/packages/connectivity/connectivity_macos/macos/Classes/ConnectivityPlugin.swift @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/connectivity/connectivity_macos/macos/Classes/IPHelper.h b/packages/connectivity/connectivity_macos/macos/Classes/IPHelper.h index e5a067b9069f..a1bc4ce12179 100644 --- a/packages/connectivity/connectivity_macos/macos/Classes/IPHelper.h +++ b/packages/connectivity/connectivity_macos/macos/Classes/IPHelper.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/connectivity/connectivity_platform_interface/AUTHORS b/packages/connectivity/connectivity_platform_interface/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/connectivity/connectivity_platform_interface/AUTHORS +++ b/packages/connectivity/connectivity_platform_interface/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/connectivity/connectivity_platform_interface/LICENSE b/packages/connectivity/connectivity_platform_interface/LICENSE index d7412e0a1e0c..67c7e2c52e46 100644 --- a/packages/connectivity/connectivity_platform_interface/LICENSE +++ b/packages/connectivity/connectivity_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020 The Chromium Authors. All rights reserved. +Copyright 2020 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/connectivity/connectivity_platform_interface/lib/connectivity_platform_interface.dart b/packages/connectivity/connectivity_platform_interface/lib/connectivity_platform_interface.dart index 8e9f0fd6af06..b137509f650a 100644 --- a/packages/connectivity/connectivity_platform_interface/lib/connectivity_platform_interface.dart +++ b/packages/connectivity/connectivity_platform_interface/lib/connectivity_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart b/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart index 640e378de0ce..9c8398f2f67a 100644 --- a/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart +++ b/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/connectivity/connectivity_platform_interface/lib/src/method_channel_connectivity.dart b/packages/connectivity/connectivity_platform_interface/lib/src/method_channel_connectivity.dart index b411b5bc069b..f04eb9193fb5 100644 --- a/packages/connectivity/connectivity_platform_interface/lib/src/method_channel_connectivity.dart +++ b/packages/connectivity/connectivity_platform_interface/lib/src/method_channel_connectivity.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart b/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart index 4df92974ba0c..5c62c61220ec 100644 --- a/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart +++ b/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/connectivity/connectivity_platform_interface/test/method_channel_connectivity_test.dart b/packages/connectivity/connectivity_platform_interface/test/method_channel_connectivity_test.dart index 0c30530fc9ab..5ae66acabc36 100644 --- a/packages/connectivity/connectivity_platform_interface/test/method_channel_connectivity_test.dart +++ b/packages/connectivity/connectivity_platform_interface/test/method_channel_connectivity_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/device_info/device_info/AUTHORS b/packages/device_info/device_info/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/device_info/device_info/AUTHORS +++ b/packages/device_info/device_info/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/device_info/device_info/LICENSE b/packages/device_info/device_info/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/device_info/device_info/LICENSE +++ b/packages/device_info/device_info/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java b/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java index 137daf508ac2..28fdc888560b 100644 --- a/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java +++ b/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java b/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java index 800ca6dcddb7..fb44bc821e6d 100644 --- a/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java +++ b/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java b/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java index 0256c6b8a1fb..6be74796a0b6 100644 --- a/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java +++ b/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/device_info/device_info/example/integration_test/device_info_test.dart b/packages/device_info/device_info/example/integration_test/device_info_test.dart index a2a3ba7733ce..9fbb682df2e8 100644 --- a/packages/device_info/device_info/example/integration_test/device_info_test.dart +++ b/packages/device_info/device_info/example/integration_test/device_info_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/device_info/device_info/example/ios/Runner.xcodeproj/project.pbxproj b/packages/device_info/device_info/example/ios/Runner.xcodeproj/project.pbxproj index 8f80e80abb09..1c6c6e8f4d50 100644 --- a/packages/device_info/device_info/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/device_info/device_info/example/ios/Runner.xcodeproj/project.pbxproj @@ -177,7 +177,7 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; diff --git a/packages/device_info/device_info/example/ios/Runner/AppDelegate.h b/packages/device_info/device_info/example/ios/Runner/AppDelegate.h index d9e18e990f2e..31fc381e7066 100644 --- a/packages/device_info/device_info/example/ios/Runner/AppDelegate.h +++ b/packages/device_info/device_info/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/device_info/device_info/example/ios/Runner/AppDelegate.m b/packages/device_info/device_info/example/ios/Runner/AppDelegate.m index f08675707182..2147d3d605ac 100644 --- a/packages/device_info/device_info/example/ios/Runner/AppDelegate.m +++ b/packages/device_info/device_info/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/device_info/device_info/example/ios/Runner/main.m b/packages/device_info/device_info/example/ios/Runner/main.m index bec320c0bee0..f451b14cb751 100644 --- a/packages/device_info/device_info/example/ios/Runner/main.m +++ b/packages/device_info/device_info/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/device_info/device_info/example/lib/main.dart b/packages/device_info/device_info/example/lib/main.dart index 805de1417f15..24129aa04b1c 100644 --- a/packages/device_info/device_info/example/lib/main.dart +++ b/packages/device_info/device_info/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/device_info/device_info/example/test_driver/integration_test.dart b/packages/device_info/device_info/example/test_driver/integration_test.dart index 84004cebd1a6..29b5b21a5941 100644 --- a/packages/device_info/device_info/example/test_driver/integration_test.dart +++ b/packages/device_info/device_info/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.h b/packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.h index b5e95ed10e84..e4e287c584d5 100644 --- a/packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.h +++ b/packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.m b/packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.m index 423896061ac7..bc2d172c576e 100644 --- a/packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.m +++ b/packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/device_info/device_info/lib/device_info.dart b/packages/device_info/device_info/lib/device_info.dart index bccc3d2fbfa6..a357844cf2d9 100644 --- a/packages/device_info/device_info/lib/device_info.dart +++ b/packages/device_info/device_info/lib/device_info.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/device_info/device_info_platform_interface/AUTHORS b/packages/device_info/device_info_platform_interface/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/device_info/device_info_platform_interface/AUTHORS +++ b/packages/device_info/device_info_platform_interface/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/device_info/device_info_platform_interface/LICENSE b/packages/device_info/device_info_platform_interface/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/device_info/device_info_platform_interface/LICENSE +++ b/packages/device_info/device_info_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/device_info/device_info_platform_interface/lib/device_info_platform_interface.dart b/packages/device_info/device_info_platform_interface/lib/device_info_platform_interface.dart index 2dd41dcc580f..676207ba07fe 100644 --- a/packages/device_info/device_info_platform_interface/lib/device_info_platform_interface.dart +++ b/packages/device_info/device_info_platform_interface/lib/device_info_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/device_info/device_info_platform_interface/lib/method_channel/method_channel_device_info.dart b/packages/device_info/device_info_platform_interface/lib/method_channel/method_channel_device_info.dart index 331f718989ce..d9eb455684e7 100644 --- a/packages/device_info/device_info_platform_interface/lib/method_channel/method_channel_device_info.dart +++ b/packages/device_info/device_info_platform_interface/lib/method_channel/method_channel_device_info.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/device_info/device_info_platform_interface/lib/model/android_device_info.dart b/packages/device_info/device_info_platform_interface/lib/model/android_device_info.dart index c5210ab10f50..00195a8f42b2 100644 --- a/packages/device_info/device_info_platform_interface/lib/model/android_device_info.dart +++ b/packages/device_info/device_info_platform_interface/lib/model/android_device_info.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/device_info/device_info_platform_interface/lib/model/ios_device_info.dart b/packages/device_info/device_info_platform_interface/lib/model/ios_device_info.dart index 20ec8362f66d..e779ddc8a129 100644 --- a/packages/device_info/device_info_platform_interface/lib/model/ios_device_info.dart +++ b/packages/device_info/device_info_platform_interface/lib/model/ios_device_info.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart b/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart index b257109fe2f6..cc0b4b4d10a7 100644 --- a/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart +++ b/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/espresso/AUTHORS b/packages/espresso/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/espresso/AUTHORS +++ b/packages/espresso/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/espresso/LICENSE b/packages/espresso/LICENSE index 507569823f1b..b257ce7c224c 100644 --- a/packages/espresso/LICENSE +++ b/packages/espresso/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019 The Chromium Authors. All rights reserved. +Copyright 2019 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/EspressoFlutter.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/EspressoFlutter.java index 6730a66a5406..89233e64799f 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/EspressoFlutter.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/EspressoFlutter.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/ActionUtil.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/ActionUtil.java index 7dcb05b41724..8ab4c4a137cf 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/ActionUtil.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/ActionUtil.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/ClickAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/ClickAction.java index 5da56fd402ad..949c1e1cffbd 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/ClickAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/ClickAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterActions.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterActions.java index 258daf67a66e..3fdcb08eb525 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterActions.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterActions.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterScrollToAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterScrollToAction.java index b97252a2306e..4462ff6d6646 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterScrollToAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterScrollToAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterTypeTextAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterTypeTextAction.java index bb62250eefcb..b0b744773066 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterTypeTextAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterTypeTextAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterViewAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterViewAction.java index fc554d761db5..0d8d94844d97 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterViewAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterViewAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/SyntheticClickAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/SyntheticClickAction.java index 5036be1fd290..ddc347defa55 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/SyntheticClickAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/SyntheticClickAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WaitUntilIdleAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WaitUntilIdleAction.java index b83e29b7e582..054c00e86d60 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WaitUntilIdleAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WaitUntilIdleAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WidgetCoordinatesCalculator.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WidgetCoordinatesCalculator.java index 8d541ae823ee..0ef5a5761dc3 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WidgetCoordinatesCalculator.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WidgetCoordinatesCalculator.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WidgetInfoFetcher.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WidgetInfoFetcher.java index 90d494e0b8ea..3e5f48d56983 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WidgetInfoFetcher.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WidgetInfoFetcher.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/FlutterAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/FlutterAction.java index 24b264c00a27..3f1d3a23d99a 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/FlutterAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/FlutterAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/FlutterTestingProtocol.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/FlutterTestingProtocol.java index d01aaf5fdc09..54be97652157 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/FlutterTestingProtocol.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/FlutterTestingProtocol.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/SyntheticAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/SyntheticAction.java index aed0c4bc7570..0d2f0cbf49cf 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/SyntheticAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/SyntheticAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetAction.java index e49d3ef2bb0f..b04cb0cb1d8a 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetAssertion.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetAssertion.java index 313dd2672336..d69972b09b3f 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetAssertion.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetAssertion.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetMatcher.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetMatcher.java index 9f47e0bbeee6..a8e0b6a07c75 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetMatcher.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetMatcher.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/assertion/FlutterAssertions.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/assertion/FlutterAssertions.java index 63ec0f6f6fdc..6573f2a2a705 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/assertion/FlutterAssertions.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/assertion/FlutterAssertions.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/assertion/FlutterViewAssertion.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/assertion/FlutterViewAssertion.java index 5f4697de947a..6bc81b5862e4 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/assertion/FlutterViewAssertion.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/assertion/FlutterViewAssertion.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/common/Constants.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/common/Constants.java index c47f8df1e34d..170830fc7abb 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/common/Constants.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/common/Constants.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/common/Duration.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/common/Duration.java index d620153fc2f5..1d7bac224ec6 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/common/Duration.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/common/Duration.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/AmbiguousWidgetMatcherException.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/AmbiguousWidgetMatcherException.java index 24d495f74945..adf2e39db0b8 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/AmbiguousWidgetMatcherException.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/AmbiguousWidgetMatcherException.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/InvalidFlutterViewException.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/InvalidFlutterViewException.java index ca69e39802d0..16c49220e0b9 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/InvalidFlutterViewException.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/InvalidFlutterViewException.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/NoMatchingWidgetException.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/NoMatchingWidgetException.java index 49c949a07c8a..55ce0f4e3935 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/NoMatchingWidgetException.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/NoMatchingWidgetException.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdException.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdException.java index 1a3666ec24e1..5be422184fe6 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdException.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdException.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdGenerator.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdGenerator.java index b69d8f61aa4f..ee6d693d97ee 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdGenerator.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdGenerator.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdGenerators.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdGenerators.java index f8f72dc2a37d..28d6816b7306 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdGenerators.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdGenerators.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/JsonRpcClient.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/JsonRpcClient.java index 028a78028406..7b5f8458a8f5 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/JsonRpcClient.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/JsonRpcClient.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/ErrorObject.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/ErrorObject.java index d7779d3e5ec7..bf31679d7b3b 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/ErrorObject.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/ErrorObject.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/JsonRpcRequest.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/JsonRpcRequest.java index fa033407eabf..6eff736b5434 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/JsonRpcRequest.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/JsonRpcRequest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/JsonRpcResponse.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/JsonRpcResponse.java index f845765a98e5..45b376a3f793 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/JsonRpcResponse.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/JsonRpcResponse.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/DartVmService.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/DartVmService.java index c6ec0e08b03a..7e3b277558c9 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/DartVmService.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/DartVmService.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/DartVmServiceUtil.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/DartVmServiceUtil.java index a943194e348e..2534cc4d4736 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/DartVmServiceUtil.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/DartVmServiceUtil.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/FlutterProtocolException.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/FlutterProtocolException.java index 71cdb26ebf5c..b2b182f10640 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/FlutterProtocolException.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/FlutterProtocolException.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetOffsetAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetOffsetAction.java index 9b92f672f356..4dbf78836223 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetOffsetAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetOffsetAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetOffsetResponse.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetOffsetResponse.java index 52fcd4ce45ab..202f774f5d6b 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetOffsetResponse.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetOffsetResponse.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetVmResponse.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetVmResponse.java index 2fe0d44bfcda..e3f97afb97fa 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetVmResponse.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetVmResponse.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetWidgetDiagnosticsAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetWidgetDiagnosticsAction.java index 5982ee481ed8..4753dd3dc451 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetWidgetDiagnosticsAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetWidgetDiagnosticsAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetWidgetDiagnosticsResponse.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetWidgetDiagnosticsResponse.java index 65a456c0939a..6ee27de06705 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetWidgetDiagnosticsResponse.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetWidgetDiagnosticsResponse.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoPendingFrameCondition.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoPendingFrameCondition.java index 7e7739b6a1a0..64c37d31a782 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoPendingFrameCondition.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoPendingFrameCondition.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoPendingPlatformMessagesCondition.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoPendingPlatformMessagesCondition.java index 8430ee23f92d..7969ef851b3e 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoPendingPlatformMessagesCondition.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoPendingPlatformMessagesCondition.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoTransientCallbacksCondition.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoTransientCallbacksCondition.java index 4548b28b66bd..d4eb77810d0b 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoTransientCallbacksCondition.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoTransientCallbacksCondition.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WaitCondition.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WaitCondition.java index 7017e88765f3..5baba66b89cb 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WaitCondition.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WaitCondition.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WaitForConditionAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WaitForConditionAction.java index efbe588828c3..2880130e8438 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WaitForConditionAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WaitForConditionAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WidgetInfoFactory.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WidgetInfoFactory.java index 2353577e5f4b..264f6cb77e5d 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WidgetInfoFactory.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WidgetInfoFactory.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/FlutterMatchers.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/FlutterMatchers.java index f867b7dcbed4..634e2197ee94 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/FlutterMatchers.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/FlutterMatchers.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/IsDescendantOfMatcher.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/IsDescendantOfMatcher.java index 24a441549624..947a0f79cad4 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/IsDescendantOfMatcher.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/IsDescendantOfMatcher.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/IsExistingMatcher.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/IsExistingMatcher.java index 3380d2146b87..843d331d10a3 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/IsExistingMatcher.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/IsExistingMatcher.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTextMatcher.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTextMatcher.java index 4b86aed03216..711a835a45a5 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTextMatcher.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTextMatcher.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTooltipMatcher.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTooltipMatcher.java index 27d4314b3039..fde9cd805ce8 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTooltipMatcher.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTooltipMatcher.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTypeMatcher.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTypeMatcher.java index 84cf0e03feae..b30fdf38674c 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTypeMatcher.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTypeMatcher.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithValueKeyMatcher.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithValueKeyMatcher.java index 0e3df39be9b8..719f8adcab4d 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithValueKeyMatcher.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithValueKeyMatcher.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/model/WidgetInfo.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/model/WidgetInfo.java index d6394d2052f3..5b90a0002b53 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/model/WidgetInfo.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/model/WidgetInfo.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/model/WidgetInfoBuilder.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/model/WidgetInfoBuilder.java index 53ea8a27cddc..c119278af645 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/model/WidgetInfoBuilder.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/model/WidgetInfoBuilder.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/espresso/example/android/app/src/androidTest/java/com/example/MainActivityTest.java b/packages/espresso/example/android/app/src/androidTest/java/com/example/MainActivityTest.java index aaedd6cbd7cb..8a432809e9cb 100644 --- a/packages/espresso/example/android/app/src/androidTest/java/com/example/MainActivityTest.java +++ b/packages/espresso/example/android/app/src/androidTest/java/com/example/MainActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/flutter_plugin_android_lifecycle/AUTHORS b/packages/flutter_plugin_android_lifecycle/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/flutter_plugin_android_lifecycle/AUTHORS +++ b/packages/flutter_plugin_android_lifecycle/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/flutter_plugin_android_lifecycle/LICENSE b/packages/flutter_plugin_android_lifecycle/LICENSE index 507569823f1b..b257ce7c224c 100644 --- a/packages/flutter_plugin_android_lifecycle/LICENSE +++ b/packages/flutter_plugin_android_lifecycle/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019 The Chromium Authors. All rights reserved. +Copyright 2019 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapter.java b/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapter.java index 91ac6e0fd15f..3c91bb744d5c 100644 --- a/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapter.java +++ b/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapter.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle/FlutterAndroidLifecyclePlugin.java b/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle/FlutterAndroidLifecyclePlugin.java index bd77c1545ac7..fa90a210ffd2 100644 --- a/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle/FlutterAndroidLifecyclePlugin.java +++ b/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle/FlutterAndroidLifecyclePlugin.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. // diff --git a/packages/flutter_plugin_android_lifecycle/android/src/test/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapterTest.java b/packages/flutter_plugin_android_lifecycle/android/src/test/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapterTest.java index 6657dfbb5a71..c184b1ad88db 100644 --- a/packages/flutter_plugin_android_lifecycle/android/src/test/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapterTest.java +++ b/packages/flutter_plugin_android_lifecycle/android/src/test/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapterTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/EmbeddingV1ActivityTest.java b/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/EmbeddingV1ActivityTest.java index e61cadd3a9d3..89b9192c1676 100644 --- a/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/EmbeddingV1ActivityTest.java +++ b/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/MainActivityTest.java b/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/MainActivityTest.java index 4c3c9a247883..22bc3fe68d46 100644 --- a/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/MainActivityTest.java +++ b/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/MainActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/MainActivity.java b/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/MainActivity.java index e2d2560e9105..a05da9ebb71a 100644 --- a/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/MainActivity.java +++ b/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/MainActivity.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. 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 e4b92c8db7ed..8890f14925ab 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 @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/flutter_plugin_android_lifecycle/example/lib/main.dart b/packages/flutter_plugin_android_lifecycle/example/lib/main.dart index c055c5359515..d9ee842364a6 100644 --- a/packages/flutter_plugin_android_lifecycle/example/lib/main.dart +++ b/packages/flutter_plugin_android_lifecycle/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/flutter_plugin_android_lifecycle/lib/flutter_plugin_android_lifecycle.dart b/packages/flutter_plugin_android_lifecycle/lib/flutter_plugin_android_lifecycle.dart index ea111552567d..38bb867225d1 100644 --- a/packages/flutter_plugin_android_lifecycle/lib/flutter_plugin_android_lifecycle.dart +++ b/packages/flutter_plugin_android_lifecycle/lib/flutter_plugin_android_lifecycle.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/AUTHORS b/packages/google_maps_flutter/google_maps_flutter/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/google_maps_flutter/google_maps_flutter/AUTHORS +++ b/packages/google_maps_flutter/google_maps_flutter/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/google_maps_flutter/google_maps_flutter/LICENSE b/packages/google_maps_flutter/google_maps_flutter/LICENSE index ad33cf3c3ed1..050e2c7cac4f 100644 --- a/packages/google_maps_flutter/google_maps_flutter/LICENSE +++ b/packages/google_maps_flutter/google_maps_flutter/LICENSE @@ -1,4 +1,4 @@ -Copyright 2018 The Chromium Authors. All rights reserved. +Copyright 2018 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleBuilder.java index 751887a6fa22..230659d2bf71 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleBuilder.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleController.java index 709045a1b9f6..27accafd9bd9 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleController.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleOptionsSink.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleOptionsSink.java index 950c3209ee62..51e6c2194ab7 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleOptionsSink.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleOptionsSink.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CirclesController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CirclesController.java index b7b562ee94a6..d9661e9e80f8 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CirclesController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CirclesController.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java index f9e0ed9c32d0..30e7339f3de5 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java index 6d5c8c64ae1d..8d3414edfc4c 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java index 7db65c56a5e8..92d0e044e577 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java index bf9188ffd1b1..96cfee088ad3 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapListener.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapListener.java index 518d45c4a9f6..c240f89deddb 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapListener.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapListener.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java index 03377d4b760e..4ed31fabdab0 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java index 69ba8cb222c0..0a0a17a05f47 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/LifecycleProvider.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/LifecycleProvider.java index 154de200fd86..0e06321e7267 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/LifecycleProvider.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/LifecycleProvider.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerBuilder.java index 29e4de00c5b0..69637a12bff0 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerBuilder.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerController.java index 412daee5cf68..667254ea9d7f 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerController.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerOptionsSink.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerOptionsSink.java index 3f853b9f1459..25ed42927189 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerOptionsSink.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerOptionsSink.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkersController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkersController.java index 70feb978af3f..8a9897886f11 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkersController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkersController.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonBuilder.java index 7691e58e4ae6..149c1246f596 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonBuilder.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonController.java index 43f1bfd7ec4c..3fe58f2fb900 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonController.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonOptionsSink.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonOptionsSink.java index 2985a7b762e5..6b4aea89efc1 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonOptionsSink.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonOptionsSink.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonsController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonsController.java index 07f2ad0f7c38..734525b2b0a3 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonsController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonsController.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineBuilder.java index 9fd242a4706f..2a8718710262 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineBuilder.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineController.java index ec0fed83be49..172c807eb2a2 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineController.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineOptionsSink.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineOptionsSink.java index adaf867b92d1..d05059860d68 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineOptionsSink.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineOptionsSink.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylinesController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylinesController.java index a6ad61adc170..b6f3a90f4745 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylinesController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylinesController.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayBuilder.java index 1b5593358536..cbe6cfbd5e51 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayBuilder.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayController.java index 1204bcdaafd7..9f07d7e6859f 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayController.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaySink.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaySink.java index fd611d7c57f3..b32ae8fb6f67 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaySink.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaySink.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java index cd583e247cdd..f72dd7d6c1af 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileProviderController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileProviderController.java index f28118c91db4..e760fafca8b7 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileProviderController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileProviderController.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleBuilderTest.java b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleBuilderTest.java index 24bee4ea7550..5b24902e17f1 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleBuilderTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleBuilderTest.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleControllerTest.java b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleControllerTest.java index 7c8032b2b0d4..33765e71e7a1 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleControllerTest.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonBuilderTest.java b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonBuilderTest.java index e3c2f339f250..0d167a5dbe1e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonBuilderTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonBuilderTest.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonControllerTest.java b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonControllerTest.java index e65cb1f22dc9..f4a0248240a4 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonControllerTest.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineBuilderTest.java b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineBuilderTest.java index 7e5d39c380fd..bca2ebe5b8ce 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineBuilderTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineBuilderTest.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineControllerTest.java b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineControllerTest.java index 1f0a7000f5e7..7cfa33acbd7c 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineControllerTest.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart index 33ad5d03778e..02e1ac430e2e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. // @dart=2.9 diff --git a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart index 44412d490ec0..0230a2157297 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. // @dart=2.9 diff --git a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner.xcodeproj/project.pbxproj b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner.xcodeproj/project.pbxproj index 75392aeb82e5..9cbff5466ec5 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner.xcodeproj/project.pbxproj @@ -166,7 +166,7 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/animate_camera.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/animate_camera.dart index f6a2fecf5b0d..6581bc0af7b8 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/animate_camera.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/animate_camera.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/lite_mode.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/lite_mode.dart index 7c814f31a660..cb7fe0b861d8 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/lite_mode.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/lite_mode.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart index b795040658e6..9a6cf91a987d 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_click.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_click.dart index eaeb463e1b33..cea5c3ee3d35 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_click.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_click.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_coordinates.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_coordinates.dart index 20cccd6b61fd..4819fcbd577b 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_coordinates.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_coordinates.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_ui.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_ui.dart index edae82e4074c..703523efc2ec 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_ui.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_ui.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/marker_icons.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/marker_icons.dart index 90404c347dd8..d37fe5fb2203 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/marker_icons.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/marker_icons.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/move_camera.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/move_camera.dart index 860b19e7925c..add70fbdd7a8 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/move_camera.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/move_camera.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/padding.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/padding.dart index 45b4a9e09e5c..fa35ae0c90f3 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/padding.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/padding.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/page.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/page.dart index eaa43fc9f26d..536cbbc361d3 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/page.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/page.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_circle.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_circle.dart index 59d30e51ce8b..9885747e7cba 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_circle.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_circle.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart index c650ca34c1b0..8ba85eff1b37 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart index 8ee58420f508..192416a92e01 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart index c66343d78f00..7f24979b5ed1 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/scrolling_map.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/scrolling_map.dart index b7d88bc46a58..684a66b993ef 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/scrolling_map.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/scrolling_map.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/snapshot.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/snapshot.dart index 3ba12bfac3f2..fadfc1775f31 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/snapshot.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/snapshot.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart index 8ae3b3bca979..a8cb34133dcf 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/test_driver/integration_test.dart b/packages/google_maps_flutter/google_maps_flutter/example/test_driver/integration_test.dart index 7a26a52ae1a1..80715b0ee874 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/test_driver/integration_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. // @dart=2.9 diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h index f84ad7c20bb4..5ef5eb86dfbb 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m index 7fbd7c53b90a..68884c650ecb 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.h index 645ace34f9ed..ca815956de9a 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.m index 14585bcdb29c..2b345a1ddee2 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.h index 166cf996a572..2a8022a3ef2a 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m index 6688d4d57695..25c0f37b427b 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.h index 1bc8536f97d9..f261722cf7e1 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m index 749ce9e84a4e..a823c4bbe660 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.h index 593d2ff9931b..468c399e808f 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. @@ -52,4 +52,4 @@ NS_ASSUME_NONNULL_BEGIN - (void)isMarkerInfoWindowShown:(NSString*)markerId result:(FlutterResult)result; @end -NS_ASSUME_NONNULL_END \ No newline at end of file +NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m index cd51b2fd9896..a6d395b0c505 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h index eb1735d134b8..ad611a759548 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m index 1063a8cda990..445e4aebde1d 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.h index d1e10ace462e..c0f46070c945 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m index 9bb57ed897ac..0d54cf13c458 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.h index 099ff3be1bd5..a0e09f7b6fe2 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m index 829f87791a07..d2fd2c1c82eb 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart b/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart index 703ba63e5ccc..11f674b197a3 100644 --- a/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart +++ b/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart index 9b61ec002ff9..529950566ccc 100644 --- a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart index deac00658d6b..82549c3b491a 100644 --- a/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart +++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/test/android_google_map_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/android_google_map_test.dart index 2399b7b15eff..e6ac4331a935 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/android_google_map_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/android_google_map_test.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/test/circle_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/circle_updates_test.dart index d61526b2bbeb..d39173197d31 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/circle_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/circle_updates_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart b/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart index 8bc0fbb1d86e..5871745fc1da 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/test/google_map_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/google_map_test.dart index 857344f5ac5e..0718d59a674b 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/google_map_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/google_map_test.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart index 684e8659c4b5..c90c47d0a038 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/test/marker_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/marker_updates_test.dart index ce0da4235c9c..ec3a89b72886 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/marker_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/marker_updates_test.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/test/polygon_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/polygon_updates_test.dart index e187426bf7f6..f4df8ac137ad 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/polygon_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/polygon_updates_test.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/test/polyline_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/polyline_updates_test.dart index 3644f83a1adc..c82693cad9c8 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/polyline_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/polyline_updates_test.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart index 953d85ec85e6..c7f5ef8e8286 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/AUTHORS b/packages/google_maps_flutter/google_maps_flutter_platform_interface/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/AUTHORS +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/LICENSE b/packages/google_maps_flutter/google_maps_flutter_platform_interface/LICENSE index ad33cf3c3ed1..050e2c7cac4f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/LICENSE +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2018 The Chromium Authors. All rights reserved. +Copyright 2018 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/google_maps_flutter_platform_interface.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/google_maps_flutter_platform_interface.dart index cb28b40470fd..3b01002e8d92 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/google_maps_flutter_platform_interface.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/google_maps_flutter_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/events/map_event.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/events/map_event.dart index c462b4b182e2..9afc6db8cb94 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/events/map_event.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/events/map_event.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart index 9d447701fdd8..dee04c92db14 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart index a363fc30f83c..c38a87f5a5c0 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart index cc9887512d0e..0f2192fda1db 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/callbacks.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/callbacks.dart index c20ece5d6c7c..62b535bec08e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/callbacks.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/callbacks.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart index f15254104b0e..a4d762e87f48 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart index c88923a59404..9580a89189b8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart index daf7c918f67a..8d1d9ac7dbb6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle_updates.dart index a0b064b7be2a..b063a6bec0d6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle_updates.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle_updates.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/joint_type.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/joint_type.dart index c7df0b298624..5dc15b394fd8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/joint_type.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/joint_type.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/location.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/location.dart index a719f0bc741f..cd9d0ee6993f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/location.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/location.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart index 1e7932c7cde2..d8cdfdce9f48 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object_updates.dart index 01cf967f54e3..0d94b77b48f4 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object_updates.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object_updates.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart index e493d6cec8cc..014e5515e6cb 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker_updates.dart index 9c96ab63af18..8c0a1336ad32 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker_updates.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker_updates.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/pattern_item.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/pattern_item.dart index f1cd7f4cb8eb..89422a3423ec 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/pattern_item.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/pattern_item.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart index 57438287a156..78e25c1f91cf 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon_updates.dart index 29b74aecbd66..cb5b2a1faf6a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon_updates.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon_updates.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart index 6738bbf2f079..f4d70dc1dcf8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline_updates.dart index 60e0bfe6c7ce..2fddcfe26619 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline_updates.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline_updates.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/screen_coordinate.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/screen_coordinate.dart index af7a951a149c..efbd77942a46 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/screen_coordinate.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/screen_coordinate.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile.dart index bfc322856b5a..4aa07669c2e7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart index 7f7ef09123b0..d430623cdafe 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay_updates.dart index 1436880e9626..914aacdc8393 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay_updates.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay_updates.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_provider.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_provider.dart index abaf38ba719d..eb87bb6bb15d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_provider.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_provider.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart index 9b7da87f2cb0..c49ad7c47171 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/ui.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/ui.dart index 1c030e338353..3490c121acbc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/ui.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/ui.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/circle.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/circle.dart index 18bd31ec7df6..e0374269daea 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/circle.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/circle.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/maps_object.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/maps_object.dart index fa5a7e7591ee..4418638353ce 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/maps_object.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/maps_object.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/marker.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/marker.dart index 057bebdc8b8a..1c112a68ceb9 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/marker.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polygon.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polygon.dart index 050ecafce31f..53e946e11943 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polygon.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polyline.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polyline.dart index 8f4098feedf7..0b163f7b84ee 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polyline.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/tile_overlay.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/tile_overlay.dart index 336f814d329a..9f8c51906abd 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/tile_overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/tile_overlay.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart index 582acea54dd1..be20335e834b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/bitmap_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/bitmap_test.dart index afcf57debef1..81ca300a6955 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/bitmap_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/bitmap_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart index 4774311feb90..aa48b7b74760 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart index 2d1ae8314a94..4f9fc7cca2dd 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart index 673b3c63c59e..252303076a04 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart index 360d86617754..077f823a1e05 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart index 992438fafef1..ddcb693cc217 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart index 0db7d9d33324..f2054c676d41 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart index d985ac30136e..f7f0c285168a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/AUTHORS b/packages/google_maps_flutter/google_maps_flutter_web/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/AUTHORS +++ b/packages/google_maps_flutter/google_maps_flutter_web/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index 0eca5b82d922..11d054a64c42 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart index f0cae1dcdaf6..b33d8ae69205 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart index c83e92dbb79d..a8858bedcdab 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart index 71cf41522d67..e8526d9f314a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart index b1a691d18def..91ad7dfac90f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart index 26db542c60fe..3735bd06a5c8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/test_driver/integration_driver.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/test_driver/integration_driver.dart index 39444c0daa24..dba91905cd68 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/test_driver/integration_driver.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/test_driver/integration_driver.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart index 2ce3923c7ea9..df2d04853c8a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart index 96f9be7aa001..ea24d4d6ab15 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart index c7c33ed1811f..6463c9e11ba1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index 5212679fb5fe..ca15df56cbd0 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index a119f2aab9f2..7ccce3bde370 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart index cb2a8aa238f9..92ee16ad3d49 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart index 30db477ee5f4..c0efc6b5bdda 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart index fea6164515b8..a3128043d575 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart index f4c692d2ee83..3cb5638846df 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart index 5c078ea0aa7a..bb232d0d94a7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart index f8ff2c62191d..cf9de5b36d33 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart index f24ca4b1bb42..9fbcf119100e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui.dart index 27d39b528e51..ec93f431138b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_fake.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_fake.dart index 7f8c2b2c0796..2a8c7f5f5c6e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_fake.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_fake.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_real.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_real.dart index 16654a0fa967..b6c2f8812a1b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_real.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_real.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart index 039cc473db5e..0393cb205200 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/tests_exist_elsewhere_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/tests_exist_elsewhere_test.dart index a8cd22dbe285..ab69a33ba215 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/test/tests_exist_elsewhere_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/tests_exist_elsewhere_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in/AUTHORS b/packages/google_sign_in/google_sign_in/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/google_sign_in/google_sign_in/AUTHORS +++ b/packages/google_sign_in/google_sign_in/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1Activity.java b/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1Activity.java index 5ec19822734c..215136625dc2 100644 --- a/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1Activity.java +++ b/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java b/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java index 3e7250cea0ee..893a13d2379b 100644 --- a/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java +++ b/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java b/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java index f9aa77b30e5d..6ab856eca8bd 100644 --- a/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java +++ b/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/google_sign_in/google_sign_in/example/android/app/src/test/java/io/flutter/plugins/googlesignin/GoogleSignInPluginTests.java b/packages/google_sign_in/google_sign_in/example/android/app/src/test/java/io/flutter/plugins/googlesignin/GoogleSignInPluginTests.java index acc7996ee94b..b2a13a712823 100644 --- a/packages/google_sign_in/google_sign_in/example/android/app/src/test/java/io/flutter/plugins/googlesignin/GoogleSignInPluginTests.java +++ b/packages/google_sign_in/google_sign_in/example/android/app/src/test/java/io/flutter/plugins/googlesignin/GoogleSignInPluginTests.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/project.pbxproj b/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/project.pbxproj index faaaa58070bd..72aaf05b41b2 100644 --- a/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/project.pbxproj @@ -169,7 +169,7 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; diff --git a/packages/google_sign_in/google_sign_in/example/ios/Runner/AppDelegate.h b/packages/google_sign_in/google_sign_in/example/ios/Runner/AppDelegate.h index d9e18e990f2e..31fc381e7066 100644 --- a/packages/google_sign_in/google_sign_in/example/ios/Runner/AppDelegate.h +++ b/packages/google_sign_in/google_sign_in/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in/example/ios/Runner/AppDelegate.m b/packages/google_sign_in/google_sign_in/example/ios/Runner/AppDelegate.m index f08675707182..2147d3d605ac 100644 --- a/packages/google_sign_in/google_sign_in/example/ios/Runner/AppDelegate.m +++ b/packages/google_sign_in/google_sign_in/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in/example/ios/Runner/main.m b/packages/google_sign_in/google_sign_in/example/ios/Runner/main.m index bec320c0bee0..f451b14cb751 100644 --- a/packages/google_sign_in/google_sign_in/example/ios/Runner/main.m +++ b/packages/google_sign_in/google_sign_in/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in/ios/Tests/GoogleSignInPluginTest.m b/packages/google_sign_in/google_sign_in/ios/Tests/GoogleSignInPluginTest.m index f3968a15622e..d00ef82237c0 100644 --- a/packages/google_sign_in/google_sign_in/ios/Tests/GoogleSignInPluginTest.m +++ b/packages/google_sign_in/google_sign_in/ios/Tests/GoogleSignInPluginTest.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_sign_in/google_sign_in/test_driver/integration_test.dart b/packages/google_sign_in/google_sign_in/test_driver/integration_test.dart index abb86f07086a..c85665696a0f 100644 --- a/packages/google_sign_in/google_sign_in/test_driver/integration_test.dart +++ b/packages/google_sign_in/google_sign_in/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020, the Chromium project authors. All rights reserved. +// 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. diff --git a/packages/google_sign_in/google_sign_in_platform_interface/AUTHORS b/packages/google_sign_in/google_sign_in_platform_interface/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/AUTHORS +++ b/packages/google_sign_in/google_sign_in_platform_interface/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/google_sign_in/google_sign_in_platform_interface/LICENSE b/packages/google_sign_in/google_sign_in_platform_interface/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/LICENSE +++ b/packages/google_sign_in/google_sign_in_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart b/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart index 3499558f9114..560b72088978 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart index ea2426159e21..b2718d0f08b0 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/types.dart b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/types.dart index a4c5906723dd..e20d44fae473 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/types.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/types.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/utils.dart b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/utils.dart index f6236d4ca12e..14701897933a 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/utils.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/utils.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in_platform_interface/test/google_sign_in_platform_interface_test.dart b/packages/google_sign_in/google_sign_in_platform_interface/test/google_sign_in_platform_interface_test.dart index e2565d799e1f..e49f6a1074e2 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/test/google_sign_in_platform_interface_test.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/test/google_sign_in_platform_interface_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart b/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart index 9447cd0edfc4..dbc5bb00f17f 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_sign_in/google_sign_in_web/AUTHORS b/packages/google_sign_in/google_sign_in_web/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/google_sign_in/google_sign_in_web/AUTHORS +++ b/packages/google_sign_in/google_sign_in_web/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/auth2_test.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/auth2_test.dart index b80080935d42..0df203f2f4d8 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/auth2_test.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/auth2_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_load_test.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_load_test.dart index e0729bcf9b5e..0e0363bdd760 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_load_test.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_load_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/gapi_mocks.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/gapi_mocks.dart index 9a7d4f403f97..eb77900d27b6 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/gapi_mocks.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/gapi_mocks.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/auth2_init.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/auth2_init.dart index 79d798ad2c85..acda5d525a91 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/auth2_init.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/auth2_init.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/gapi.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/gapi.dart index 42d9a8be262c..587920494692 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/gapi.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/gapi.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/google_user.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/google_user.dart index f8e794ae48a5..98e978641d3d 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/google_user.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/google_user.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/test_iife.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/test_iife.dart index 43a7a044fc1b..277dfa39104a 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/test_iife.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/test_iife.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_utils_test.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_utils_test.dart index e03974a145b7..2b439c9c74fb 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_utils_test.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_utils_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/src/test_utils.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/src/test_utils.dart index 5a6c8906682c..f01c801dcb14 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/src/test_utils.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/src/test_utils.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/test_driver/integration_driver.dart b/packages/google_sign_in/google_sign_in_web/example/test_driver/integration_driver.dart index 39444c0daa24..dba91905cd68 100644 --- a/packages/google_sign_in/google_sign_in_web/example/test_driver/integration_driver.dart +++ b/packages/google_sign_in/google_sign_in_web/example/test_driver/integration_driver.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart b/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart index 41e8106802de..320dad4ea220 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart index f0f886ce7880..d2c00a840597 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart index b2b5c368b6ab..b42486b9fd7f 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/load_gapi.dart b/packages/google_sign_in/google_sign_in_web/lib/src/load_gapi.dart index 0d3e4165227c..5aad2d9c52ba 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/load_gapi.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/load_gapi.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/utils.dart b/packages/google_sign_in/google_sign_in_web/lib/src/utils.dart index 98cb24efaeeb..12cdd0a3162b 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/utils.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/utils.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/image_picker/image_picker/AUTHORS b/packages/image_picker/image_picker/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/image_picker/image_picker/AUTHORS +++ b/packages/image_picker/image_picker/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1Activity.java b/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1Activity.java index 55f3f92eef7c..215fcfdb9212 100644 --- a/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1Activity.java +++ b/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1ActivityTest.java b/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1ActivityTest.java index e7fcd25142ad..34a827eed3ae 100644 --- a/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1ActivityTest.java +++ b/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/project.pbxproj b/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/project.pbxproj index 492dd014ce6d..f9895f0cc06f 100644 --- a/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/image_picker/image_picker/example/ios/Runner.xcodeproj/project.pbxproj @@ -258,7 +258,7 @@ attributes = { DefaultBuildSystemTypeForWorkspace = Original; LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 6801C8352555D726009DAF8D = { CreatedOnToolsVersion = 11.7; diff --git a/packages/image_picker/image_picker/example/ios/Runner/AppDelegate.h b/packages/image_picker/image_picker/example/ios/Runner/AppDelegate.h index d9e18e990f2e..31fc381e7066 100644 --- a/packages/image_picker/image_picker/example/ios/Runner/AppDelegate.h +++ b/packages/image_picker/image_picker/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/image_picker/image_picker/example/ios/Runner/AppDelegate.m b/packages/image_picker/image_picker/example/ios/Runner/AppDelegate.m index a4b51c88eb60..abfe2106b092 100644 --- a/packages/image_picker/image_picker/example/ios/Runner/AppDelegate.m +++ b/packages/image_picker/image_picker/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/image_picker/image_picker/example/ios/Runner/main.m b/packages/image_picker/image_picker/example/ios/Runner/main.m index bec320c0bee0..f451b14cb751 100644 --- a/packages/image_picker/image_picker/example/ios/Runner/main.m +++ b/packages/image_picker/image_picker/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m b/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m index 8be41dc63587..68ca6304e17e 100644 --- a/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m +++ b/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/image_picker/image_picker/example/test_driver/test/integration_test.dart b/packages/image_picker/image_picker/example/test_driver/test/integration_test.dart index 6332de2cfd8d..b02d7d397106 100644 --- a/packages/image_picker/image_picker/example/test_driver/test/integration_test.dart +++ b/packages/image_picker/image_picker/example/test_driver/test/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/image_picker/image_picker/ios/Tests/ImagePickerPluginTests.m b/packages/image_picker/image_picker/ios/Tests/ImagePickerPluginTests.m index c8d5a2bb5368..f34fa7049616 100644 --- a/packages/image_picker/image_picker/ios/Tests/ImagePickerPluginTests.m +++ b/packages/image_picker/image_picker/ios/Tests/ImagePickerPluginTests.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/image_picker/image_picker/ios/Tests/ImagePickerTestImages.h b/packages/image_picker/image_picker/ios/Tests/ImagePickerTestImages.h index 7173e1c455ba..8ba64a4d03b6 100644 --- a/packages/image_picker/image_picker/ios/Tests/ImagePickerTestImages.h +++ b/packages/image_picker/image_picker/ios/Tests/ImagePickerTestImages.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/image_picker/image_picker/ios/Tests/ImagePickerTestImages.m b/packages/image_picker/image_picker/ios/Tests/ImagePickerTestImages.m index 53559f0b637b..536e3b3cba8e 100644 --- a/packages/image_picker/image_picker/ios/Tests/ImagePickerTestImages.m +++ b/packages/image_picker/image_picker/ios/Tests/ImagePickerTestImages.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/image_picker/image_picker/ios/Tests/ImageUtilTests.m b/packages/image_picker/image_picker/ios/Tests/ImageUtilTests.m index 126795f8bdc9..87c8249e78a4 100644 --- a/packages/image_picker/image_picker/ios/Tests/ImageUtilTests.m +++ b/packages/image_picker/image_picker/ios/Tests/ImageUtilTests.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/image_picker/image_picker/ios/Tests/MetaDataUtilTests.m b/packages/image_picker/image_picker/ios/Tests/MetaDataUtilTests.m index 120ba3890a0e..505ccbfecab8 100644 --- a/packages/image_picker/image_picker/ios/Tests/MetaDataUtilTests.m +++ b/packages/image_picker/image_picker/ios/Tests/MetaDataUtilTests.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/image_picker/image_picker/ios/Tests/PhotoAssetUtilTests.m b/packages/image_picker/image_picker/ios/Tests/PhotoAssetUtilTests.m index 7491c907724c..ac408b22c387 100644 --- a/packages/image_picker/image_picker/ios/Tests/PhotoAssetUtilTests.m +++ b/packages/image_picker/image_picker/ios/Tests/PhotoAssetUtilTests.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/image_picker/image_picker_for_web/AUTHORS b/packages/image_picker/image_picker_for_web/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/image_picker/image_picker_for_web/AUTHORS +++ b/packages/image_picker/image_picker_for_web/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/image_picker/image_picker_for_web/LICENSE b/packages/image_picker/image_picker_for_web/LICENSE index 507569823f1b..b257ce7c224c 100644 --- a/packages/image_picker/image_picker_for_web/LICENSE +++ b/packages/image_picker/image_picker_for_web/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019 The Chromium Authors. All rights reserved. +Copyright 2019 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index ccee15066b8c..75e185470d60 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/image_picker/image_picker_for_web/test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/test/image_picker_for_web_test.dart index fcc2c003a10b..aa97170bf800 100644 --- a/packages/image_picker/image_picker_for_web/test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/test/image_picker_for_web_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/image_picker/image_picker_platform_interface/AUTHORS b/packages/image_picker/image_picker_platform_interface/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/image_picker/image_picker_platform_interface/AUTHORS +++ b/packages/image_picker/image_picker_platform_interface/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/image_picker/image_picker_platform_interface/LICENSE b/packages/image_picker/image_picker_platform_interface/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/image_picker/image_picker_platform_interface/LICENSE +++ b/packages/image_picker/image_picker_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/image_picker/image_picker_platform_interface/lib/image_picker_platform_interface.dart b/packages/image_picker/image_picker_platform_interface/lib/image_picker_platform_interface.dart index e46ee58e766b..e04027cbd744 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/image_picker_platform_interface.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/image_picker_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/method_channel/method_channel_image_picker.dart b/packages/image_picker/image_picker_platform_interface/lib/src/method_channel/method_channel_image_picker.dart index 8535f9dfb20e..272a018a3e35 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/method_channel/method_channel_image_picker.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/method_channel/method_channel_image_picker.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/platform_interface/image_picker_platform.dart b/packages/image_picker/image_picker_platform_interface/lib/src/platform_interface/image_picker_platform.dart index 44b85f17f3db..66986d35719f 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/platform_interface/image_picker_platform.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/platform_interface/image_picker_platform.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/camera_device.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/camera_device.dart index 6c70fd451a0e..658adc5f2c7f 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/camera_device.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/camera_device.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/image_source.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/image_source.dart index 37981e3038f1..6676a9dab30b 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/image_source.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/image_source.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart index 39db13951fd1..a6cbeeed5c97 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart index ea1ad9a84606..8e757774042b 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart index 06bc52308095..08c172a98a05 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/lost_data.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/lost_data.dart index 831c7bd6cb15..3bd9a696d035 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/lost_data.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/lost_data.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/picked_file.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/picked_file.dart index 125b1e968740..34fa2f624f0d 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/picked_file.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/picked_file.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/unsupported.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/unsupported.dart index e204604f5a13..25a0a73d49a9 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/unsupported.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/unsupported.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/retrieve_type.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/retrieve_type.dart index cc32be9711c2..3090513b5b8d 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/retrieve_type.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/retrieve_type.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart index 8ea3cfe06de6..c07ac524335e 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/image_picker/image_picker_platform_interface/test/picked_file_html_test.dart b/packages/image_picker/image_picker_platform_interface/test/picked_file_html_test.dart index ee0edbea03e0..00d6e99ec0bf 100644 --- a/packages/image_picker/image_picker_platform_interface/test/picked_file_html_test.dart +++ b/packages/image_picker/image_picker_platform_interface/test/picked_file_html_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/image_picker/image_picker_platform_interface/test/picked_file_io_test.dart b/packages/image_picker/image_picker_platform_interface/test/picked_file_io_test.dart index 28c0886b864e..c721326e17a4 100644 --- a/packages/image_picker/image_picker_platform_interface/test/picked_file_io_test.dart +++ b/packages/image_picker/image_picker_platform_interface/test/picked_file_io_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/AUTHORS b/packages/in_app_purchase/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/in_app_purchase/AUTHORS +++ b/packages/in_app_purchase/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/in_app_purchase/LICENSE b/packages/in_app_purchase/LICENSE index ad33cf3c3ed1..050e2c7cac4f 100644 --- a/packages/in_app_purchase/LICENSE +++ b/packages/in_app_purchase/LICENSE @@ -1,4 +1,4 @@ -Copyright 2018 The Chromium Authors. All rights reserved. +Copyright 2018 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactory.java b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactory.java index b320c17aa992..915a18eee7ac 100644 --- a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactory.java +++ b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactory.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactoryImpl.java b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactoryImpl.java index 9bfddaf57545..38e59321ce8a 100644 --- a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactoryImpl.java +++ b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactoryImpl.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/InAppPurchasePlugin.java b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/InAppPurchasePlugin.java index 65904b12da28..f412b517cf1c 100644 --- a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/InAppPurchasePlugin.java +++ b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/InAppPurchasePlugin.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java index d90fc6040454..1663c39cfa0f 100644 --- a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java +++ b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/PluginPurchaseListener.java b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/PluginPurchaseListener.java index 20ab8ad92e65..04f980429eaf 100644 --- a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/PluginPurchaseListener.java +++ b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/PluginPurchaseListener.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java index f9fc12fbb34e..c7e7e9029ebd 100644 --- a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java +++ b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1Activity.java b/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1Activity.java index f6849a867b0a..dd4ad6db07a7 100644 --- a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1Activity.java +++ b/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1ActivityTest.java b/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1ActivityTest.java index 4b5a14472b4f..165bc4b42c67 100644 --- a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1ActivityTest.java +++ b/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/FlutterActivityTest.java b/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/FlutterActivityTest.java index 15ec0da9958e..eaacdf16282d 100644 --- a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/FlutterActivityTest.java +++ b/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/FlutterActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java index 0befa87e1d05..248e4105b200 100644 --- a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java +++ b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java index 476577d330c8..63f670dc26e1 100644 --- a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java +++ b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/example/ios/Runner.xcodeproj/project.pbxproj b/packages/in_app_purchase/example/ios/Runner.xcodeproj/project.pbxproj index 1065ac201e4a..95b145bc544b 100644 --- a/packages/in_app_purchase/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/in_app_purchase/example/ios/Runner.xcodeproj/project.pbxproj @@ -243,7 +243,7 @@ attributes = { DefaultBuildSystemTypeForWorkspace = Original; LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; diff --git a/packages/in_app_purchase/example/lib/consumable_store.dart b/packages/in_app_purchase/example/lib/consumable_store.dart index 3c2bec95646d..271291ca6eee 100644 --- a/packages/in_app_purchase/example/lib/consumable_store.dart +++ b/packages/in_app_purchase/example/lib/consumable_store.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/example/lib/main.dart b/packages/in_app_purchase/example/lib/main.dart index 32676cf799ea..2172ca3480f5 100644 --- a/packages/in_app_purchase/example/lib/main.dart +++ b/packages/in_app_purchase/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/example/test_driver/test/integration_test.dart b/packages/in_app_purchase/example/test_driver/test/integration_test.dart index 6332de2cfd8d..b02d7d397106 100644 --- a/packages/in_app_purchase/example/test_driver/test/integration_test.dart +++ b/packages/in_app_purchase/example/test_driver/test/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/in_app_purchase/integration_test/in_app_purchase_test.dart b/packages/in_app_purchase/integration_test/in_app_purchase_test.dart index 758d266e7f8b..f7edfb71412c 100644 --- a/packages/in_app_purchase/integration_test/in_app_purchase_test.dart +++ b/packages/in_app_purchase/integration_test/in_app_purchase_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/in_app_purchase/ios/Classes/FIAObjectTranslator.h b/packages/in_app_purchase/ios/Classes/FIAObjectTranslator.h index 5243a391ddaf..383e5440509a 100644 --- a/packages/in_app_purchase/ios/Classes/FIAObjectTranslator.h +++ b/packages/in_app_purchase/ios/Classes/FIAObjectTranslator.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/ios/Classes/FIAObjectTranslator.m b/packages/in_app_purchase/ios/Classes/FIAObjectTranslator.m index f1e5c538cb0e..e54504a67218 100644 --- a/packages/in_app_purchase/ios/Classes/FIAObjectTranslator.m +++ b/packages/in_app_purchase/ios/Classes/FIAObjectTranslator.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.h b/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.h index c5b67756bad0..797e4a6f4216 100644 --- a/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.h +++ b/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.m b/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.m index f6bdf0c4f249..deeed2873b30 100644 --- a/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.m +++ b/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/ios/Classes/FIAPRequestHandler.h b/packages/in_app_purchase/ios/Classes/FIAPRequestHandler.h index 892f5f013cc9..6c75a9fcdf44 100644 --- a/packages/in_app_purchase/ios/Classes/FIAPRequestHandler.h +++ b/packages/in_app_purchase/ios/Classes/FIAPRequestHandler.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/ios/Classes/FIAPRequestHandler.m b/packages/in_app_purchase/ios/Classes/FIAPRequestHandler.m index 5dc2cea2e9db..7172687956bf 100644 --- a/packages/in_app_purchase/ios/Classes/FIAPRequestHandler.m +++ b/packages/in_app_purchase/ios/Classes/FIAPRequestHandler.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.h b/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.h index a27855230adb..4776062aa04c 100644 --- a/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.h +++ b/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.m b/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.m index 8d179aee7ba8..8eed06ce022c 100644 --- a/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.m +++ b/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.h b/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.h index a7c00f18bc37..6974b33fd230 100644 --- a/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.h +++ b/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m b/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m index e9b6bb9b8490..b254e622e69f 100644 --- a/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m +++ b/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m b/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m index 31e0f255034d..7ef757b7c4c5 100644 --- a/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m +++ b/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/ios/Tests/PaymentQueueTest.m b/packages/in_app_purchase/ios/Tests/PaymentQueueTest.m index 07b6bbb42a65..f5248da74635 100644 --- a/packages/in_app_purchase/ios/Tests/PaymentQueueTest.m +++ b/packages/in_app_purchase/ios/Tests/PaymentQueueTest.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/ios/Tests/ProductRequestHandlerTest.m b/packages/in_app_purchase/ios/Tests/ProductRequestHandlerTest.m index 5e214e8c795e..25d11de5f6ad 100644 --- a/packages/in_app_purchase/ios/Tests/ProductRequestHandlerTest.m +++ b/packages/in_app_purchase/ios/Tests/ProductRequestHandlerTest.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/ios/Tests/Stubs.h b/packages/in_app_purchase/ios/Tests/Stubs.h index 630ae2f633dd..f93d41325199 100644 --- a/packages/in_app_purchase/ios/Tests/Stubs.h +++ b/packages/in_app_purchase/ios/Tests/Stubs.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/ios/Tests/Stubs.m b/packages/in_app_purchase/ios/Tests/Stubs.m index 58b77c14127d..640352a82146 100644 --- a/packages/in_app_purchase/ios/Tests/Stubs.m +++ b/packages/in_app_purchase/ios/Tests/Stubs.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/ios/Tests/TranslatorTest.m b/packages/in_app_purchase/ios/Tests/TranslatorTest.m index 135c7f3616f4..e1db3d154310 100644 --- a/packages/in_app_purchase/ios/Tests/TranslatorTest.m +++ b/packages/in_app_purchase/ios/Tests/TranslatorTest.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/billing_client_wrappers.dart b/packages/in_app_purchase/lib/billing_client_wrappers.dart index 127c980c15e6..e8d13e7d2315 100644 --- a/packages/in_app_purchase/lib/billing_client_wrappers.dart +++ b/packages/in_app_purchase/lib/billing_client_wrappers.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/in_app_purchase.dart b/packages/in_app_purchase/lib/in_app_purchase.dart index 5a68075db3e5..b197583614a6 100644 --- a/packages/in_app_purchase/lib/in_app_purchase.dart +++ b/packages/in_app_purchase/lib/in_app_purchase.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart index f14e8dbec6bd..909c4d70b101 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart index 469d71b63637..0b1e96a19d53 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart index 567e8bbd4f2b..2353175b15b4 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart index 7451a24a8b4f..bfaafb7faf08 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/src/channel.dart b/packages/in_app_purchase/lib/src/channel.dart index 5d140e281e7b..9976ea6e23d1 100644 --- a/packages/in_app_purchase/lib/src/channel.dart +++ b/packages/in_app_purchase/lib/src/channel.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart b/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart index e437e7f99cfc..cf0b4df2fbbe 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart b/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart index 83435d23d395..044144e04f24 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart b/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart index 751bab62803c..c53d40914874 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/product_details.dart b/packages/in_app_purchase/lib/src/in_app_purchase/product_details.dart index a3eb79d9a450..0f23c3a8e557 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/product_details.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/product_details.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart b/packages/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart index b4a509055f14..e346c7f42e42 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.dart index ce2c1fad406f..2a20b21eabb7 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart index f17166fbc969..f4a766a9f4c6 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.dart index 9921380e6e96..edf0708b8041 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.dart index d77ea81c2d38..045c2fcd5b07 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_receipt_manager.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_receipt_manager.dart index 16bcb77a2c70..5cab368558a5 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_receipt_manager.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_receipt_manager.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_request_maker.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_request_maker.dart index c22df0a9dbdd..6f143edd50da 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_request_maker.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_request_maker.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/lib/store_kit_wrappers.dart b/packages/in_app_purchase/lib/store_kit_wrappers.dart index 12af4ba0a18f..3b94a17f9ad9 100644 --- a/packages/in_app_purchase/lib/store_kit_wrappers.dart +++ b/packages/in_app_purchase/lib/store_kit_wrappers.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart b/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart index 7ba560257b39..b1bfa7f3b6dd 100644 --- a/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart +++ b/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart b/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart index f97b937c96df..8aeef23cda3b 100644 --- a/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart +++ b/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart b/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart index f7f410a1cd8b..46ec9c602e23 100644 --- a/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart +++ b/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart b/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart index 14383b96774d..9b979e6ef021 100644 --- a/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart +++ b/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart b/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart index 13582736f86f..d29c0e43d9bc 100644 --- a/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart +++ b/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart b/packages/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart index 8df380bc223b..57932cd44af6 100644 --- a/packages/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart +++ b/packages/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/test/store_kit_wrappers/sk_product_test.dart b/packages/in_app_purchase/test/store_kit_wrappers/sk_product_test.dart index 6e1f59bf377e..6508c83bceb1 100644 --- a/packages/in_app_purchase/test/store_kit_wrappers/sk_product_test.dart +++ b/packages/in_app_purchase/test/store_kit_wrappers/sk_product_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/in_app_purchase/test/store_kit_wrappers/sk_test_stub_objects.dart b/packages/in_app_purchase/test/store_kit_wrappers/sk_test_stub_objects.dart index f7d86f5cf59b..7c92a11962fb 100644 --- a/packages/in_app_purchase/test/store_kit_wrappers/sk_test_stub_objects.dart +++ b/packages/in_app_purchase/test/store_kit_wrappers/sk_test_stub_objects.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/in_app_purchase/test/stub_in_app_purchase_platform.dart b/packages/in_app_purchase/test/stub_in_app_purchase_platform.dart index 431d8859d44d..325b48931896 100644 --- a/packages/in_app_purchase/test/stub_in_app_purchase_platform.dart +++ b/packages/in_app_purchase/test/stub_in_app_purchase_platform.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/AUTHORS b/packages/integration_test/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/integration_test/AUTHORS +++ b/packages/integration_test/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/integration_test/LICENSE b/packages/integration_test/LICENSE index 507569823f1b..b257ce7c224c 100644 --- a/packages/integration_test/LICENSE +++ b/packages/integration_test/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019 The Chromium Authors. All rights reserved. +Copyright 2019 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/FlutterTestRunner.java b/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/FlutterTestRunner.java index fc6b99b30f64..3cada2f44a58 100644 --- a/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/FlutterTestRunner.java +++ b/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/FlutterTestRunner.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/IntegrationTestPlugin.java b/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/IntegrationTestPlugin.java index 919eb7add9ba..01adf98ad90d 100644 --- a/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/IntegrationTestPlugin.java +++ b/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/IntegrationTestPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/example/android/app/src/main/java/com/example/e2e_example/EmbedderV1Activity.java b/packages/integration_test/example/android/app/src/main/java/com/example/e2e_example/EmbedderV1Activity.java index 9318e457800d..fedd3626fa80 100644 --- a/packages/integration_test/example/android/app/src/main/java/com/example/e2e_example/EmbedderV1Activity.java +++ b/packages/integration_test/example/android/app/src/main/java/com/example/e2e_example/EmbedderV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/example/ios/Runner.xcodeproj/project.pbxproj b/packages/integration_test/example/ios/Runner.xcodeproj/project.pbxproj index b96fa2fb2618..1028a7d3e995 100644 --- a/packages/integration_test/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/integration_test/example/ios/Runner.xcodeproj/project.pbxproj @@ -231,7 +231,7 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1020; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 769541C723A0351900E5C350 = { CreatedOnToolsVersion = 11.0; diff --git a/packages/integration_test/example/ios/Runner/AppDelegate.h b/packages/integration_test/example/ios/Runner/AppDelegate.h index b7984f089a9c..d53a2aeb21ac 100644 --- a/packages/integration_test/example/ios/Runner/AppDelegate.h +++ b/packages/integration_test/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/example/ios/Runner/AppDelegate.m b/packages/integration_test/example/ios/Runner/AppDelegate.m index 60df7408bded..a1fd21cf937c 100644 --- a/packages/integration_test/example/ios/Runner/AppDelegate.m +++ b/packages/integration_test/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/example/ios/Runner/main.m b/packages/integration_test/example/ios/Runner/main.m index 84022b1644c3..4817030ede8d 100644 --- a/packages/integration_test/example/ios/Runner/main.m +++ b/packages/integration_test/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/example/test_driver/failure.dart b/packages/integration_test/example/test_driver/failure.dart index 02fc55e94a53..a37306392321 100644 --- a/packages/integration_test/example/test_driver/failure.dart +++ b/packages/integration_test/example/test_driver/failure.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/ios/Classes/IntegrationTestIosTest.h b/packages/integration_test/ios/Classes/IntegrationTestIosTest.h index 7c09a1171267..19503385b70e 100644 --- a/packages/integration_test/ios/Classes/IntegrationTestIosTest.h +++ b/packages/integration_test/ios/Classes/IntegrationTestIosTest.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/ios/Classes/IntegrationTestIosTest.m b/packages/integration_test/ios/Classes/IntegrationTestIosTest.m index b3a7602b74b2..78cd0c28bbfb 100644 --- a/packages/integration_test/ios/Classes/IntegrationTestIosTest.m +++ b/packages/integration_test/ios/Classes/IntegrationTestIosTest.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/ios/Classes/IntegrationTestPlugin.h b/packages/integration_test/ios/Classes/IntegrationTestPlugin.h index 6a6171fd16e8..4593e31e1766 100644 --- a/packages/integration_test/ios/Classes/IntegrationTestPlugin.h +++ b/packages/integration_test/ios/Classes/IntegrationTestPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/ios/Classes/IntegrationTestPlugin.m b/packages/integration_test/ios/Classes/IntegrationTestPlugin.m index 5c4d0e6bfb24..51ac0e34562f 100644 --- a/packages/integration_test/ios/Classes/IntegrationTestPlugin.m +++ b/packages/integration_test/ios/Classes/IntegrationTestPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/lib/_callback_io.dart b/packages/integration_test/lib/_callback_io.dart index c1a447e27cab..fe4e400be997 100644 --- a/packages/integration_test/lib/_callback_io.dart +++ b/packages/integration_test/lib/_callback_io.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/lib/_callback_web.dart b/packages/integration_test/lib/_callback_web.dart index 036098148d99..bff8e8a9d31e 100644 --- a/packages/integration_test/lib/_callback_web.dart +++ b/packages/integration_test/lib/_callback_web.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/lib/_extension_io.dart b/packages/integration_test/lib/_extension_io.dart index a8e66fca1900..8f6f8ac8cad1 100644 --- a/packages/integration_test/lib/_extension_io.dart +++ b/packages/integration_test/lib/_extension_io.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/lib/_extension_web.dart b/packages/integration_test/lib/_extension_web.dart index 8bf5950ef74a..b83fc1eb292e 100644 --- a/packages/integration_test/lib/_extension_web.dart +++ b/packages/integration_test/lib/_extension_web.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/lib/common.dart b/packages/integration_test/lib/common.dart index da93b3b51450..15b0c5c0d0cd 100644 --- a/packages/integration_test/lib/common.dart +++ b/packages/integration_test/lib/common.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/lib/integration_test.dart b/packages/integration_test/lib/integration_test.dart index 5a37e88a3c6e..5a070a4fa9ef 100644 --- a/packages/integration_test/lib/integration_test.dart +++ b/packages/integration_test/lib/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/lib/integration_test_driver_extended.dart b/packages/integration_test/lib/integration_test_driver_extended.dart index c423f296c331..613571e26abe 100644 --- a/packages/integration_test/lib/integration_test_driver_extended.dart +++ b/packages/integration_test/lib/integration_test_driver_extended.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/test/binding_fail_test.dart b/packages/integration_test/test/binding_fail_test.dart index d0d5fd423b67..34c4e6c647df 100644 --- a/packages/integration_test/test/binding_fail_test.dart +++ b/packages/integration_test/test/binding_fail_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/test/binding_test.dart b/packages/integration_test/test/binding_test.dart index 10e3c093b140..449eab5525fc 100644 --- a/packages/integration_test/test/binding_test.dart +++ b/packages/integration_test/test/binding_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/test/data/fail_test_script.dart b/packages/integration_test/test/data/fail_test_script.dart index a495a3b3f698..3e2ac31dbd7c 100644 --- a/packages/integration_test/test/data/fail_test_script.dart +++ b/packages/integration_test/test/data/fail_test_script.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/test/data/pass_test_script.dart b/packages/integration_test/test/data/pass_test_script.dart index e31651de74ac..cb5eed12ab07 100644 --- a/packages/integration_test/test/data/pass_test_script.dart +++ b/packages/integration_test/test/data/pass_test_script.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/test/data/pass_then_fail_test_script.dart b/packages/integration_test/test/data/pass_then_fail_test_script.dart index 9116fde266e0..0b0b67821284 100644 --- a/packages/integration_test/test/data/pass_then_fail_test_script.dart +++ b/packages/integration_test/test/data/pass_then_fail_test_script.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/integration_test/test/response_serialization_test.dart b/packages/integration_test/test/response_serialization_test.dart index ee6cacc73a5e..54bd49780a5d 100644 --- a/packages/integration_test/test/response_serialization_test.dart +++ b/packages/integration_test/test/response_serialization_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/ios_platform_images/AUTHORS b/packages/ios_platform_images/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/ios_platform_images/AUTHORS +++ b/packages/ios_platform_images/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/ios_platform_images/LICENSE b/packages/ios_platform_images/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/ios_platform_images/LICENSE +++ b/packages/ios_platform_images/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/ios_platform_images/example/ios/Runner.xcodeproj/project.pbxproj b/packages/ios_platform_images/example/ios/Runner.xcodeproj/project.pbxproj index ba0b25c0015b..5cf073311353 100644 --- a/packages/ios_platform_images/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/ios_platform_images/example/ios/Runner.xcodeproj/project.pbxproj @@ -167,7 +167,7 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1020; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; diff --git a/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.h b/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.h index e53977a3d9cd..8125fb2282ba 100644 --- a/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.h +++ b/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.m b/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.m index 151c418c2f6a..76c54d5c2576 100644 --- a/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.m +++ b/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/ios_platform_images/lib/ios_platform_images.dart b/packages/ios_platform_images/lib/ios_platform_images.dart index d4599be94a64..3c30c4b8fc0c 100644 --- a/packages/ios_platform_images/lib/ios_platform_images.dart +++ b/packages/ios_platform_images/lib/ios_platform_images.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/ios_platform_images/test/ios_platform_images_test.dart b/packages/ios_platform_images/test/ios_platform_images_test.dart index 6ed7714e95c2..bbdf8de57ed5 100644 --- a/packages/ios_platform_images/test/ios_platform_images_test.dart +++ b/packages/ios_platform_images/test/ios_platform_images_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/local_auth/AUTHORS b/packages/local_auth/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/local_auth/AUTHORS +++ b/packages/local_auth/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/local_auth/LICENSE b/packages/local_auth/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/local_auth/LICENSE +++ b/packages/local_auth/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java b/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java index 3a7e2d76ca08..cf4226d4ed26 100644 --- a/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java +++ b/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. package io.flutter.plugins.localauth; diff --git a/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java b/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java index f4c6c168f54d..5df034650f34 100644 --- a/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java +++ b/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/local_auth/example/ios/Runner.xcodeproj/project.pbxproj b/packages/local_auth/example/ios/Runner.xcodeproj/project.pbxproj index 63730d4eb2e3..8960fe4d8af3 100644 --- a/packages/local_auth/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/local_auth/example/ios/Runner.xcodeproj/project.pbxproj @@ -177,7 +177,7 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; diff --git a/packages/local_auth/example/ios/Runner/AppDelegate.h b/packages/local_auth/example/ios/Runner/AppDelegate.h index d9e18e990f2e..31fc381e7066 100644 --- a/packages/local_auth/example/ios/Runner/AppDelegate.h +++ b/packages/local_auth/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/local_auth/example/ios/Runner/AppDelegate.m b/packages/local_auth/example/ios/Runner/AppDelegate.m index f08675707182..2147d3d605ac 100644 --- a/packages/local_auth/example/ios/Runner/AppDelegate.m +++ b/packages/local_auth/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/local_auth/example/lib/main.dart b/packages/local_auth/example/lib/main.dart index 8cdad5b7eed3..7d611a4ea10f 100644 --- a/packages/local_auth/example/lib/main.dart +++ b/packages/local_auth/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/local_auth/integration_test/local_auth_test.dart b/packages/local_auth/integration_test/local_auth_test.dart index d6527c7601e4..5ebaf39cfe58 100644 --- a/packages/local_auth/integration_test/local_auth_test.dart +++ b/packages/local_auth/integration_test/local_auth_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.h b/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.h index 1e9e8c3a2d24..7fc6e568a470 100644 --- a/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.h +++ b/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m b/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m index cda49a7d68c3..f11517ceb691 100644 --- a/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m +++ b/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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 diff --git a/packages/local_auth/lib/auth_strings.dart b/packages/local_auth/lib/auth_strings.dart index 855098b6aba4..c7dc6bdf09f0 100644 --- a/packages/local_auth/lib/auth_strings.dart +++ b/packages/local_auth/lib/auth_strings.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/local_auth/lib/error_codes.dart b/packages/local_auth/lib/error_codes.dart index 3b080c13baf7..4ead02005250 100644 --- a/packages/local_auth/lib/error_codes.dart +++ b/packages/local_auth/lib/error_codes.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/local_auth/lib/local_auth.dart b/packages/local_auth/lib/local_auth.dart index f8a7228bcd8d..cd32b667e140 100644 --- a/packages/local_auth/lib/local_auth.dart +++ b/packages/local_auth/lib/local_auth.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/package_info/AUTHORS b/packages/package_info/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/package_info/AUTHORS +++ b/packages/package_info/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/package_info/LICENSE b/packages/package_info/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/package_info/LICENSE +++ b/packages/package_info/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/package_info/android/src/main/java/io/flutter/plugins/packageinfo/PackageInfoPlugin.java b/packages/package_info/android/src/main/java/io/flutter/plugins/packageinfo/PackageInfoPlugin.java index 645b8dd075c6..1444b1c71148 100644 --- a/packages/package_info/android/src/main/java/io/flutter/plugins/packageinfo/PackageInfoPlugin.java +++ b/packages/package_info/android/src/main/java/io/flutter/plugins/packageinfo/PackageInfoPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/package_info/darwin/Classes/FLTPackageInfoPlugin.m b/packages/package_info/darwin/Classes/FLTPackageInfoPlugin.m index 046f15fec3ea..8207438f794b 100644 --- a/packages/package_info/darwin/Classes/FLTPackageInfoPlugin.m +++ b/packages/package_info/darwin/Classes/FLTPackageInfoPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/EmbedderV1ActivityTest.java b/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/EmbedderV1ActivityTest.java index ab1d2d29635e..aef7d0dbd264 100644 --- a/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/EmbedderV1ActivityTest.java +++ b/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/EmbedderV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/MainActivityTest.java b/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/MainActivityTest.java index 91aad52d4241..f5f95cec3ed1 100644 --- a/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/MainActivityTest.java +++ b/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/MainActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/package_info/example/android/app/src/main/java/io/flutter/plugins/packageinfoexample/EmbedderV1Activity.java b/packages/package_info/example/android/app/src/main/java/io/flutter/plugins/packageinfoexample/EmbedderV1Activity.java index eb669bf16109..d049ed7b4efc 100644 --- a/packages/package_info/example/android/app/src/main/java/io/flutter/plugins/packageinfoexample/EmbedderV1Activity.java +++ b/packages/package_info/example/android/app/src/main/java/io/flutter/plugins/packageinfoexample/EmbedderV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/package_info/example/integration_test/package_info_test.dart b/packages/package_info/example/integration_test/package_info_test.dart index 75bae13cc8f7..ecd75e2687f2 100644 --- a/packages/package_info/example/integration_test/package_info_test.dart +++ b/packages/package_info/example/integration_test/package_info_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/package_info/example/ios/Runner.xcodeproj/project.pbxproj b/packages/package_info/example/ios/Runner.xcodeproj/project.pbxproj index a3c977a0bf14..e1325039d44a 100644 --- a/packages/package_info/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/package_info/example/ios/Runner.xcodeproj/project.pbxproj @@ -177,7 +177,7 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; diff --git a/packages/package_info/example/ios/Runner/AppDelegate.h b/packages/package_info/example/ios/Runner/AppDelegate.h index d9e18e990f2e..31fc381e7066 100644 --- a/packages/package_info/example/ios/Runner/AppDelegate.h +++ b/packages/package_info/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/package_info/example/ios/Runner/AppDelegate.m b/packages/package_info/example/ios/Runner/AppDelegate.m index f08675707182..2147d3d605ac 100644 --- a/packages/package_info/example/ios/Runner/AppDelegate.m +++ b/packages/package_info/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/package_info/example/ios/Runner/main.m b/packages/package_info/example/ios/Runner/main.m index bec320c0bee0..f451b14cb751 100644 --- a/packages/package_info/example/ios/Runner/main.m +++ b/packages/package_info/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/package_info/example/lib/main.dart b/packages/package_info/example/lib/main.dart index 18620617d558..3fa7780fe9bb 100644 --- a/packages/package_info/example/lib/main.dart +++ b/packages/package_info/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/package_info/example/test_driver/integration_test.dart b/packages/package_info/example/test_driver/integration_test.dart index a2977d367f9f..9e813df086c1 100644 --- a/packages/package_info/example/test_driver/integration_test.dart +++ b/packages/package_info/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/package_info/ios/Classes/FLTPackageInfoPlugin.h b/packages/package_info/ios/Classes/FLTPackageInfoPlugin.h index 5f58c82c9446..e6a73bf164c5 100644 --- a/packages/package_info/ios/Classes/FLTPackageInfoPlugin.h +++ b/packages/package_info/ios/Classes/FLTPackageInfoPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/package_info/lib/package_info.dart b/packages/package_info/lib/package_info.dart index 5b7f4e573aa0..7bcd80619037 100644 --- a/packages/package_info/lib/package_info.dart +++ b/packages/package_info/lib/package_info.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/package_info/macos/Classes/FLTPackageInfoPlugin.h b/packages/package_info/macos/Classes/FLTPackageInfoPlugin.h index cb165ad5e41e..b8705ddfc199 100644 --- a/packages/package_info/macos/Classes/FLTPackageInfoPlugin.h +++ b/packages/package_info/macos/Classes/FLTPackageInfoPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/path_provider/path_provider/AUTHORS b/packages/path_provider/path_provider/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/path_provider/path_provider/AUTHORS +++ b/packages/path_provider/path_provider/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart b/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart index cb0b8744c84f..71c138b2dd3e 100644 --- a/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/path_provider/path_provider/example/ios/Runner.xcodeproj/project.pbxproj b/packages/path_provider/path_provider/example/ios/Runner.xcodeproj/project.pbxproj index eb0222a7c9c5..475c9d8f64a4 100644 --- a/packages/path_provider/path_provider/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/path_provider/path_provider/example/ios/Runner.xcodeproj/project.pbxproj @@ -177,7 +177,7 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; diff --git a/packages/path_provider/path_provider/example/ios/Runner/AppDelegate.h b/packages/path_provider/path_provider/example/ios/Runner/AppDelegate.h index d9e18e990f2e..31fc381e7066 100644 --- a/packages/path_provider/path_provider/example/ios/Runner/AppDelegate.h +++ b/packages/path_provider/path_provider/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/path_provider/path_provider/example/ios/Runner/AppDelegate.m b/packages/path_provider/path_provider/example/ios/Runner/AppDelegate.m index a4b51c88eb60..abfe2106b092 100644 --- a/packages/path_provider/path_provider/example/ios/Runner/AppDelegate.m +++ b/packages/path_provider/path_provider/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/path_provider/path_provider/example/ios/Runner/main.m b/packages/path_provider/path_provider/example/ios/Runner/main.m index bec320c0bee0..f451b14cb751 100644 --- a/packages/path_provider/path_provider/example/ios/Runner/main.m +++ b/packages/path_provider/path_provider/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/path_provider/path_provider/example/linux/my_application.h b/packages/path_provider/path_provider/example/linux/my_application.h index abbdf1213815..b3d62442a005 100644 --- a/packages/path_provider/path_provider/example/linux/my_application.h +++ b/packages/path_provider/path_provider/example/linux/my_application.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/path_provider/path_provider/example/test_driver/integration_test.dart b/packages/path_provider/path_provider/example/test_driver/integration_test.dart index a82b5fb51e77..dec1aa55d40e 100644 --- a/packages/path_provider/path_provider/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/path_provider/path_provider/example/windows/runner/flutter_window.cpp b/packages/path_provider/path_provider/example/windows/runner/flutter_window.cpp index dd2e3cca5666..b7d078e4d4a5 100644 --- a/packages/path_provider/path_provider/example/windows/runner/flutter_window.cpp +++ b/packages/path_provider/path_provider/example/windows/runner/flutter_window.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/path_provider/path_provider_linux/AUTHORS b/packages/path_provider/path_provider_linux/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/path_provider/path_provider_linux/AUTHORS +++ b/packages/path_provider/path_provider_linux/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/path_provider/path_provider_linux/LICENSE b/packages/path_provider/path_provider_linux/LICENSE index d7412e0a1e0c..67c7e2c52e46 100644 --- a/packages/path_provider/path_provider_linux/LICENSE +++ b/packages/path_provider/path_provider_linux/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020 The Chromium Authors. All rights reserved. +Copyright 2020 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart b/packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart index 6cd19401cf0e..a4b254145344 100644 --- a/packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart b/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart index a82b5fb51e77..dec1aa55d40e 100644 --- a/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart b/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart index e35b73bf3766..0295ffa2d15a 100644 --- a/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart +++ b/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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 'dart:io'; diff --git a/packages/path_provider/path_provider_linux/test/path_provider_linux_test.dart b/packages/path_provider/path_provider_linux/test/path_provider_linux_test.dart index be831b92211f..5ec530313462 100644 --- a/packages/path_provider/path_provider_linux/test/path_provider_linux_test.dart +++ b/packages/path_provider/path_provider_linux/test/path_provider_linux_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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_test/flutter_test.dart'; diff --git a/packages/path_provider/path_provider_macos/AUTHORS b/packages/path_provider/path_provider_macos/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/path_provider/path_provider_macos/AUTHORS +++ b/packages/path_provider/path_provider_macos/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/path_provider/path_provider_macos/LICENSE b/packages/path_provider/path_provider_macos/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/path_provider/path_provider_macos/LICENSE +++ b/packages/path_provider/path_provider_macos/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/path_provider/path_provider_macos/example/integration_test/path_provider_test.dart b/packages/path_provider/path_provider_macos/example/integration_test/path_provider_test.dart index 10be231d064e..21f757c86e71 100644 --- a/packages/path_provider/path_provider_macos/example/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider_macos/example/integration_test/path_provider_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart b/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart index a82b5fb51e77..dec1aa55d40e 100644 --- a/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/path_provider/path_provider_macos/macos/Classes/PathProviderPlugin.swift b/packages/path_provider/path_provider_macos/macos/Classes/PathProviderPlugin.swift index a1528822893f..8081b89b2ccf 100644 --- a/packages/path_provider/path_provider_macos/macos/Classes/PathProviderPlugin.swift +++ b/packages/path_provider/path_provider_macos/macos/Classes/PathProviderPlugin.swift @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/path_provider/path_provider_platform_interface/AUTHORS b/packages/path_provider/path_provider_platform_interface/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/path_provider/path_provider_platform_interface/AUTHORS +++ b/packages/path_provider/path_provider_platform_interface/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/path_provider/path_provider_platform_interface/LICENSE b/packages/path_provider/path_provider_platform_interface/LICENSE index d7412e0a1e0c..67c7e2c52e46 100644 --- a/packages/path_provider/path_provider_platform_interface/LICENSE +++ b/packages/path_provider/path_provider_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020 The Chromium Authors. All rights reserved. +Copyright 2020 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart b/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart index 1ff2a978c5a4..5b7046bda3d8 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart b/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart index f563b5ed0b2d..fe46401501d4 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart index 728c1068f876..418d983273ea 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart index 7130d7743e69..3f44387f1b7d 100644 --- a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart +++ b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/path_provider/path_provider_windows/AUTHORS b/packages/path_provider/path_provider_windows/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/path_provider/path_provider_windows/AUTHORS +++ b/packages/path_provider/path_provider_windows/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/path_provider/path_provider_windows/LICENSE b/packages/path_provider/path_provider_windows/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/path_provider/path_provider_windows/LICENSE +++ b/packages/path_provider/path_provider_windows/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/path_provider/path_provider_windows/example/integration_test/path_provider_test.dart b/packages/path_provider/path_provider_windows/example/integration_test/path_provider_test.dart index 0d521a5df247..733865b577f0 100644 --- a/packages/path_provider/path_provider_windows/example/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider_windows/example/integration_test/path_provider_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/path_provider/path_provider_windows/example/lib/main.dart b/packages/path_provider/path_provider_windows/example/lib/main.dart index 964ef3d04db1..7d4db2304259 100644 --- a/packages/path_provider/path_provider_windows/example/lib/main.dart +++ b/packages/path_provider/path_provider_windows/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart b/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart index a82b5fb51e77..dec1aa55d40e 100644 --- a/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/path_provider/path_provider_windows/lib/path_provider_windows.dart b/packages/path_provider/path_provider_windows/lib/path_provider_windows.dart index b7aeb7a6d5f6..dbb178242970 100644 --- a/packages/path_provider/path_provider_windows/lib/path_provider_windows.dart +++ b/packages/path_provider/path_provider_windows/lib/path_provider_windows.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/path_provider/path_provider_windows/lib/src/folders.dart b/packages/path_provider/path_provider_windows/lib/src/folders.dart index fc2ea8351476..d1e7ecc767f0 100644 --- a/packages/path_provider/path_provider_windows/lib/src/folders.dart +++ b/packages/path_provider/path_provider_windows/lib/src/folders.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/path_provider/path_provider_windows/lib/src/folders_stub.dart b/packages/path_provider/path_provider_windows/lib/src/folders_stub.dart index d19103602cdc..6dae052246ad 100644 --- a/packages/path_provider/path_provider_windows/lib/src/folders_stub.dart +++ b/packages/path_provider/path_provider_windows/lib/src/folders_stub.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart index db2ad9da207c..23eee59f32fb 100644 --- a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart +++ b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_stub.dart b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_stub.dart index 1a0e84e8f0da..9d71d2258e04 100644 --- a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_stub.dart +++ b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_stub.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/path_provider/path_provider_windows/test/path_provider_windows_test.dart b/packages/path_provider/path_provider_windows/test/path_provider_windows_test.dart index 989f3673ac63..0ca4595fa14e 100644 --- a/packages/path_provider/path_provider_windows/test/path_provider_windows_test.dart +++ b/packages/path_provider/path_provider_windows/test/path_provider_windows_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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 'dart:ffi'; diff --git a/packages/plugin_platform_interface/AUTHORS b/packages/plugin_platform_interface/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/plugin_platform_interface/AUTHORS +++ b/packages/plugin_platform_interface/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/plugin_platform_interface/LICENSE b/packages/plugin_platform_interface/LICENSE index 507569823f1b..b257ce7c224c 100644 --- a/packages/plugin_platform_interface/LICENSE +++ b/packages/plugin_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019 The Chromium Authors. All rights reserved. +Copyright 2019 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/plugin_platform_interface/lib/plugin_platform_interface.dart b/packages/plugin_platform_interface/lib/plugin_platform_interface.dart index 6e425a19a048..187d1fa47b44 100644 --- a/packages/plugin_platform_interface/lib/plugin_platform_interface.dart +++ b/packages/plugin_platform_interface/lib/plugin_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/plugin_platform_interface/test/plugin_platform_interface_test.dart b/packages/plugin_platform_interface/test/plugin_platform_interface_test.dart index 0488c20f3efb..8b5d68f00684 100644 --- a/packages/plugin_platform_interface/test/plugin_platform_interface_test.dart +++ b/packages/plugin_platform_interface/test/plugin_platform_interface_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/quick_actions/AUTHORS b/packages/quick_actions/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/quick_actions/AUTHORS +++ b/packages/quick_actions/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/quick_actions/LICENSE b/packages/quick_actions/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/quick_actions/LICENSE +++ b/packages/quick_actions/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/MethodCallHandlerImpl.java b/packages/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/MethodCallHandlerImpl.java index dcf2390570bd..6d7f79fb7c2d 100644 --- a/packages/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/MethodCallHandlerImpl.java +++ b/packages/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/MethodCallHandlerImpl.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/QuickActionsPlugin.java b/packages/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/QuickActionsPlugin.java index 14e59951cf5e..695ff00a1a67 100644 --- a/packages/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/QuickActionsPlugin.java +++ b/packages/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/QuickActionsPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1Activity.java b/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1Activity.java index 4a77793da48a..db2b2f69609c 100644 --- a/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1Activity.java +++ b/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1ActivityTest.java b/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1ActivityTest.java index e9e9401128a4..16820dfa0f39 100644 --- a/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1ActivityTest.java +++ b/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/FlutterActivityTest.java b/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/FlutterActivityTest.java index 9ce1e8dfe4ea..4eb4033a4f94 100644 --- a/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/FlutterActivityTest.java +++ b/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/FlutterActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/quick_actions/example/integration_test/quick_actions_test.dart b/packages/quick_actions/example/integration_test/quick_actions_test.dart index bad84debefd6..f8841843b016 100644 --- a/packages/quick_actions/example/integration_test/quick_actions_test.dart +++ b/packages/quick_actions/example/integration_test/quick_actions_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/quick_actions/example/ios/Runner.xcodeproj/project.pbxproj b/packages/quick_actions/example/ios/Runner.xcodeproj/project.pbxproj index dba32819ce42..aca645880e15 100644 --- a/packages/quick_actions/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/quick_actions/example/ios/Runner.xcodeproj/project.pbxproj @@ -214,7 +214,7 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 686BE82C25E58CCF00862533 = { CreatedOnToolsVersion = 12.4; diff --git a/packages/quick_actions/example/ios/Runner/AppDelegate.h b/packages/quick_actions/example/ios/Runner/AppDelegate.h index d9e18e990f2e..31fc381e7066 100644 --- a/packages/quick_actions/example/ios/Runner/AppDelegate.h +++ b/packages/quick_actions/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/quick_actions/example/ios/Runner/AppDelegate.m b/packages/quick_actions/example/ios/Runner/AppDelegate.m index f08675707182..2147d3d605ac 100644 --- a/packages/quick_actions/example/ios/Runner/AppDelegate.m +++ b/packages/quick_actions/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/quick_actions/example/ios/Runner/main.m b/packages/quick_actions/example/ios/Runner/main.m index bec320c0bee0..f451b14cb751 100644 --- a/packages/quick_actions/example/ios/Runner/main.m +++ b/packages/quick_actions/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/quick_actions/example/ios/RunnerUITests/RunnerUITests.m b/packages/quick_actions/example/ios/RunnerUITests/RunnerUITests.m index f78081b98a01..dfb8022529d2 100644 --- a/packages/quick_actions/example/ios/RunnerUITests/RunnerUITests.m +++ b/packages/quick_actions/example/ios/RunnerUITests/RunnerUITests.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/quick_actions/example/lib/main.dart b/packages/quick_actions/example/lib/main.dart index 08d8f4a1fbce..4422a520c9ed 100644 --- a/packages/quick_actions/example/lib/main.dart +++ b/packages/quick_actions/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/quick_actions/example/test_driver/integration_test.dart b/packages/quick_actions/example/test_driver/integration_test.dart index 6332de2cfd8d..b02d7d397106 100644 --- a/packages/quick_actions/example/test_driver/integration_test.dart +++ b/packages/quick_actions/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/quick_actions/ios/Classes/FLTQuickActionsPlugin.h b/packages/quick_actions/ios/Classes/FLTQuickActionsPlugin.h index f0ef61d445e9..d170a81a2e58 100644 --- a/packages/quick_actions/ios/Classes/FLTQuickActionsPlugin.h +++ b/packages/quick_actions/ios/Classes/FLTQuickActionsPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/quick_actions/ios/Classes/FLTQuickActionsPlugin.m b/packages/quick_actions/ios/Classes/FLTQuickActionsPlugin.m index c99c016ed1ed..808d4d112b12 100644 --- a/packages/quick_actions/ios/Classes/FLTQuickActionsPlugin.m +++ b/packages/quick_actions/ios/Classes/FLTQuickActionsPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/quick_actions/lib/quick_actions.dart b/packages/quick_actions/lib/quick_actions.dart index 875661244a74..fe95b1d07765 100644 --- a/packages/quick_actions/lib/quick_actions.dart +++ b/packages/quick_actions/lib/quick_actions.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/quick_actions/test/quick_actions_test.dart b/packages/quick_actions/test/quick_actions_test.dart index 8066719e5113..9adcf5628a47 100644 --- a/packages/quick_actions/test/quick_actions_test.dart +++ b/packages/quick_actions/test/quick_actions_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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'; diff --git a/packages/sensors/AUTHORS b/packages/sensors/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/sensors/AUTHORS +++ b/packages/sensors/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/sensors/LICENSE b/packages/sensors/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/sensors/LICENSE +++ b/packages/sensors/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/SensorsPlugin.java b/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/SensorsPlugin.java index e01c80d1cdd2..4aac1a58d6bf 100644 --- a/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/SensorsPlugin.java +++ b/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/SensorsPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/StreamHandlerImpl.java b/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/StreamHandlerImpl.java index ac0546109f96..93fd2e0fbf2b 100644 --- a/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/StreamHandlerImpl.java +++ b/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/StreamHandlerImpl.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1Activity.java b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1Activity.java index 7813e7e8e43f..23390293aeb5 100644 --- a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1Activity.java +++ b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/FlutterActivityTest.java b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/FlutterActivityTest.java index 0835b0f5945a..7f2d79bab028 100644 --- a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/FlutterActivityTest.java +++ b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/FlutterActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/sensors/example/ios/Runner.xcodeproj/project.pbxproj b/packages/sensors/example/ios/Runner.xcodeproj/project.pbxproj index 8bde68c84719..9abd66cff4d8 100644 --- a/packages/sensors/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/sensors/example/ios/Runner.xcodeproj/project.pbxproj @@ -177,7 +177,7 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; diff --git a/packages/sensors/example/lib/main.dart b/packages/sensors/example/lib/main.dart index d6f01380c534..88cc2d7a2750 100644 --- a/packages/sensors/example/lib/main.dart +++ b/packages/sensors/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/sensors/example/lib/snake.dart b/packages/sensors/example/lib/snake.dart index 72f27472dd5b..28610758ca5f 100644 --- a/packages/sensors/example/lib/snake.dart +++ b/packages/sensors/example/lib/snake.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/sensors/example/test_driver/test/integration_test.dart b/packages/sensors/example/test_driver/test/integration_test.dart index c62ef5dba800..ac2a0cf5f19b 100644 --- a/packages/sensors/example/test_driver/test/integration_test.dart +++ b/packages/sensors/example/test_driver/test/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/sensors/integration_test/sensors_test.dart b/packages/sensors/integration_test/sensors_test.dart index 5ae15967d8e4..ecee934b799a 100644 --- a/packages/sensors/integration_test/sensors_test.dart +++ b/packages/sensors/integration_test/sensors_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/sensors/ios/Classes/FLTSensorsPlugin.h b/packages/sensors/ios/Classes/FLTSensorsPlugin.h index 288db1901ed2..c3eaa137d065 100644 --- a/packages/sensors/ios/Classes/FLTSensorsPlugin.h +++ b/packages/sensors/ios/Classes/FLTSensorsPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/sensors/ios/Classes/FLTSensorsPlugin.m b/packages/sensors/ios/Classes/FLTSensorsPlugin.m index ba8d542f488e..d3541337280a 100644 --- a/packages/sensors/ios/Classes/FLTSensorsPlugin.m +++ b/packages/sensors/ios/Classes/FLTSensorsPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/sensors/lib/sensors.dart b/packages/sensors/lib/sensors.dart index 8f69255bcec7..3309f1b20453 100644 --- a/packages/sensors/lib/sensors.dart +++ b/packages/sensors/lib/sensors.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/sensors/test/sensors_test.dart b/packages/sensors/test/sensors_test.dart index fe56c7e5a36f..89856279ff16 100644 --- a/packages/sensors/test/sensors_test.dart +++ b/packages/sensors/test/sensors_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/share/AUTHORS b/packages/share/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/share/AUTHORS +++ b/packages/share/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1Activity.java b/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1Activity.java index d14e39781c2b..32c382f656f8 100644 --- a/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1Activity.java +++ b/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/FlutterActivityTest.java b/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/FlutterActivityTest.java index 3b73737f15b2..9767b63e7799 100644 --- a/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/FlutterActivityTest.java +++ b/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/FlutterActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/share/example/ios/Runner.xcodeproj/project.pbxproj b/packages/share/example/ios/Runner.xcodeproj/project.pbxproj index d03ef3e65776..956735eafeab 100644 --- a/packages/share/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/share/example/ios/Runner.xcodeproj/project.pbxproj @@ -214,7 +214,7 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 683426AA2538D314009B194C = { CreatedOnToolsVersion = 11.7; diff --git a/packages/share/example/ios/Runner/AppDelegate.h b/packages/share/example/ios/Runner/AppDelegate.h index d9e18e990f2e..31fc381e7066 100644 --- a/packages/share/example/ios/Runner/AppDelegate.h +++ b/packages/share/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/share/example/ios/Runner/AppDelegate.m b/packages/share/example/ios/Runner/AppDelegate.m index a4b51c88eb60..abfe2106b092 100644 --- a/packages/share/example/ios/Runner/AppDelegate.m +++ b/packages/share/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/share/example/ios/Runner/main.m b/packages/share/example/ios/Runner/main.m index bec320c0bee0..f451b14cb751 100644 --- a/packages/share/example/ios/Runner/main.m +++ b/packages/share/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/share/example/ios/RunnerUITests/FLTShareExampleUITests.m b/packages/share/example/ios/RunnerUITests/FLTShareExampleUITests.m index 8e18d03ba354..05966fb439f1 100644 --- a/packages/share/example/ios/RunnerUITests/FLTShareExampleUITests.m +++ b/packages/share/example/ios/RunnerUITests/FLTShareExampleUITests.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/share/example/test_driver/test/integration_test.dart b/packages/share/example/test_driver/test/integration_test.dart index c62ef5dba800..ac2a0cf5f19b 100644 --- a/packages/share/example/test_driver/test/integration_test.dart +++ b/packages/share/example/test_driver/test/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/share/integration_test/share_test.dart b/packages/share/integration_test/share_test.dart index a6a2ddb4f7cd..4fdfc220c9cc 100644 --- a/packages/share/integration_test/share_test.dart +++ b/packages/share/integration_test/share_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/shared_preferences/shared_preferences/AUTHORS b/packages/shared_preferences/shared_preferences/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/shared_preferences/shared_preferences/AUTHORS +++ b/packages/shared_preferences/shared_preferences/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/shared_preferences/shared_preferences/LICENSE b/packages/shared_preferences/shared_preferences/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/shared_preferences/shared_preferences/LICENSE +++ b/packages/shared_preferences/shared_preferences/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java index 4486421e3959..7955f2f89afb 100644 --- a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java +++ b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java index 83163f82d9ec..3583f3b73cb7 100644 --- a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java +++ b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart index d36286a559b3..daa2cbba1670 100644 --- a/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner.xcodeproj/project.pbxproj b/packages/shared_preferences/shared_preferences/example/ios/Runner.xcodeproj/project.pbxproj index 2adc7021c6bf..e26da81f1166 100644 --- a/packages/shared_preferences/shared_preferences/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner.xcodeproj/project.pbxproj @@ -177,7 +177,7 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.h b/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.h index d9e18e990f2e..31fc381e7066 100644 --- a/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.h +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.m b/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.m index a4b51c88eb60..abfe2106b092 100644 --- a/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.m +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner/Runner-Bridging-Header.h b/packages/shared_preferences/shared_preferences/example/ios/Runner/Runner-Bridging-Header.h index 0592e2dd559c..3a69a7befa44 100644 --- a/packages/shared_preferences/shared_preferences/example/ios/Runner/Runner-Bridging-Header.h +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner/Runner-Bridging-Header.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner/main.m b/packages/shared_preferences/shared_preferences/example/ios/Runner/main.m index bec320c0bee0..f451b14cb751 100644 --- a/packages/shared_preferences/shared_preferences/example/ios/Runner/main.m +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/example/lib/main.dart b/packages/shared_preferences/shared_preferences/example/lib/main.dart index 26e6c8eb42f8..a56deb276037 100644 --- a/packages/shared_preferences/shared_preferences/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/example/linux/my_application.h b/packages/shared_preferences/shared_preferences/example/linux/my_application.h index abbdf1213815..b3d62442a005 100644 --- a/packages/shared_preferences/shared_preferences/example/linux/my_application.h +++ b/packages/shared_preferences/shared_preferences/example/linux/my_application.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/example/test_driver/integration_test.dart b/packages/shared_preferences/shared_preferences/example/test_driver/integration_test.dart index a82b5fb51e77..dec1aa55d40e 100644 --- a/packages/shared_preferences/shared_preferences/example/test_driver/integration_test.dart +++ b/packages/shared_preferences/shared_preferences/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.cpp b/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.cpp index dd2e3cca5666..b7d078e4d4a5 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.cpp +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.h b/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.h index a9d273e419eb..9b4ef089621b 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.h +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/main.cpp b/packages/shared_preferences/shared_preferences/example/windows/runner/main.cpp index 40492ac76edb..e74157ed999a 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/main.cpp +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/main.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.cpp b/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.cpp index 4dd13b6d1db9..ee2e2fd5eae9 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.cpp +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.h b/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.h index 12aaab42c59b..a24c47f2e55f 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.h +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/utils.cpp b/packages/shared_preferences/shared_preferences/example/windows/runner/utils.cpp index c408cb3f7a74..9eba364025d0 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/utils.cpp +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/utils.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/utils.h b/packages/shared_preferences/shared_preferences/example/windows/runner/utils.h index 2754c7a7f9ef..640587eb23ab 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/utils.h +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/utils.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.cpp b/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.cpp index 878b64afe276..97628170c2c2 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.cpp +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.h b/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.h index 99e24a555afa..59b78382b27d 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.h +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/ios/Classes/FLTSharedPreferencesPlugin.h b/packages/shared_preferences/shared_preferences/ios/Classes/FLTSharedPreferencesPlugin.h index 6bb1d5eecbeb..d77611fde7b4 100644 --- a/packages/shared_preferences/shared_preferences/ios/Classes/FLTSharedPreferencesPlugin.h +++ b/packages/shared_preferences/shared_preferences/ios/Classes/FLTSharedPreferencesPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/ios/Classes/FLTSharedPreferencesPlugin.m b/packages/shared_preferences/shared_preferences/ios/Classes/FLTSharedPreferencesPlugin.m index dd68fb5b98c4..77d53504b4d3 100644 --- a/packages/shared_preferences/shared_preferences/ios/Classes/FLTSharedPreferencesPlugin.m +++ b/packages/shared_preferences/shared_preferences/ios/Classes/FLTSharedPreferencesPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart b/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart index 2f4ebe730351..6ed771e87c53 100644 --- a/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart +++ b/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart index 7866b2e38fac..412285ed4fd3 100755 --- a/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_linux/AUTHORS b/packages/shared_preferences/shared_preferences_linux/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/shared_preferences/shared_preferences_linux/AUTHORS +++ b/packages/shared_preferences/shared_preferences_linux/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/shared_preferences/shared_preferences_linux/LICENSE b/packages/shared_preferences/shared_preferences_linux/LICENSE index d7412e0a1e0c..67c7e2c52e46 100644 --- a/packages/shared_preferences/shared_preferences_linux/LICENSE +++ b/packages/shared_preferences/shared_preferences_linux/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020 The Chromium Authors. All rights reserved. +Copyright 2020 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart index 019dc248a918..a8e52ccc3063 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_linux/example/lib/main.dart b/packages/shared_preferences/shared_preferences_linux/example/lib/main.dart index ab664cd652ff..0f6d7fc49f7e 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences_linux/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.h b/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.h index d1c3f9c4fb0b..5d666ca73bec 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.h +++ b/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.h @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/shared_preferences/shared_preferences_linux/example/test_driver/integration_test.dart b/packages/shared_preferences/shared_preferences_linux/example/test_driver/integration_test.dart index a82b5fb51e77..dec1aa55d40e 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/test_driver/integration_test.dart +++ b/packages/shared_preferences/shared_preferences_linux/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart b/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart index 5a694658cdf5..6252da4668c9 100644 --- a/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart +++ b/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart b/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart index cf0bc80e3ec2..98260302b778 100644 --- a/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart +++ b/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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:file/memory.dart'; diff --git a/packages/shared_preferences/shared_preferences_macos/AUTHORS b/packages/shared_preferences/shared_preferences_macos/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/shared_preferences/shared_preferences_macos/AUTHORS +++ b/packages/shared_preferences/shared_preferences_macos/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/shared_preferences/shared_preferences_macos/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_macos/example/integration_test/shared_preferences_test.dart index 94dee2d73c9d..53d3cfdf3bc5 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_macos/example/integration_test/shared_preferences_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017, the Chromium project authors. All rights reserved. +// Copyright 2017, 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. diff --git a/packages/shared_preferences/shared_preferences_macos/example/lib/main.dart b/packages/shared_preferences/shared_preferences_macos/example/lib/main.dart index f1058cddd63b..388f2389bf5b 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences_macos/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_macos/example/test_driver/integration_test.dart b/packages/shared_preferences/shared_preferences_macos/example/test_driver/integration_test.dart index a82b5fb51e77..dec1aa55d40e 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/test_driver/integration_test.dart +++ b/packages/shared_preferences/shared_preferences_macos/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/shared_preferences/shared_preferences_macos/macos/Classes/SharedPreferencesPlugin.swift b/packages/shared_preferences/shared_preferences_macos/macos/Classes/SharedPreferencesPlugin.swift index 8f7f58ece635..19a420d002a4 100644 --- a/packages/shared_preferences/shared_preferences_macos/macos/Classes/SharedPreferencesPlugin.swift +++ b/packages/shared_preferences/shared_preferences_macos/macos/Classes/SharedPreferencesPlugin.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_platform_interface/AUTHORS b/packages/shared_preferences/shared_preferences_platform_interface/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/AUTHORS +++ b/packages/shared_preferences/shared_preferences_platform_interface/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/shared_preferences/shared_preferences_platform_interface/LICENSE b/packages/shared_preferences/shared_preferences_platform_interface/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/LICENSE +++ b/packages/shared_preferences/shared_preferences_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/shared_preferences/shared_preferences_platform_interface/lib/method_channel_shared_preferences.dart b/packages/shared_preferences/shared_preferences_platform_interface/lib/method_channel_shared_preferences.dart index c02c537adcbd..47004b198175 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/lib/method_channel_shared_preferences.dart +++ b/packages/shared_preferences/shared_preferences_platform_interface/lib/method_channel_shared_preferences.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_platform_interface.dart b/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_platform_interface.dart index cf194f82c267..f330b04cd30c 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_platform_interface.dart +++ b/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_platform_interface/test/method_channel_shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_platform_interface/test/method_channel_shared_preferences_test.dart index d828126168ba..3225090e5b51 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/test/method_channel_shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_platform_interface/test/method_channel_shared_preferences_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_platform_interface/test/shared_preferences_platform_interface_test.dart b/packages/shared_preferences/shared_preferences_platform_interface/test/shared_preferences_platform_interface_test.dart index 9e957734d174..a1c4ca9219aa 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/test/shared_preferences_platform_interface_test.dart +++ b/packages/shared_preferences/shared_preferences_platform_interface/test/shared_preferences_platform_interface_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_web/LICENSE b/packages/shared_preferences/shared_preferences_web/LICENSE index 507569823f1b..b257ce7c224c 100644 --- a/packages/shared_preferences/shared_preferences_web/LICENSE +++ b/packages/shared_preferences/shared_preferences_web/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019 The Chromium Authors. All rights reserved. +Copyright 2019 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart b/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart index 346877e8a120..7d5292a54db1 100644 --- a/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart +++ b/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_web/test/shared_preferences_web_test.dart b/packages/shared_preferences/shared_preferences_web/test/shared_preferences_web_test.dart index c0cf92cc1bf0..b1275330e3a7 100644 --- a/packages/shared_preferences/shared_preferences_web/test/shared_preferences_web_test.dart +++ b/packages/shared_preferences/shared_preferences_web/test/shared_preferences_web_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_windows/AUTHORS b/packages/shared_preferences/shared_preferences_windows/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/shared_preferences/shared_preferences_windows/AUTHORS +++ b/packages/shared_preferences/shared_preferences_windows/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/shared_preferences/shared_preferences_windows/LICENSE b/packages/shared_preferences/shared_preferences_windows/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/shared_preferences/shared_preferences_windows/LICENSE +++ b/packages/shared_preferences/shared_preferences_windows/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/shared_preferences/shared_preferences_windows/example/LICENSE b/packages/shared_preferences/shared_preferences_windows/example/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/LICENSE +++ b/packages/shared_preferences/shared_preferences_windows/example/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart index 41fc5dbf8b2a..16f17cf71094 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017, the Chromium project authors. All rights reserved. +// Copyright 2017, 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart b/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart index f0dc155aee4a..96c2490a60ee 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/test_driver/integration_test.dart b/packages/shared_preferences/shared_preferences_windows/example/test_driver/integration_test.dart index 5504f8c79080..f41cb47e07a2 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/test_driver/integration_test.dart +++ b/packages/shared_preferences/shared_preferences_windows/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017, the Chromium project authors. All rights reserved. +// Copyright 2017, 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.cpp b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.cpp index dd2e3cca5666..b7d078e4d4a5 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.cpp +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.h b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.h index a9d273e419eb..9b4ef089621b 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.h +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/main.cpp b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/main.cpp index 40492ac76edb..e74157ed999a 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/main.cpp +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/main.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.cpp b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.cpp index 4dd13b6d1db9..ee2e2fd5eae9 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.cpp +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.h b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.h index 12aaab42c59b..a24c47f2e55f 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.h +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.cpp b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.cpp index c408cb3f7a74..9eba364025d0 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.cpp +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.h b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.h index 2754c7a7f9ef..640587eb23ab 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.h +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.cpp b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.cpp index 878b64afe276..97628170c2c2 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.cpp +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.h b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.h index 99e24a555afa..59b78382b27d 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.h +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart index b2678c49782b..04efce9946d4 100644 --- a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart +++ b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart b/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart index 785092f6fa16..a78dce207c09 100644 --- a/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart +++ b/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/url_launcher/url_launcher/AUTHORS b/packages/url_launcher/url_launcher/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/url_launcher/url_launcher/AUTHORS +++ b/packages/url_launcher/url_launcher/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/url_launcher/url_launcher/LICENSE b/packages/url_launcher/url_launcher/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/url_launcher/url_launcher/LICENSE +++ b/packages/url_launcher/url_launcher/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/MethodCallHandlerImpl.java b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/MethodCallHandlerImpl.java index 7a4b37488e69..7b858fbafdb3 100644 --- a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/MethodCallHandlerImpl.java +++ b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/MethodCallHandlerImpl.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java index a6f29e1af68d..b6446458322b 100644 --- a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java +++ b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java index 79198200c526..cafc7a65c04b 100644 --- a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java +++ b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java index 160e24e331d3..53b2e8a44479 100644 --- a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java +++ b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher/android/src/test/java/io/flutter/plugins/urllauncher/MethodCallHandlerImplTest.java b/packages/url_launcher/url_launcher/android/src/test/java/io/flutter/plugins/urllauncher/MethodCallHandlerImplTest.java index e9d27e3e3b01..0055659c5fc0 100644 --- a/packages/url_launcher/url_launcher/android/src/test/java/io/flutter/plugins/urllauncher/MethodCallHandlerImplTest.java +++ b/packages/url_launcher/url_launcher/android/src/test/java/io/flutter/plugins/urllauncher/MethodCallHandlerImplTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher/example/android/app/src/main/java/io/flutter/plugins/urllauncherexample/EmbeddingV1Activity.java b/packages/url_launcher/url_launcher/example/android/app/src/main/java/io/flutter/plugins/urllauncherexample/EmbeddingV1Activity.java index 9fd4871c0711..a005c452d426 100644 --- a/packages/url_launcher/url_launcher/example/android/app/src/main/java/io/flutter/plugins/urllauncherexample/EmbeddingV1Activity.java +++ b/packages/url_launcher/url_launcher/example/android/app/src/main/java/io/flutter/plugins/urllauncherexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher/example/integration_test/url_launcher_test.dart index 9e7b04b38b46..62343c6dc689 100644 --- a/packages/url_launcher/url_launcher/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher/example/integration_test/url_launcher_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/url_launcher/url_launcher/example/ios/Runner.xcodeproj/project.pbxproj b/packages/url_launcher/url_launcher/example/ios/Runner.xcodeproj/project.pbxproj index db72809a6169..de3d24772fb4 100644 --- a/packages/url_launcher/url_launcher/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/url_launcher/url_launcher/example/ios/Runner.xcodeproj/project.pbxproj @@ -177,7 +177,7 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; diff --git a/packages/url_launcher/url_launcher/example/ios/Runner/AppDelegate.h b/packages/url_launcher/url_launcher/example/ios/Runner/AppDelegate.h index d9e18e990f2e..31fc381e7066 100644 --- a/packages/url_launcher/url_launcher/example/ios/Runner/AppDelegate.h +++ b/packages/url_launcher/url_launcher/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher/example/ios/Runner/AppDelegate.m b/packages/url_launcher/url_launcher/example/ios/Runner/AppDelegate.m index 9cf1c7796c6a..07cf6cb9b49f 100644 --- a/packages/url_launcher/url_launcher/example/ios/Runner/AppDelegate.m +++ b/packages/url_launcher/url_launcher/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher/example/ios/Runner/main.m b/packages/url_launcher/url_launcher/example/ios/Runner/main.m index bec320c0bee0..f451b14cb751 100644 --- a/packages/url_launcher/url_launcher/example/ios/Runner/main.m +++ b/packages/url_launcher/url_launcher/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher/example/lib/main.dart b/packages/url_launcher/url_launcher/example/lib/main.dart index 0b310490d0e9..8af62ed7859e 100644 --- a/packages/url_launcher/url_launcher/example/lib/main.dart +++ b/packages/url_launcher/url_launcher/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher/example/test_driver/integration_test.dart b/packages/url_launcher/url_launcher/example/test_driver/integration_test.dart index 3e3caf844689..f044c8de676e 100644 --- a/packages/url_launcher/url_launcher/example/test_driver/integration_test.dart +++ b/packages/url_launcher/url_launcher/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.h b/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.h index 7ce28f598082..35eade666e15 100644 --- a/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.h +++ b/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.m b/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.m index ac05417473a3..bbcfdfdc949c 100644 --- a/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.m +++ b/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher/lib/link.dart b/packages/url_launcher/url_launcher/lib/link.dart index ac1d4064d10f..cdcc2ee1a016 100644 --- a/packages/url_launcher/url_launcher/lib/link.dart +++ b/packages/url_launcher/url_launcher/lib/link.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher/lib/src/link.dart b/packages/url_launcher/url_launcher/lib/src/link.dart index 14fdc9055d7a..e614c2200b02 100644 --- a/packages/url_launcher/url_launcher/lib/src/link.dart +++ b/packages/url_launcher/url_launcher/lib/src/link.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher/lib/url_launcher.dart b/packages/url_launcher/url_launcher/lib/url_launcher.dart index 35833de18738..1a3ac40ce5e2 100644 --- a/packages/url_launcher/url_launcher/lib/url_launcher.dart +++ b/packages/url_launcher/url_launcher/lib/url_launcher.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher/test/link_test.dart b/packages/url_launcher/url_launcher/test/link_test.dart index 8da5111f5733..02678a3559dd 100644 --- a/packages/url_launcher/url_launcher/test/link_test.dart +++ b/packages/url_launcher/url_launcher/test/link_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher/test/mock_url_launcher_platform.dart b/packages/url_launcher/url_launcher/test/mock_url_launcher_platform.dart index 87ae99e81024..6d862844e1d0 100644 --- a/packages/url_launcher/url_launcher/test/mock_url_launcher_platform.dart +++ b/packages/url_launcher/url_launcher/test/mock_url_launcher_platform.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher/test/url_launcher_test.dart b/packages/url_launcher/url_launcher/test/url_launcher_test.dart index 9fb16019a543..89eb259e2fa9 100644 --- a/packages/url_launcher/url_launcher/test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher/test/url_launcher_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher_linux/AUTHORS b/packages/url_launcher/url_launcher_linux/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/url_launcher/url_launcher_linux/AUTHORS +++ b/packages/url_launcher/url_launcher_linux/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/url_launcher/url_launcher_linux/LICENSE b/packages/url_launcher/url_launcher_linux/LICENSE index d7412e0a1e0c..67c7e2c52e46 100644 --- a/packages/url_launcher/url_launcher_linux/LICENSE +++ b/packages/url_launcher/url_launcher_linux/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020 The Chromium Authors. All rights reserved. +Copyright 2020 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/url_launcher/url_launcher_linux/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_linux/example/integration_test/url_launcher_test.dart index aa668ed747b5..b14cc943c90d 100644 --- a/packages/url_launcher/url_launcher_linux/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_linux/example/integration_test/url_launcher_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/url_launcher/url_launcher_linux/example/lib/main.dart b/packages/url_launcher/url_launcher_linux/example/lib/main.dart index f49e9fa290c5..e6e027b4a6ba 100644 --- a/packages/url_launcher/url_launcher_linux/example/lib/main.dart +++ b/packages/url_launcher/url_launcher_linux/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher_linux/example/test_driver/integration_test.dart b/packages/url_launcher/url_launcher_linux/example/test_driver/integration_test.dart index c62ef5dba800..ac2a0cf5f19b 100644 --- a/packages/url_launcher/url_launcher_linux/example/test_driver/integration_test.dart +++ b/packages/url_launcher/url_launcher_linux/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/url_launcher/url_launcher_linux/linux/include/url_launcher_linux/url_launcher_plugin.h b/packages/url_launcher/url_launcher_linux/linux/include/url_launcher_linux/url_launcher_plugin.h index efcfe62e706a..399bde268919 100644 --- a/packages/url_launcher/url_launcher_linux/linux/include/url_launcher_linux/url_launcher_plugin.h +++ b/packages/url_launcher/url_launcher_linux/linux/include/url_launcher_linux/url_launcher_plugin.h @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/url_launcher/url_launcher_linux/linux/url_launcher_plugin.cc b/packages/url_launcher/url_launcher_linux/linux/url_launcher_plugin.cc index 8ef1a8aedbc2..17431d1c2f81 100644 --- a/packages/url_launcher/url_launcher_linux/linux/url_launcher_plugin.cc +++ b/packages/url_launcher/url_launcher_linux/linux/url_launcher_plugin.cc @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/url_launcher/url_launcher_macos/AUTHORS b/packages/url_launcher/url_launcher_macos/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/url_launcher/url_launcher_macos/AUTHORS +++ b/packages/url_launcher/url_launcher_macos/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/url_launcher/url_launcher_macos/LICENSE b/packages/url_launcher/url_launcher_macos/LICENSE index 507569823f1b..b257ce7c224c 100644 --- a/packages/url_launcher/url_launcher_macos/LICENSE +++ b/packages/url_launcher/url_launcher_macos/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019 The Chromium Authors. All rights reserved. +Copyright 2019 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/url_launcher/url_launcher_macos/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_macos/example/integration_test/url_launcher_test.dart index 6775a637f7dc..ade3da82700d 100644 --- a/packages/url_launcher/url_launcher_macos/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_macos/example/integration_test/url_launcher_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/url_launcher/url_launcher_macos/example/lib/main.dart b/packages/url_launcher/url_launcher_macos/example/lib/main.dart index f49e9fa290c5..e6e027b4a6ba 100644 --- a/packages/url_launcher/url_launcher_macos/example/lib/main.dart +++ b/packages/url_launcher/url_launcher_macos/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher_macos/example/test_driver/integration_test.dart b/packages/url_launcher/url_launcher_macos/example/test_driver/integration_test.dart index c62ef5dba800..ac2a0cf5f19b 100644 --- a/packages/url_launcher/url_launcher_macos/example/test_driver/integration_test.dart +++ b/packages/url_launcher/url_launcher_macos/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/url_launcher/url_launcher_macos/macos/Classes/UrlLauncherPlugin.swift b/packages/url_launcher/url_launcher_macos/macos/Classes/UrlLauncherPlugin.swift index 916f5c9aa22f..46df87a34304 100644 --- a/packages/url_launcher/url_launcher_macos/macos/Classes/UrlLauncherPlugin.swift +++ b/packages/url_launcher/url_launcher_macos/macos/Classes/UrlLauncherPlugin.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher_platform_interface/AUTHORS b/packages/url_launcher/url_launcher_platform_interface/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/url_launcher/url_launcher_platform_interface/AUTHORS +++ b/packages/url_launcher/url_launcher_platform_interface/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/url_launcher/url_launcher_platform_interface/LICENSE b/packages/url_launcher/url_launcher_platform_interface/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/url_launcher/url_launcher_platform_interface/LICENSE +++ b/packages/url_launcher/url_launcher_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/url_launcher/url_launcher_platform_interface/lib/link.dart b/packages/url_launcher/url_launcher_platform_interface/lib/link.dart index a176972e06bd..6c1a13b604a8 100644 --- a/packages/url_launcher/url_launcher_platform_interface/lib/link.dart +++ b/packages/url_launcher/url_launcher_platform_interface/lib/link.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher_platform_interface/lib/method_channel_url_launcher.dart b/packages/url_launcher/url_launcher_platform_interface/lib/method_channel_url_launcher.dart index 7b9dfc9cc5cf..93fdaff7ea1b 100644 --- a/packages/url_launcher/url_launcher_platform_interface/lib/method_channel_url_launcher.dart +++ b/packages/url_launcher/url_launcher_platform_interface/lib/method_channel_url_launcher.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher_platform_interface/lib/url_launcher_platform_interface.dart b/packages/url_launcher/url_launcher_platform_interface/lib/url_launcher_platform_interface.dart index 2a4edfa8d1af..d34ce7512afb 100644 --- a/packages/url_launcher/url_launcher_platform_interface/lib/url_launcher_platform_interface.dart +++ b/packages/url_launcher/url_launcher_platform_interface/lib/url_launcher_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher_platform_interface/test/link_test.dart b/packages/url_launcher/url_launcher_platform_interface/test/link_test.dart index a01637e2f378..e60cc25f25fe 100644 --- a/packages/url_launcher/url_launcher_platform_interface/test/link_test.dart +++ b/packages/url_launcher/url_launcher_platform_interface/test/link_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher_platform_interface/test/method_channel_url_launcher_test.dart b/packages/url_launcher/url_launcher_platform_interface/test/method_channel_url_launcher_test.dart index b5a96b18c91a..3e450e83e41b 100644 --- a/packages/url_launcher/url_launcher_platform_interface/test/method_channel_url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_platform_interface/test/method_channel_url_launcher_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher_web/AUTHORS b/packages/url_launcher/url_launcher_web/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/url_launcher/url_launcher_web/AUTHORS +++ b/packages/url_launcher/url_launcher_web/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/url_launcher/url_launcher_web/LICENSE b/packages/url_launcher/url_launcher_web/LICENSE index 46b9e8c222d7..b66343316afd 100644 --- a/packages/url_launcher/url_launcher_web/LICENSE +++ b/packages/url_launcher/url_launcher_web/LICENSE @@ -1,6 +1,6 @@ url_launcher_web -Copyright 2019 The Chromium Authors. All rights reserved. +Copyright 2019 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart b/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart index 3c1dbd8b1b89..43bd2234ec84 100644 --- a/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart +++ b/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart index f7ea35667530..f8057d5f4204 100644 --- a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart +++ b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/url_launcher/url_launcher_web/example/test_driver/integration_test_driver.dart b/packages/url_launcher/url_launcher_web/example/test_driver/integration_test_driver.dart index 64e2248a4f9b..0dd5f694f16b 100644 --- a/packages/url_launcher/url_launcher_web/example/test_driver/integration_test_driver.dart +++ b/packages/url_launcher/url_launcher_web/example/test_driver/integration_test_driver.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/url_launcher/url_launcher_web/lib/src/link.dart b/packages/url_launcher/url_launcher_web/lib/src/link.dart index 42c711b7d818..a39dbd4edf58 100644 --- a/packages/url_launcher/url_launcher_web/lib/src/link.dart +++ b/packages/url_launcher/url_launcher_web/lib/src/link.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui.dart b/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui.dart index 27d39b528e51..ec93f431138b 100644 --- a/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui.dart +++ b/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui_fake.dart b/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui_fake.dart index 7f8c2b2c0796..2a8c7f5f5c6e 100644 --- a/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui_fake.dart +++ b/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui_fake.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui_real.dart b/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui_real.dart index 16654a0fa967..b6c2f8812a1b 100644 --- a/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui_real.dart +++ b/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui_real.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart b/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart index e4d2116445cf..a2a1f2a9d863 100644 --- a/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart +++ b/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart b/packages/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart index 11f9b24dc878..64d8e547e485 100644 --- a/packages/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart +++ b/packages/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/url_launcher/url_launcher_windows/AUTHORS b/packages/url_launcher/url_launcher_windows/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/url_launcher/url_launcher_windows/AUTHORS +++ b/packages/url_launcher/url_launcher_windows/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/url_launcher/url_launcher_windows/LICENSE b/packages/url_launcher/url_launcher_windows/LICENSE index 507569823f1b..b257ce7c224c 100644 --- a/packages/url_launcher/url_launcher_windows/LICENSE +++ b/packages/url_launcher/url_launcher_windows/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019 The Chromium Authors. All rights reserved. +Copyright 2019 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/url_launcher/url_launcher_windows/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_windows/example/integration_test/url_launcher_test.dart index aa668ed747b5..b14cc943c90d 100644 --- a/packages/url_launcher/url_launcher_windows/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_windows/example/integration_test/url_launcher_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/url_launcher/url_launcher_windows/example/lib/main.dart b/packages/url_launcher/url_launcher_windows/example/lib/main.dart index f49e9fa290c5..e6e027b4a6ba 100644 --- a/packages/url_launcher/url_launcher_windows/example/lib/main.dart +++ b/packages/url_launcher/url_launcher_windows/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/url_launcher/url_launcher_windows/example/test_driver/integration_test.dart b/packages/url_launcher/url_launcher_windows/example/test_driver/integration_test.dart index c62ef5dba800..ac2a0cf5f19b 100644 --- a/packages/url_launcher/url_launcher_windows/example/test_driver/integration_test.dart +++ b/packages/url_launcher/url_launcher_windows/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/url_launcher/url_launcher_windows/windows/include/url_launcher_windows/url_launcher_plugin.h b/packages/url_launcher/url_launcher_windows/windows/include/url_launcher_windows/url_launcher_plugin.h index cdd018a0924e..7ffb0f93f271 100644 --- a/packages/url_launcher/url_launcher_windows/windows/include/url_launcher_windows/url_launcher_plugin.h +++ b/packages/url_launcher/url_launcher_windows/windows/include/url_launcher_windows/url_launcher_plugin.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. #ifndef PACKAGES_URL_LAUNCHER_URL_LAUNCHER_WINDOWS_WINDOWS_INCLUDE_URL_LAUNCHER_WINDOWS_URL_LAUNCHER_PLUGIN_H_ diff --git a/packages/url_launcher/url_launcher_windows/windows/url_launcher_plugin.cpp b/packages/url_launcher/url_launcher_windows/windows/url_launcher_plugin.cpp index dfb406385787..e6a36f76ad77 100644 --- a/packages/url_launcher/url_launcher_windows/windows/url_launcher_plugin.cpp +++ b/packages/url_launcher/url_launcher_windows/windows/url_launcher_plugin.cpp @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. #include "include/url_launcher_windows/url_launcher_plugin.h" diff --git a/packages/video_player/video_player/AUTHORS b/packages/video_player/video_player/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/video_player/video_player/AUTHORS +++ b/packages/video_player/video_player/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/video_player/video_player/LICENSE b/packages/video_player/video_player/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/video_player/video_player/LICENSE +++ b/packages/video_player/video_player/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/CustomSSLSocketFactory.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/CustomSSLSocketFactory.java index adccd2e2cdcd..0deb06b6fa08 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/CustomSSLSocketFactory.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/CustomSSLSocketFactory.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java index 0d108caa0597..c42abff848d5 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/QueuingEventSink.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/QueuingEventSink.java index 18835271a83a..fc1acc3250f9 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/QueuingEventSink.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/QueuingEventSink.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java index bba301666993..dae24d17ece2 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerOptions.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerOptions.java index fa51fbf50b43..63b1896038c7 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerOptions.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerOptions.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java index 0c5854f4bc83..644c0e88c226 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player/example/android/app/src/main/java/io/flutter/plugins/videoplayerexample/EmbeddingV1Activity.java b/packages/video_player/video_player/example/android/app/src/main/java/io/flutter/plugins/videoplayerexample/EmbeddingV1Activity.java index 841853dbd758..60bebe82d4df 100644 --- a/packages/video_player/video_player/example/android/app/src/main/java/io/flutter/plugins/videoplayerexample/EmbeddingV1Activity.java +++ b/packages/video_player/video_player/example/android/app/src/main/java/io/flutter/plugins/videoplayerexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/video_player/video_player/example/integration_test/video_player_test.dart b/packages/video_player/video_player/example/integration_test/video_player_test.dart index b39bb087a21c..0566ceeb01c4 100644 --- a/packages/video_player/video_player/example/integration_test/video_player_test.dart +++ b/packages/video_player/video_player/example/integration_test/video_player_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/video_player/video_player/example/ios/Runner.xcodeproj/project.pbxproj b/packages/video_player/video_player/example/ios/Runner.xcodeproj/project.pbxproj index 9f0a7ef189b9..d558ae5d68e0 100644 --- a/packages/video_player/video_player/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/video_player/video_player/example/ios/Runner.xcodeproj/project.pbxproj @@ -177,7 +177,7 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 1100; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; diff --git a/packages/video_player/video_player/example/ios/Runner/AppDelegate.h b/packages/video_player/video_player/example/ios/Runner/AppDelegate.h index d9e18e990f2e..31fc381e7066 100644 --- a/packages/video_player/video_player/example/ios/Runner/AppDelegate.h +++ b/packages/video_player/video_player/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player/example/ios/Runner/AppDelegate.m b/packages/video_player/video_player/example/ios/Runner/AppDelegate.m index f08675707182..2147d3d605ac 100644 --- a/packages/video_player/video_player/example/ios/Runner/AppDelegate.m +++ b/packages/video_player/video_player/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player/example/ios/Runner/main.m b/packages/video_player/video_player/example/ios/Runner/main.m index bec320c0bee0..f451b14cb751 100644 --- a/packages/video_player/video_player/example/ios/Runner/main.m +++ b/packages/video_player/video_player/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player/example/lib/main.dart b/packages/video_player/video_player/example/lib/main.dart index c874f740eab2..8ab4ff12216c 100644 --- a/packages/video_player/video_player/example/lib/main.dart +++ b/packages/video_player/video_player/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player/example/test_driver/integration_test.dart b/packages/video_player/video_player/example/test_driver/integration_test.dart index ca76cd86091a..2a2476ac7a1a 100644 --- a/packages/video_player/video_player/example/test_driver/integration_test.dart +++ b/packages/video_player/video_player/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/video_player/video_player/example/test_driver/video_player.dart b/packages/video_player/video_player/example/test_driver/video_player.dart index b942d20c17ba..317632834566 100644 --- a/packages/video_player/video_player/example/test_driver/video_player.dart +++ b/packages/video_player/video_player/example/test_driver/video_player.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/video_player/video_player/example/test_driver/video_player_test.dart b/packages/video_player/video_player/example/test_driver/video_player_test.dart index 232a88d89926..63e53f0b69e9 100644 --- a/packages/video_player/video_player/example/test_driver/video_player_test.dart +++ b/packages/video_player/video_player/example/test_driver/video_player_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.h b/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.h index 18fdcca6d54e..80f07014954e 100644 --- a/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.h +++ b/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m b/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m index c2a1a40aa4fe..ed1623f4f575 100644 --- a/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m +++ b/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player/ios/Classes/messages.h b/packages/video_player/video_player/ios/Classes/messages.h index 8e2ae130643f..ab54e8d8048f 100644 --- a/packages/video_player/video_player/ios/Classes/messages.h +++ b/packages/video_player/video_player/ios/Classes/messages.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player/ios/Classes/messages.m b/packages/video_player/video_player/ios/Classes/messages.m index 368601b9d6cb..78174d43a153 100644 --- a/packages/video_player/video_player/ios/Classes/messages.m +++ b/packages/video_player/video_player/ios/Classes/messages.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player/lib/src/closed_caption_file.dart b/packages/video_player/video_player/lib/src/closed_caption_file.dart index 64ab1f6ca651..1542746e08b1 100644 --- a/packages/video_player/video_player/lib/src/closed_caption_file.dart +++ b/packages/video_player/video_player/lib/src/closed_caption_file.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/video_player/video_player/lib/src/sub_rip.dart b/packages/video_player/video_player/lib/src/sub_rip.dart index 11456db88d09..89c1d5f78b01 100644 --- a/packages/video_player/video_player/lib/src/sub_rip.dart +++ b/packages/video_player/video_player/lib/src/sub_rip.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/video_player/video_player/lib/video_player.dart b/packages/video_player/video_player/lib/video_player.dart index 96dd73d3adea..4d3e4fa2dcbc 100644 --- a/packages/video_player/video_player/lib/video_player.dart +++ b/packages/video_player/video_player/lib/video_player.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player/pigeons/messages.dart b/packages/video_player/video_player/pigeons/messages.dart index 33ca12e7969e..43bcf4d6a3c2 100644 --- a/packages/video_player/video_player/pigeons/messages.dart +++ b/packages/video_player/video_player/pigeons/messages.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player/test/closed_caption_file_test.dart b/packages/video_player/video_player/test/closed_caption_file_test.dart index 148c082bceee..9b5ca8a11b22 100644 --- a/packages/video_player/video_player/test/closed_caption_file_test.dart +++ b/packages/video_player/video_player/test/closed_caption_file_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/video_player/video_player/test/sub_rip_file_test.dart b/packages/video_player/video_player/test/sub_rip_file_test.dart index 2b9803d8275e..5f696fa0d351 100644 --- a/packages/video_player/video_player/test/sub_rip_file_test.dart +++ b/packages/video_player/video_player/test/sub_rip_file_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/video_player/video_player/test/video_player_initialization_test.dart b/packages/video_player/video_player/test/video_player_initialization_test.dart index 1a09ed9f718c..64bbb99d09b8 100644 --- a/packages/video_player/video_player/test/video_player_initialization_test.dart +++ b/packages/video_player/video_player/test/video_player_initialization_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/video_player/video_player/test/video_player_test.dart b/packages/video_player/video_player/test/video_player_test.dart index 582012097b71..bdb9dc9ec432 100644 --- a/packages/video_player/video_player/test/video_player_test.dart +++ b/packages/video_player/video_player/test/video_player_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/video_player/video_player_platform_interface/AUTHORS b/packages/video_player/video_player_platform_interface/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/video_player/video_player_platform_interface/AUTHORS +++ b/packages/video_player/video_player_platform_interface/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/video_player/video_player_platform_interface/LICENSE b/packages/video_player/video_player_platform_interface/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/video_player/video_player_platform_interface/LICENSE +++ b/packages/video_player/video_player_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/video_player/video_player_platform_interface/lib/messages.dart b/packages/video_player/video_player_platform_interface/lib/messages.dart index 96ff20ea907f..83e34ee33eb8 100644 --- a/packages/video_player/video_player_platform_interface/lib/messages.dart +++ b/packages/video_player/video_player_platform_interface/lib/messages.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart b/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart index 9b007d00d6a9..9a37d6084c0a 100644 --- a/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart +++ b/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player_platform_interface/lib/test.dart b/packages/video_player/video_player_platform_interface/lib/test.dart index 7365f6dfb391..fd23a61a0365 100644 --- a/packages/video_player/video_player_platform_interface/lib/test.dart +++ b/packages/video_player/video_player_platform_interface/lib/test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart index 77b34f46bc10..bf30ecc6fc93 100644 --- a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart +++ b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart b/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart index fae4b746bf05..7a5192d861c0 100644 --- a/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart +++ b/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player_web/AUTHORS b/packages/video_player/video_player_web/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/video_player/video_player_web/AUTHORS +++ b/packages/video_player/video_player_web/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/video_player/video_player_web/LICENSE b/packages/video_player/video_player_web/LICENSE index a6d6c0749818..bb6f2c07756f 100644 --- a/packages/video_player/video_player_web/LICENSE +++ b/packages/video_player/video_player_web/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Chromium Authors. All rights reserved. +Copyright 2017 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/video_player/video_player_web/lib/src/shims/dart_ui.dart b/packages/video_player/video_player_web/lib/src/shims/dart_ui.dart index 27d39b528e51..ec93f431138b 100644 --- a/packages/video_player/video_player_web/lib/src/shims/dart_ui.dart +++ b/packages/video_player/video_player_web/lib/src/shims/dart_ui.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player_web/lib/src/shims/dart_ui_fake.dart b/packages/video_player/video_player_web/lib/src/shims/dart_ui_fake.dart index 7f8c2b2c0796..2a8c7f5f5c6e 100644 --- a/packages/video_player/video_player_web/lib/src/shims/dart_ui_fake.dart +++ b/packages/video_player/video_player_web/lib/src/shims/dart_ui_fake.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player_web/lib/src/shims/dart_ui_real.dart b/packages/video_player/video_player_web/lib/src/shims/dart_ui_real.dart index 16654a0fa967..b6c2f8812a1b 100644 --- a/packages/video_player/video_player_web/lib/src/shims/dart_ui_real.dart +++ b/packages/video_player/video_player_web/lib/src/shims/dart_ui_real.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player_web/lib/video_player_web.dart b/packages/video_player/video_player_web/lib/video_player_web.dart index d22c8f4f983c..6c99e24c4feb 100644 --- a/packages/video_player/video_player_web/lib/video_player_web.dart +++ b/packages/video_player/video_player_web/lib/video_player_web.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/packages/video_player/video_player_web/test/video_player_web_test.dart b/packages/video_player/video_player_web/test/video_player_web_test.dart index aee5b0350570..4fdbc7e9d3d6 100644 --- a/packages/video_player/video_player_web/test/video_player_web_test.dart +++ b/packages/video_player/video_player_web/test/video_player_web_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/AUTHORS b/packages/webview_flutter/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/webview_flutter/AUTHORS +++ b/packages/webview_flutter/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/webview_flutter/LICENSE b/packages/webview_flutter/LICENSE index ad33cf3c3ed1..050e2c7cac4f 100644 --- a/packages/webview_flutter/LICENSE +++ b/packages/webview_flutter/LICENSE @@ -1,4 +1,4 @@ -Copyright 2018 The Chromium Authors. All rights reserved. +Copyright 2018 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/DisplayListenerProxy.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/DisplayListenerProxy.java index e98c2b0fc4da..2d66da8fc918 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/DisplayListenerProxy.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/DisplayListenerProxy.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterCookieManager.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterCookieManager.java index 86b4fd412a29..456d07c2d214 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterCookieManager.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterCookieManager.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index 022f1c3597e7..f170e7267c56 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java index 3590d67eb334..30bbeafd1b68 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/InputAwareWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/InputAwareWebView.java index 9b81a5b7cc6b..51758d05c57a 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/InputAwareWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/InputAwareWebView.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/JavaScriptChannel.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/JavaScriptChannel.java index f23aae5b2b69..4b39d3bb83ef 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/JavaScriptChannel.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/JavaScriptChannel.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/ThreadedInputConnectionProxyAdapterView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/ThreadedInputConnectionProxyAdapterView.java index 8fbdfaff1a6d..2be6dc1f575c 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/ThreadedInputConnectionProxyAdapterView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/ThreadedInputConnectionProxyAdapterView.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFactory.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFactory.java index 6fdc36fbe545..054e68554df4 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFactory.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFactory.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java index 2de8fdf94bc4..23926c4577ea 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/webview_flutter/example/android/app/src/main/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1Activity.java b/packages/webview_flutter/example/android/app/src/main/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1Activity.java index dbdb1d7f72f9..8eda066ea776 100644 --- a/packages/webview_flutter/example/android/app/src/main/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1Activity.java +++ b/packages/webview_flutter/example/android/app/src/main/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. 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 20391f70d2ff..37da553b0893 100644 --- a/packages/webview_flutter/example/integration_test/webview_flutter_test.dart +++ b/packages/webview_flutter/example/integration_test/webview_flutter_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/webview_flutter/example/ios/Runner.xcodeproj/project.pbxproj b/packages/webview_flutter/example/ios/Runner.xcodeproj/project.pbxproj index d651613f32dc..30ce866bcf73 100644 --- a/packages/webview_flutter/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/webview_flutter/example/ios/Runner.xcodeproj/project.pbxproj @@ -227,7 +227,7 @@ attributes = { DefaultBuildSystemTypeForWorkspace = Original; LastUpgradeCheck = 1030; - ORGANIZATIONNAME = "The Chromium Authors"; + ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 68BDCAE823C3F7CB00D9C032 = { ProvisioningStyle = Automatic; diff --git a/packages/webview_flutter/example/ios/Runner/AppDelegate.h b/packages/webview_flutter/example/ios/Runner/AppDelegate.h index d129e6e65e7a..d0578fc417d7 100644 --- a/packages/webview_flutter/example/ios/Runner/AppDelegate.h +++ b/packages/webview_flutter/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/webview_flutter/example/ios/Runner/AppDelegate.m b/packages/webview_flutter/example/ios/Runner/AppDelegate.m index e5b5ebef5767..f6a895ac8dd8 100644 --- a/packages/webview_flutter/example/ios/Runner/AppDelegate.m +++ b/packages/webview_flutter/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/webview_flutter/example/ios/Runner/main.m b/packages/webview_flutter/example/ios/Runner/main.m index bc098e4e00a4..a6d55eceeb0e 100644 --- a/packages/webview_flutter/example/ios/Runner/main.m +++ b/packages/webview_flutter/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/webview_flutter/example/lib/main.dart b/packages/webview_flutter/example/lib/main.dart index e7e7981150ca..5c9e638ee1aa 100644 --- a/packages/webview_flutter/example/lib/main.dart +++ b/packages/webview_flutter/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/webview_flutter/example/test_driver/integration_test.dart b/packages/webview_flutter/example/test_driver/integration_test.dart index c62ef5dba800..ac2a0cf5f19b 100644 --- a/packages/webview_flutter/example/test_driver/integration_test.dart +++ b/packages/webview_flutter/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. All rights reserved. +// Copyright 2019, 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. diff --git a/packages/webview_flutter/ios/Classes/FLTCookieManager.h b/packages/webview_flutter/ios/Classes/FLTCookieManager.h index 3ad5c7e0d9bf..29e028ced59f 100644 --- a/packages/webview_flutter/ios/Classes/FLTCookieManager.h +++ b/packages/webview_flutter/ios/Classes/FLTCookieManager.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/ios/Classes/FLTCookieManager.m b/packages/webview_flutter/ios/Classes/FLTCookieManager.m index 47948bf6b9f0..0a15c7ceb975 100644 --- a/packages/webview_flutter/ios/Classes/FLTCookieManager.m +++ b/packages/webview_flutter/ios/Classes/FLTCookieManager.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.h b/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.h index 1625c4999bd2..3e661ff93b3e 100644 --- a/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.h +++ b/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m b/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m index 7eb08daea40e..85a5decf6e3e 100644 --- a/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m +++ b/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.h b/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.h index 40139ead262c..36ed108bb727 100644 --- a/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.h +++ b/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.m b/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.m index ad864e6e1fd1..d53f132bea25 100644 --- a/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.m +++ b/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.h b/packages/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.h index fffaedbe513b..109170e9af66 100644 --- a/packages/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.h +++ b/packages/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.m b/packages/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.m index a131263c9a92..3d39d96a6771 100644 --- a/packages/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.m +++ b/packages/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.h b/packages/webview_flutter/ios/Classes/FlutterWebView.h index 875551d3535d..555a90837da9 100644 --- a/packages/webview_flutter/ios/Classes/FlutterWebView.h +++ b/packages/webview_flutter/ios/Classes/FlutterWebView.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.m b/packages/webview_flutter/ios/Classes/FlutterWebView.m index 5f2af3b8aae0..a1ea10c397f9 100644 --- a/packages/webview_flutter/ios/Classes/FlutterWebView.m +++ b/packages/webview_flutter/ios/Classes/FlutterWebView.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/webview_flutter/ios/Classes/JavaScriptChannelHandler.h b/packages/webview_flutter/ios/Classes/JavaScriptChannelHandler.h index 1e0a9f2fe9d6..d3b1261dae94 100644 --- a/packages/webview_flutter/ios/Classes/JavaScriptChannelHandler.h +++ b/packages/webview_flutter/ios/Classes/JavaScriptChannelHandler.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/ios/Classes/JavaScriptChannelHandler.m b/packages/webview_flutter/ios/Classes/JavaScriptChannelHandler.m index 5bafd8c715dd..2e9e1b864f34 100644 --- a/packages/webview_flutter/ios/Classes/JavaScriptChannelHandler.m +++ b/packages/webview_flutter/ios/Classes/JavaScriptChannelHandler.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/ios/Tests/FLTWKNavigationDelegateTests.m b/packages/webview_flutter/ios/Tests/FLTWKNavigationDelegateTests.m index b22f9aa9d642..af6ce0b71450 100644 --- a/packages/webview_flutter/ios/Tests/FLTWKNavigationDelegateTests.m +++ b/packages/webview_flutter/ios/Tests/FLTWKNavigationDelegateTests.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/ios/Tests/FLTWebViewTests.m b/packages/webview_flutter/ios/Tests/FLTWebViewTests.m index 40b79e356389..9a886d383c22 100644 --- a/packages/webview_flutter/ios/Tests/FLTWebViewTests.m +++ b/packages/webview_flutter/ios/Tests/FLTWebViewTests.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/lib/platform_interface.dart b/packages/webview_flutter/lib/platform_interface.dart index 16b529d7090e..198e07767fc5 100644 --- a/packages/webview_flutter/lib/platform_interface.dart +++ b/packages/webview_flutter/lib/platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/lib/src/webview_android.dart b/packages/webview_flutter/lib/src/webview_android.dart index cba9e1b698b8..a8b87fc52616 100644 --- a/packages/webview_flutter/lib/src/webview_android.dart +++ b/packages/webview_flutter/lib/src/webview_android.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/lib/src/webview_cupertino.dart b/packages/webview_flutter/lib/src/webview_cupertino.dart index e6816555f73b..eb1e75876d4e 100644 --- a/packages/webview_flutter/lib/src/webview_cupertino.dart +++ b/packages/webview_flutter/lib/src/webview_cupertino.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/lib/src/webview_method_channel.dart index e26604f74628..bd042130f92a 100644 --- a/packages/webview_flutter/lib/src/webview_method_channel.dart +++ b/packages/webview_flutter/lib/src/webview_method_channel.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart index 56315b6692a5..af373d1bcbb7 100644 --- a/packages/webview_flutter/lib/webview_flutter.dart +++ b/packages/webview_flutter/lib/webview_flutter.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/webview_flutter/test/webview_flutter_test.dart b/packages/webview_flutter/test/webview_flutter_test.dart index 8ae6e625431d..afe6664a5957 100644 --- a/packages/webview_flutter/test/webview_flutter_test.dart +++ b/packages/webview_flutter/test/webview_flutter_test.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/AUTHORS b/packages/wifi_info_flutter/wifi_info_flutter/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/AUTHORS +++ b/packages/wifi_info_flutter/wifi_info_flutter/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/wifi_info_flutter/wifi_info_flutter/LICENSE b/packages/wifi_info_flutter/wifi_info_flutter/LICENSE index d7412e0a1e0c..67c7e2c52e46 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/LICENSE +++ b/packages/wifi_info_flutter/wifi_info_flutter/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020 The Chromium Authors. All rights reserved. +Copyright 2020 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java b/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java index e5e33af715ca..6425b9be2909 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java +++ b/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterMethodChannelHandler.java b/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterMethodChannelHandler.java index b996d32255e3..77861fd4b5fa 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterMethodChannelHandler.java +++ b/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterMethodChannelHandler.java @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterPlugin.java b/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterPlugin.java index 1346617df53b..f1b3c0e181ba 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterPlugin.java +++ b/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/lib/main.dart b/packages/wifi_info_flutter/wifi_info_flutter/example/lib/main.dart index b92e55028a45..7e25bc527b2a 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/lib/main.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/integration_test/wifi_info_test.dart b/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/integration_test/wifi_info_test.dart index 6fe4737ae7a1..98f56d4e5e25 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/integration_test/wifi_info_test.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/integration_test/wifi_info_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/test/integration_test.dart b/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/test/integration_test.dart index d59272c77431..8997c9275a06 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/test/integration_test.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/test/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/integration_test/wifi_info_test.dart b/packages/wifi_info_flutter/wifi_info_flutter/integration_test/wifi_info_test.dart index 4760b88d9019..5b6c0ded11cf 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/integration_test/wifi_info_test.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/integration_test/wifi_info_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/FLTWifiInfoLocationHandler.h b/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/FLTWifiInfoLocationHandler.h index 7cfe42df6079..05b885c7d2ac 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/FLTWifiInfoLocationHandler.h +++ b/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/FLTWifiInfoLocationHandler.h @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/FLTWifiInfoLocationHandler.m b/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/FLTWifiInfoLocationHandler.m index 2f237a1d3f15..331b6cca2ea8 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/FLTWifiInfoLocationHandler.m +++ b/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/FLTWifiInfoLocationHandler.m @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.h b/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.h index 92d843793990..66e3dd18c9b4 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.h +++ b/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.m b/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.m index f0811dd92ef6..1db163a65766 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.m +++ b/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/lib/wifi_info_flutter.dart b/packages/wifi_info_flutter/wifi_info_flutter/lib/wifi_info_flutter.dart index a2a69d161f5a..c15718bdb82d 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/lib/wifi_info_flutter.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/lib/wifi_info_flutter.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/test/wifi_info_flutter_test.dart b/packages/wifi_info_flutter/wifi_info_flutter/test/wifi_info_flutter_test.dart index 19e84f696f7f..c0874d10aa07 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/test/wifi_info_flutter_test.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/test/wifi_info_flutter_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/AUTHORS b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/AUTHORS index dbf9d190931b..493a0b4ef9c2 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/AUTHORS +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/AUTHORS @@ -4,6 +4,7 @@ # Name/Organization Google Inc. +The Chromium Authors German Saprykin Benjamin Sauer larsenthomasj@gmail.com diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/LICENSE b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/LICENSE index d7412e0a1e0c..67c7e2c52e46 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/LICENSE +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020 The Chromium Authors. All rights reserved. +Copyright 2020 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/enums.dart b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/enums.dart index 4529938b4761..8dae9737981a 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/enums.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/enums.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/method_channel_wifi_info_flutter.dart b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/method_channel_wifi_info_flutter.dart index ba422ecd7565..efd775ab7486 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/method_channel_wifi_info_flutter.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/method_channel_wifi_info_flutter.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/wifi_info_flutter_platform_interface.dart b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/wifi_info_flutter_platform_interface.dart index 5115af7e56eb..7e8de96336b4 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/wifi_info_flutter_platform_interface.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/wifi_info_flutter_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/test/method_channel_wifi_info_flutter_test.dart b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/test/method_channel_wifi_info_flutter_test.dart index 33733170c9fb..c30713a65b72 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/test/method_channel_wifi_info_flutter_test.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/test/method_channel_wifi_info_flutter_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// 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. diff --git a/script/build_all_plugins_app.sh b/script/build_all_plugins_app.sh index cfd783e64d1e..864a81a85057 100755 --- a/script/build_all_plugins_app.sh +++ b/script/build_all_plugins_app.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2017 The Chromium Authors. All rights reserved. +# Copyright 2017 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. diff --git a/script/check_publish.sh b/script/check_publish.sh index ead4aa3b2b34..5c68806c092a 100755 --- a/script/check_publish.sh +++ b/script/check_publish.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2017 The Chromium Authors. All rights reserved. +# Copyright 2017 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. diff --git a/script/common.sh b/script/common.sh index 9668688f50b2..81fc96cbdc18 100644 --- a/script/common.sh +++ b/script/common.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2017 The Chromium Authors. All rights reserved. +# Copyright 2017 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. diff --git a/script/incremental_build.sh b/script/incremental_build.sh index b46f500ae414..d087745eb88d 100755 --- a/script/incremental_build.sh +++ b/script/incremental_build.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2017 The Chromium Authors. All rights reserved. +# Copyright 2017 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. diff --git a/script/tool/lib/src/analyze_command.dart b/script/tool/lib/src/analyze_command.dart index 8cd57fa0b338..7a0b47261a90 100644 --- a/script/tool/lib/src/analyze_command.dart +++ b/script/tool/lib/src/analyze_command.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/script/tool/lib/src/build_examples_command.dart b/script/tool/lib/src/build_examples_command.dart index bb140bd429c6..22029791f324 100644 --- a/script/tool/lib/src/build_examples_command.dart +++ b/script/tool/lib/src/build_examples_command.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/script/tool/lib/src/common.dart b/script/tool/lib/src/common.dart index ce4f37873b07..1228aef5b0f6 100644 --- a/script/tool/lib/src/common.dart +++ b/script/tool/lib/src/common.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/script/tool/lib/src/create_all_plugins_app_command.dart b/script/tool/lib/src/create_all_plugins_app_command.dart index 0f1431c5aee0..ec2fb7ed698e 100644 --- a/script/tool/lib/src/create_all_plugins_app_command.dart +++ b/script/tool/lib/src/create_all_plugins_app_command.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/script/tool/lib/src/drive_examples_command.dart b/script/tool/lib/src/drive_examples_command.dart index 0bd531a20f8a..4b5b33ff9029 100644 --- a/script/tool/lib/src/drive_examples_command.dart +++ b/script/tool/lib/src/drive_examples_command.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/script/tool/lib/src/firebase_test_lab_command.dart b/script/tool/lib/src/firebase_test_lab_command.dart index 0b4b2a471dbc..382161226987 100644 --- a/script/tool/lib/src/firebase_test_lab_command.dart +++ b/script/tool/lib/src/firebase_test_lab_command.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/script/tool/lib/src/format_command.dart b/script/tool/lib/src/format_command.dart index e1c14e04cfec..54895cbae094 100644 --- a/script/tool/lib/src/format_command.dart +++ b/script/tool/lib/src/format_command.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/script/tool/lib/src/java_test_command.dart b/script/tool/lib/src/java_test_command.dart index cf605bfc5ce2..07800349a37b 100644 --- a/script/tool/lib/src/java_test_command.dart +++ b/script/tool/lib/src/java_test_command.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/script/tool/lib/src/license_check_command.dart b/script/tool/lib/src/license_check_command.dart index e70e60b154d9..2df217ef78fd 100644 --- a/script/tool/lib/src/license_check_command.dart +++ b/script/tool/lib/src/license_check_command.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. @@ -60,13 +60,7 @@ final RegExp _workivaLicenseRegex = RegExp( multiLine: true, dotAll: true); -// TODO(stuartmorgan): Replace this with a single string once all the copyrights -// are standardized. -final List _firstPartyAuthors = [ - 'The Chromium Authors', - 'the Chromium project authors', - 'The Flutter Authors', -]; +const String _firstPartyAuthors = 'The Flutter Authors'; // The exact format of the BSD license that our license files should contain. // Slight variants are not accepted because they may prevent consolidation in @@ -129,7 +123,7 @@ class LicenseCheckCommand extends PluginCommand { p.basename(file.basename) == 'LICENSE' && !_isThirdParty(file)); final bool copyrightCheckSucceeded = await _checkCodeLicenses(codeFiles); - print('\n=======================================\n'); + _print('\n=======================================\n'); final bool licenseCheckSucceeded = await _checkLicenseFiles(firstPartyLicenseFiles); @@ -170,7 +164,7 @@ class LicenseCheckCommand extends PluginCommand { continue; } final String author = copyright.group(1); - if (!_firstPartyAuthors.contains(author) && !_isThirdParty(file)) { + if (author != _firstPartyAuthors && !_isThirdParty(file)) { misplacedThirdPartyFiles.add(file); } diff --git a/script/tool/lib/src/lint_podspecs_command.dart b/script/tool/lib/src/lint_podspecs_command.dart index 13de64415e9e..1e75eb62e4ea 100644 --- a/script/tool/lib/src/lint_podspecs_command.dart +++ b/script/tool/lib/src/lint_podspecs_command.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/script/tool/lib/src/list_command.dart b/script/tool/lib/src/list_command.dart index 7f94daac7096..53c1ba2f3ea3 100644 --- a/script/tool/lib/src/list_command.dart +++ b/script/tool/lib/src/list_command.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2018 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. diff --git a/script/tool/lib/src/main.dart b/script/tool/lib/src/main.dart index 329112931251..bb8af5d5ad58 100644 --- a/script/tool/lib/src/main.dart +++ b/script/tool/lib/src/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/script/tool/lib/src/publish_check_command.dart b/script/tool/lib/src/publish_check_command.dart index 670fedaf2fa1..53002b57897a 100644 --- a/script/tool/lib/src/publish_check_command.dart +++ b/script/tool/lib/src/publish_check_command.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/script/tool/lib/src/publish_plugin_command.dart b/script/tool/lib/src/publish_plugin_command.dart index f61a76947c9e..d48ed5b7fe7d 100644 --- a/script/tool/lib/src/publish_plugin_command.dart +++ b/script/tool/lib/src/publish_plugin_command.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/script/tool/lib/src/test_command.dart b/script/tool/lib/src/test_command.dart index e938168cfa89..47f7ad89cb8d 100644 --- a/script/tool/lib/src/test_command.dart +++ b/script/tool/lib/src/test_command.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/script/tool/lib/src/version_check_command.dart b/script/tool/lib/src/version_check_command.dart index 111239f0399a..36105ad300ab 100644 --- a/script/tool/lib/src/version_check_command.dart +++ b/script/tool/lib/src/version_check_command.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/script/tool/lib/src/xctest_command.dart b/script/tool/lib/src/xctest_command.dart index a4d03360b292..cdc02594a192 100644 --- a/script/tool/lib/src/xctest_command.dart +++ b/script/tool/lib/src/xctest_command.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. diff --git a/script/tool/test/analyze_command_test.dart b/script/tool/test/analyze_command_test.dart index 63afb51c8595..6474d02f3d28 100644 --- a/script/tool/test/analyze_command_test.dart +++ b/script/tool/test/analyze_command_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/script/tool/test/build_examples_command_test.dart b/script/tool/test/build_examples_command_test.dart index e0213893db38..ef959a6e251c 100644 --- a/script/tool/test/build_examples_command_test.dart +++ b/script/tool/test/build_examples_command_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/script/tool/test/common_test.dart b/script/tool/test/common_test.dart index a8deacc8e483..8ee82ca2e95a 100644 --- a/script/tool/test/common_test.dart +++ b/script/tool/test/common_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/script/tool/test/drive_examples_command_test.dart b/script/tool/test/drive_examples_command_test.dart index 7a8e9f3e9f95..63a3e69adcdc 100644 --- a/script/tool/test/drive_examples_command_test.dart +++ b/script/tool/test/drive_examples_command_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/script/tool/test/firebase_test_lab_test.dart b/script/tool/test/firebase_test_lab_test.dart index d11624671523..6db4461a23a8 100644 --- a/script/tool/test/firebase_test_lab_test.dart +++ b/script/tool/test/firebase_test_lab_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/script/tool/test/license_check_command_test.dart b/script/tool/test/license_check_command_test.dart index 8ae956740d72..69879bff8869 100644 --- a/script/tool/test/license_check_command_test.dart +++ b/script/tool/test/license_check_command_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. @@ -45,7 +45,7 @@ void main() { String prefix = '', String suffix = '', String copyright = - 'Copyright 2019 The Chromium Authors. All rights reserved.', + 'Copyright 2019 The Flutter Authors. All rights reserved.', List license = const [ 'Use of this source code is governed by a BSD-style license that can be', 'found in the LICENSE file.', diff --git a/script/tool/test/lint_podspecs_command_test.dart b/script/tool/test/lint_podspecs_command_test.dart index 2a3e60853d08..44e94ee873e4 100644 --- a/script/tool/test/lint_podspecs_command_test.dart +++ b/script/tool/test/lint_podspecs_command_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/script/tool/test/list_command_test.dart b/script/tool/test/list_command_test.dart index d06f6d2ca464..e9b68254fb5d 100644 --- a/script/tool/test/list_command_test.dart +++ b/script/tool/test/list_command_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/script/tool/test/mocks.dart b/script/tool/test/mocks.dart index 35a4eb7cbacb..d5cfe4ec4f76 100644 --- a/script/tool/test/mocks.dart +++ b/script/tool/test/mocks.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/script/tool/test/publish_plugin_command_test.dart b/script/tool/test/publish_plugin_command_test.dart index 4f770b2054f9..b8ab1d25e532 100644 --- a/script/tool/test/publish_plugin_command_test.dart +++ b/script/tool/test/publish_plugin_command_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/script/tool/test/test_command_test.dart b/script/tool/test/test_command_test.dart index 520f4c316f5c..eb9f3a9b0cf3 100644 --- a/script/tool/test/test_command_test.dart +++ b/script/tool/test/test_command_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/script/tool/test/util.dart b/script/tool/test/util.dart index 63cd5defbb27..e463b88a1abb 100644 --- a/script/tool/test/util.dart +++ b/script/tool/test/util.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. diff --git a/script/tool/test/version_check_test.dart b/script/tool/test/version_check_test.dart index 400d4263357c..9e610d8a7a20 100644 --- a/script/tool/test/version_check_test.dart +++ b/script/tool/test/version_check_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. @@ -215,7 +215,7 @@ void main() { createFakePubspec(pluginDirectory, isFlutter: true, includeVersion: true, version: '1.0.1'); String changelog = ''' - + ## 1.0.1 diff --git a/script/tool/test/xctest_command_test.dart b/script/tool/test/xctest_command_test.dart index 2b75ccde4210..3b76fa6ffa19 100644 --- a/script/tool/test/xctest_command_test.dart +++ b/script/tool/test/xctest_command_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2017 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. From 15d4f9c4e06014225807c5fbcf681bd6ea1f765d Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Thu, 18 Mar 2021 17:05:38 -0700 Subject: [PATCH 0281/1565] [integration_test] Deprecate, and stop using in this repository (#3723) Updates integration_test README to note that the published version is deprecated and direct people to the SDK version. Updates all plugins here to use the SDK version. --- CODEOWNERS | 1 - CONTRIBUTING.md | 2 +- README.md | 3 +-- .../android_alarm_manager/example/pubspec.yaml | 2 +- packages/android_intent/example/pubspec.yaml | 2 +- packages/battery/battery/example/pubspec.yaml | 2 +- packages/battery/battery/pubspec.yaml | 2 +- packages/camera/camera/example/pubspec.yaml | 2 +- .../connectivity/example/pubspec.yaml | 2 +- packages/connectivity/connectivity/pubspec.yaml | 2 +- .../connectivity_macos/example/pubspec.yaml | 2 +- .../device_info/device_info/example/pubspec.yaml | 2 +- .../example/pubspec.yaml | 2 +- .../google_maps_flutter/example/pubspec.yaml | 2 +- .../google_sign_in/example/pubspec.yaml | 2 +- .../google_sign_in/google_sign_in/pubspec.yaml | 2 +- .../image_picker/example/pubspec.yaml | 2 +- packages/image_picker/image_picker/pubspec.yaml | 2 +- packages/in_app_purchase/example/pubspec.yaml | 2 +- packages/in_app_purchase/pubspec.yaml | 2 +- packages/integration_test/CHANGELOG.md | 4 ++++ packages/integration_test/README.md | 15 ++++++++++++++- packages/integration_test/pubspec.yaml | 2 +- packages/local_auth/example/pubspec.yaml | 2 +- packages/local_auth/pubspec.yaml | 2 +- packages/package_info/example/pubspec.yaml | 2 +- packages/package_info/pubspec.yaml | 2 +- .../path_provider/example/pubspec.yaml | 2 +- packages/path_provider/path_provider/pubspec.yaml | 2 +- .../path_provider_linux/example/pubspec.yaml | 2 +- .../path_provider_macos/example/pubspec.yaml | 2 +- .../path_provider_windows/example/pubspec.yaml | 2 +- packages/quick_actions/example/pubspec.yaml | 2 +- packages/quick_actions/pubspec.yaml | 2 +- packages/sensors/example/pubspec.yaml | 2 +- packages/sensors/pubspec.yaml | 2 +- packages/share/example/pubspec.yaml | 2 +- packages/share/pubspec.yaml | 2 +- .../shared_preferences/example/pubspec.yaml | 2 +- .../shared_preferences/pubspec.yaml | 2 +- .../shared_preferences_linux/example/pubspec.yaml | 2 +- .../shared_preferences_macos/example/pubspec.yaml | 2 +- .../example/pubspec.yaml | 2 +- .../url_launcher/example/pubspec.yaml | 2 +- .../url_launcher_linux/example/pubspec.yaml | 2 +- .../url_launcher_macos/example/pubspec.yaml | 2 +- .../url_launcher_windows/example/pubspec.yaml | 2 +- .../video_player/example/pubspec.yaml | 2 +- packages/webview_flutter/example/pubspec.yaml | 2 +- .../wifi_info_flutter/example/pubspec.yaml | 2 +- .../wifi_info_flutter/pubspec.yaml | 2 +- 51 files changed, 66 insertions(+), 51 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 8ab65bbb5a63..1d52dcefcbef 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -9,6 +9,5 @@ packages/camera/** @bparrishMines packages/file_selector/** @ditman packages/google_maps_flutter/** @cyanglaz packages/image_picker/** @cyanglaz -packages/integration_test/** @dnfield packages/in_app_purchase/** @cyanglaz @LHLL packages/ios_platform_images/** @gaaclarke diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d5ea4766b363..f307695b5956 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -61,7 +61,7 @@ USB and debugging enabled on that device. ## Setting up XCUITests -Sometimes, XCUITests are useful when integration testing a plugin that has native UI on iOS (e.g image_picker, in_app_purchase, camera, share, local_auth etc). Most of the time, XCUITests are not necessary, consider using [integration_test](https://pub.dev/packages/integration_test) if the tests are not focused on iOS system UI. +Sometimes, XCUITests are useful when integration testing a plugin that has native UI on iOS (e.g image_picker, in_app_purchase, camera, share, local_auth etc). Most of the time, XCUITests are not necessary, consider using `integration_test` if the tests are not focused on iOS system UI. If XCUITests has always been set up for the plugin, a RunnerUITests folder under `/example/ios` directory can be found. If XCUITests has not been set up for the plugin, follow these steps to set it up: diff --git a/README.md b/README.md index b65c10e7f381..c5c88d554df1 100644 --- a/README.md +++ b/README.md @@ -47,13 +47,12 @@ These are the available plugins in this repository. | [camera](./packages/camera/) | [![pub package](https://img.shields.io/pub/v/camera.svg)](https://pub.dev/packages/camera) | [![pub points](https://badges.bar/camera/pub%20points)](https://pub.dev/packages/camera/score) | [![popularity](https://badges.bar/camera/popularity)](https://pub.dev/packages/camera/score) | [![likes](https://badges.bar/camera/likes)](https://pub.dev/packages/camera/score) | | [connectivity](./packages/connectivity/) | [![pub package](https://img.shields.io/pub/v/connectivity.svg)](https://pub.dev/packages/connectivity) | [![pub points](https://badges.bar/connectivity/pub%20points)](https://pub.dev/packages/connectivity/score) | [![popularity](https://badges.bar/connectivity/popularity)](https://pub.dev/packages/connectivity/score) | [![likes](https://badges.bar/connectivity/likes)](https://pub.dev/packages/connectivity/score) | | [device_info](./packages/device_info/) | [![pub package](https://img.shields.io/pub/v/device_info.svg)](https://pub.dev/packages/device_info) | [![pub points](https://badges.bar/device_info/pub%20points)](https://pub.dev/packages/device_info/score) | [![popularity](https://badges.bar/device_info/popularity)](https://pub.dev/packages/device_info/score) | [![likes](https://badges.bar/device_info/likes)](https://pub.dev/packages/device_info/score) | -| [e2e (Discontinued, use integration_test)](./packages/e2e/) | [![pub package](https://img.shields.io/pub/v/e2e.svg)](https://pub.dev/packages/e2e) | [![pub points](https://badges.bar/e2e/pub%20points)](https://pub.dev/packages/e2e/score) | [![popularity](https://badges.bar/e2e/popularity)](https://pub.dev/packages/e2e/score) | [![likes](https://badges.bar/e2e/likes)](https://pub.dev/packages/e2e/score) | | [espresso](./packages/espresso/) | [![pub package](https://img.shields.io/pub/v/espresso.svg)](https://pub.dev/packages/espresso) | [![pub points](https://badges.bar/espresso/pub%20points)](https://pub.dev/packages/espresso/score) | [![popularity](https://badges.bar/espresso/popularity)](https://pub.dev/packages/espresso/score) | [![likes](https://badges.bar/espresso/likes)](https://pub.dev/packages/espresso/score) | | [flutter_plugin_android_lifecycle](./packages/flutter_plugin_android_lifecycle/) | [![pub package](https://img.shields.io/pub/v/flutter_plugin_android_lifecycle.svg)](https://pub.dev/packages/flutter_plugin_android_lifecycle) | [![pub points](https://badges.bar/flutter_plugin_android_lifecycle/pub%20points)](https://pub.dev/packages/flutter_plugin_android_lifecycle/score) | [![popularity](https://badges.bar/flutter_plugin_android_lifecycle/popularity)](https://pub.dev/packages/flutter_plugin_android_lifecycle/score) | [![likes](https://badges.bar/flutter_plugin_android_lifecycle/likes)](https://pub.dev/packages/flutter_plugin_android_lifecycle/score) | | [google_maps_flutter](./packages/google_maps_flutter) | [![pub package](https://img.shields.io/pub/v/google_maps_flutter.svg)](https://pub.dev/packages/google_maps_flutter) | [![pub points](https://badges.bar/google_maps_flutter/pub%20points)](https://pub.dev/packages/google_maps_flutter/score) | [![popularity](https://badges.bar/google_maps_flutter/popularity)](https://pub.dev/packages/google_maps_flutter/score) | [![likes](https://badges.bar/google_maps_flutter/likes)](https://pub.dev/packages/google_maps_flutter/score) | | [google_sign_in](./packages/google_sign_in/) | [![pub package](https://img.shields.io/pub/v/google_sign_in.svg)](https://pub.dev/packages/google_sign_in) | [![pub points](https://badges.bar/google_sign_in/pub%20points)](https://pub.dev/packages/google_sign_in/score) | [![popularity](https://badges.bar/google_sign_in/popularity)](https://pub.dev/packages/google_sign_in/score) | [![likes](https://badges.bar/google_sign_in/likes)](https://pub.dev/packages/google_sign_in/score) | | [image_picker](./packages/image_picker/) | [![pub package](https://img.shields.io/pub/v/image_picker.svg)](https://pub.dev/packages/image_picker) | [![pub points](https://badges.bar/image_picker/pub%20points)](https://pub.dev/packages/image_picker/score) | [![popularity](https://badges.bar/image_picker/popularity)](https://pub.dev/packages/image_picker/score) | [![likes](https://badges.bar/image_picker/likes)](https://pub.dev/packages/image_picker/score) | -| [integration_test](./packages/integration_test/) | [![pub package](https://img.shields.io/pub/v/integration_test.svg)](https://pub.dev/packages/integration_test) | [![pub points](https://badges.bar/integration_test/pub%20points)](https://pub.dev/packages/integration_test/score) | [![popularity](https://badges.bar/integration_test/popularity)](https://pub.dev/packages/integration_test/score) | [![likes](https://badges.bar/integration_test/likes)](https://pub.dev/packages/integration_test/score) | +| [integration_test (discontinued)](./packages/integration_test/) | [![pub package](https://img.shields.io/pub/v/integration_test.svg)](https://pub.dev/packages/integration_test) | [![pub points](https://badges.bar/integration_test/pub%20points)](https://pub.dev/packages/integration_test/score) | [![popularity](https://badges.bar/integration_test/popularity)](https://pub.dev/packages/integration_test/score) | [![likes](https://badges.bar/integration_test/likes)](https://pub.dev/packages/integration_test/score) | | [in_app_purchase](./packages/in_app_purchase/) | [![pub package](https://img.shields.io/pub/v/in_app_purchase.svg)](https://pub.dev/packages/in_app_purchase) | [![pub points](https://badges.bar/in_app_purchase/pub%20points)](https://pub.dev/packages/in_app_purchase/score) | [![popularity](https://badges.bar/in_app_purchase/popularity)](https://pub.dev/packages/in_app_purchase/score) | [![likes](https://badges.bar/in_app_purchase/likes)](https://pub.dev/packages/in_app_purchase/score) | | [ios_platform_images](./packages/ios_platform_images/) | [![pub package](https://img.shields.io/pub/v/ios_platform_images.svg)](https://pub.dev/packages/ios_platform_images) | [![pub points](https://badges.bar/ios_platform_images/pub%20points)](https://pub.dev/packages/ios_platform_images/score) | [![popularity](https://badges.bar/ios_platform_images/popularity)](https://pub.dev/packages/ios_platform_images/score) | [![likes](https://badges.bar/ios_platform_images/likes)](https://pub.dev/packages/ios_platform_images/score) | | [local_auth](./packages/local_auth/) | [![pub package](https://img.shields.io/pub/v/local_auth.svg)](https://pub.dev/packages/local_auth) | [![pub points](https://badges.bar/local_auth/pub%20points)](https://pub.dev/packages/local_auth/score) | [![popularity](https://badges.bar/local_auth/popularity)](https://pub.dev/packages/local_auth/score) | [![likes](https://badges.bar/local_auth/likes)](https://pub.dev/packages/local_auth/score) | diff --git a/packages/android_alarm_manager/example/pubspec.yaml b/packages/android_alarm_manager/example/pubspec.yaml index b92f45c73d35..78525345ab5c 100644 --- a/packages/android_alarm_manager/example/pubspec.yaml +++ b/packages/android_alarm_manager/example/pubspec.yaml @@ -13,7 +13,7 @@ dependencies: path: ../ shared_preferences: ^2.0.0 integration_test: - path: ../../integration_test + sdk: flutter path_provider: ^2.0.0 dev_dependencies: diff --git a/packages/android_intent/example/pubspec.yaml b/packages/android_intent/example/pubspec.yaml index fd0e2d6b7844..fc154511dfa1 100644 --- a/packages/android_intent/example/pubspec.yaml +++ b/packages/android_intent/example/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: dev_dependencies: integration_test: - path: ../../integration_test + sdk: flutter flutter_driver: sdk: flutter pedantic: ^1.10.0 diff --git a/packages/battery/battery/example/pubspec.yaml b/packages/battery/battery/example/pubspec.yaml index ea3d5d39ae14..648e9f578db6 100644 --- a/packages/battery/battery/example/pubspec.yaml +++ b/packages/battery/battery/example/pubspec.yaml @@ -16,7 +16,7 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: - path: ../../../integration_test + sdk: flutter pedantic: ^1.10.0 flutter: diff --git a/packages/battery/battery/pubspec.yaml b/packages/battery/battery/pubspec.yaml index b705955efdef..4a93af02b0ea 100644 --- a/packages/battery/battery/pubspec.yaml +++ b/packages/battery/battery/pubspec.yaml @@ -24,7 +24,7 @@ dev_dependencies: sdk: flutter plugin_platform_interface: ^2.0.0 integration_test: - path: ../../integration_test + sdk: flutter pedantic: ^1.10.0 test: ^1.16.3 diff --git a/packages/camera/camera/example/pubspec.yaml b/packages/camera/camera/example/pubspec.yaml index b3ef8e497dc1..5fdaf5812d72 100644 --- a/packages/camera/camera/example/pubspec.yaml +++ b/packages/camera/camera/example/pubspec.yaml @@ -20,7 +20,7 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: - path: ../../../integration_test + sdk: flutter pedantic: ^1.10.0 flutter: diff --git a/packages/connectivity/connectivity/example/pubspec.yaml b/packages/connectivity/connectivity/example/pubspec.yaml index 6395dc38c3ae..58d6f0ddca61 100644 --- a/packages/connectivity/connectivity/example/pubspec.yaml +++ b/packages/connectivity/connectivity/example/pubspec.yaml @@ -17,7 +17,7 @@ dev_dependencies: sdk: flutter test: ^1.16.3 integration_test: - path: ../../../integration_test + sdk: flutter pedantic: ^1.10.0 flutter: diff --git a/packages/connectivity/connectivity/pubspec.yaml b/packages/connectivity/connectivity/pubspec.yaml index 7b4dc60eee81..85985dd45565 100644 --- a/packages/connectivity/connectivity/pubspec.yaml +++ b/packages/connectivity/connectivity/pubspec.yaml @@ -32,7 +32,7 @@ dev_dependencies: sdk: flutter test: ^1.16.3 integration_test: - path: ../../integration_test + sdk: flutter plugin_platform_interface: ^2.0.0 pedantic: ^1.10.0 diff --git a/packages/connectivity/connectivity_macos/example/pubspec.yaml b/packages/connectivity/connectivity_macos/example/pubspec.yaml index 61cf16854d8b..d130158c4364 100644 --- a/packages/connectivity/connectivity_macos/example/pubspec.yaml +++ b/packages/connectivity/connectivity_macos/example/pubspec.yaml @@ -17,7 +17,7 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: - path: ../../../integration_test + sdk: flutter pedantic: ^1.10.0 flutter: diff --git a/packages/device_info/device_info/example/pubspec.yaml b/packages/device_info/device_info/example/pubspec.yaml index bc7d00ef87f0..36b6d6e9441c 100644 --- a/packages/device_info/device_info/example/pubspec.yaml +++ b/packages/device_info/device_info/example/pubspec.yaml @@ -16,7 +16,7 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: - path: ../../../integration_test + sdk: flutter pedantic: ^1.10.0 flutter: diff --git a/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml b/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml index 833c2eba4319..4506437b1180 100644 --- a/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml +++ b/packages/flutter_plugin_android_lifecycle/example/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: dev_dependencies: integration_test: - path: ../../integration_test + sdk: flutter flutter_test: sdk: flutter pedantic: ^1.8.0 diff --git a/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml index 35d0da3488be..5d553eaa3c99 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml @@ -23,7 +23,7 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: - path: ../../../integration_test + sdk: flutter pedantic: ^1.10.0 flutter: diff --git a/packages/google_sign_in/google_sign_in/example/pubspec.yaml b/packages/google_sign_in/google_sign_in/example/pubspec.yaml index b5a1f3e1c2cc..f08a131e484a 100755 --- a/packages/google_sign_in/google_sign_in/example/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/example/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: dev_dependencies: pedantic: ^1.10.0 integration_test: - path: ../../../integration_test + sdk: flutter flutter_driver: sdk: flutter diff --git a/packages/google_sign_in/google_sign_in/pubspec.yaml b/packages/google_sign_in/google_sign_in/pubspec.yaml index 23f2588c8f90..1184d0f9af25 100644 --- a/packages/google_sign_in/google_sign_in/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/pubspec.yaml @@ -30,7 +30,7 @@ dev_dependencies: sdk: flutter pedantic: ^1.10.0 integration_test: - path: ../../integration_test + sdk: flutter environment: sdk: ">=2.12.0-259.9.beta <3.0.0" diff --git a/packages/image_picker/image_picker/example/pubspec.yaml b/packages/image_picker/image_picker/example/pubspec.yaml index ceafc317fa82..68b70b909162 100755 --- a/packages/image_picker/image_picker/example/pubspec.yaml +++ b/packages/image_picker/image_picker/example/pubspec.yaml @@ -19,7 +19,7 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: - path: ../../../integration_test + sdk: flutter pedantic: ^1.10.0 flutter: diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index cd4089e58798..0018e87ab437 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -26,7 +26,7 @@ dev_dependencies: flutter_test: sdk: flutter integration_test: - path: ../../integration_test + sdk: flutter mockito: ^5.0.0-nullsafety.7 pedantic: ^1.10.0 plugin_platform_interface: ^2.0.0 diff --git a/packages/in_app_purchase/example/pubspec.yaml b/packages/in_app_purchase/example/pubspec.yaml index 8c9296dc98c8..8d193debb826 100644 --- a/packages/in_app_purchase/example/pubspec.yaml +++ b/packages/in_app_purchase/example/pubspec.yaml @@ -18,7 +18,7 @@ dev_dependencies: # the parent directory to use the current plugin's version. path: ../ integration_test: - path: ../../integration_test + sdk: flutter pedantic: ^1.10.0 flutter: diff --git a/packages/in_app_purchase/pubspec.yaml b/packages/in_app_purchase/pubspec.yaml index c7582f91d8c2..2a8f56946bf2 100644 --- a/packages/in_app_purchase/pubspec.yaml +++ b/packages/in_app_purchase/pubspec.yaml @@ -19,7 +19,7 @@ dev_dependencies: sdk: flutter test: ^1.16.0 integration_test: - path: ../integration_test + sdk: flutter pedantic: ^1.10.0 flutter: diff --git a/packages/integration_test/CHANGELOG.md b/packages/integration_test/CHANGELOG.md index 71ab0e86266b..c5c34f49c2ab 100644 --- a/packages/integration_test/CHANGELOG.md +++ b/packages/integration_test/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.2+3 + +* Update README to reflect deprecation. + ## 1.0.2+2 * Fix tests from changes to `flutter test` machine output. diff --git a/packages/integration_test/README.md b/packages/integration_test/README.md index 676041eefae5..802fd4cafefc 100644 --- a/packages/integration_test/README.md +++ b/packages/integration_test/README.md @@ -1,4 +1,17 @@ -# integration_test +# integration_test (deprecated) + +## DEPRECATED + +This package has been moved to the Flutter SDK. Starting with Flutter 2.0, +it should be included as: + +``` +dev_dependencies: + integration_test: + sdk: flutter +``` + +## Old instructions This package enables self-driving testing of Flutter code on devices and emulators. It adapts flutter_test results into a format that is compatible with `flutter drive` diff --git a/packages/integration_test/pubspec.yaml b/packages/integration_test/pubspec.yaml index 33c174a9724a..daf84d6a5164 100644 --- a/packages/integration_test/pubspec.yaml +++ b/packages/integration_test/pubspec.yaml @@ -1,6 +1,6 @@ name: integration_test description: Runs tests that use the flutter_test API as integration tests. -version: 1.0.2+2 +version: 1.0.2+3 homepage: https://github.com/flutter/plugins/tree/master/packages/integration_test environment: diff --git a/packages/local_auth/example/pubspec.yaml b/packages/local_auth/example/pubspec.yaml index d50940f6b63c..aad68c59f930 100644 --- a/packages/local_auth/example/pubspec.yaml +++ b/packages/local_auth/example/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: dev_dependencies: integration_test: - path: ../../integration_test + sdk: flutter flutter_driver: sdk: flutter pedantic: ^1.10.0 diff --git a/packages/local_auth/pubspec.yaml b/packages/local_auth/pubspec.yaml index 337006aa196f..a63027728d86 100644 --- a/packages/local_auth/pubspec.yaml +++ b/packages/local_auth/pubspec.yaml @@ -23,7 +23,7 @@ dependencies: dev_dependencies: integration_test: - path: ../integration_test + sdk: flutter flutter_driver: sdk: flutter flutter_test: diff --git a/packages/package_info/example/pubspec.yaml b/packages/package_info/example/pubspec.yaml index a4691fcba518..0e47ad232eaa 100644 --- a/packages/package_info/example/pubspec.yaml +++ b/packages/package_info/example/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: # the parent directory to use the current plugin's version. path: ../ integration_test: - path: ../../integration_test + sdk: flutter dev_dependencies: flutter_driver: diff --git a/packages/package_info/pubspec.yaml b/packages/package_info/pubspec.yaml index 2769af1f83d5..dac73571fd33 100644 --- a/packages/package_info/pubspec.yaml +++ b/packages/package_info/pubspec.yaml @@ -25,7 +25,7 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: - path: ../integration_test + sdk: flutter pedantic: ^1.10.0 environment: diff --git a/packages/path_provider/path_provider/example/pubspec.yaml b/packages/path_provider/path_provider/example/pubspec.yaml index 68c751a81843..326c68e0e3e5 100644 --- a/packages/path_provider/path_provider/example/pubspec.yaml +++ b/packages/path_provider/path_provider/example/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: dev_dependencies: integration_test: - path: ../../../integration_test + sdk: flutter flutter_driver: sdk: flutter pedantic: ^1.10.0 diff --git a/packages/path_provider/path_provider/pubspec.yaml b/packages/path_provider/path_provider/pubspec.yaml index 3ee67007f97d..6cb451344a3d 100644 --- a/packages/path_provider/path_provider/pubspec.yaml +++ b/packages/path_provider/path_provider/pubspec.yaml @@ -28,7 +28,7 @@ dependencies: dev_dependencies: integration_test: - path: ../../integration_test + sdk: flutter flutter_test: sdk: flutter flutter_driver: diff --git a/packages/path_provider/path_provider_linux/example/pubspec.yaml b/packages/path_provider/path_provider_linux/example/pubspec.yaml index cb778ef6ac57..c9c2f47bf654 100644 --- a/packages/path_provider/path_provider_linux/example/pubspec.yaml +++ b/packages/path_provider/path_provider_linux/example/pubspec.yaml @@ -24,7 +24,7 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: - path: ../../../integration_test + sdk: flutter flutter: uses-material-design: true diff --git a/packages/path_provider/path_provider_macos/example/pubspec.yaml b/packages/path_provider/path_provider_macos/example/pubspec.yaml index db7fd9a0dea6..1451dea36362 100644 --- a/packages/path_provider/path_provider_macos/example/pubspec.yaml +++ b/packages/path_provider/path_provider_macos/example/pubspec.yaml @@ -15,7 +15,7 @@ dependencies: dev_dependencies: integration_test: - path: ../../../integration_test + sdk: flutter flutter_driver: sdk: flutter pedantic: ^1.8.0 diff --git a/packages/path_provider/path_provider_windows/example/pubspec.yaml b/packages/path_provider/path_provider_windows/example/pubspec.yaml index 8c1f88b89cb0..29e228d0fd19 100644 --- a/packages/path_provider/path_provider_windows/example/pubspec.yaml +++ b/packages/path_provider/path_provider_windows/example/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: dev_dependencies: integration_test: - path: ../../../integration_test + sdk: flutter flutter_driver: sdk: flutter pedantic: ^1.10.0 diff --git a/packages/quick_actions/example/pubspec.yaml b/packages/quick_actions/example/pubspec.yaml index ded88685c41b..b26f8432e9ad 100644 --- a/packages/quick_actions/example/pubspec.yaml +++ b/packages/quick_actions/example/pubspec.yaml @@ -16,7 +16,7 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: - path: ../../integration_test + sdk: flutter pedantic: ^1.10.0 flutter: diff --git a/packages/quick_actions/pubspec.yaml b/packages/quick_actions/pubspec.yaml index dc500e2516e1..ed6555833b83 100644 --- a/packages/quick_actions/pubspec.yaml +++ b/packages/quick_actions/pubspec.yaml @@ -23,7 +23,7 @@ dev_dependencies: flutter_test: sdk: flutter integration_test: - path: ../integration_test + sdk: flutter pedantic: ^1.10.0 environment: diff --git a/packages/sensors/example/pubspec.yaml b/packages/sensors/example/pubspec.yaml index 0cd30b12df2b..7d8effbcce87 100644 --- a/packages/sensors/example/pubspec.yaml +++ b/packages/sensors/example/pubspec.yaml @@ -16,7 +16,7 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: - path: ../../integration_test + sdk: flutter pedantic: ^1.10.0 flutter: diff --git a/packages/sensors/pubspec.yaml b/packages/sensors/pubspec.yaml index da45c82b7dd7..8056d99d07ed 100644 --- a/packages/sensors/pubspec.yaml +++ b/packages/sensors/pubspec.yaml @@ -22,7 +22,7 @@ dev_dependencies: flutter_test: sdk: flutter integration_test: - path: ../integration_test + sdk: flutter mockito: ^5.0.0-nullsafety.0 pedantic: ^1.10.0 diff --git a/packages/share/example/pubspec.yaml b/packages/share/example/pubspec.yaml index 2df76efb6ca2..378e25bc9c75 100644 --- a/packages/share/example/pubspec.yaml +++ b/packages/share/example/pubspec.yaml @@ -17,7 +17,7 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: - path: ../../integration_test + sdk: flutter pedantic: ^1.10.0 flutter: diff --git a/packages/share/pubspec.yaml b/packages/share/pubspec.yaml index dd82fb4926bf..5f2c9f0a400b 100644 --- a/packages/share/pubspec.yaml +++ b/packages/share/pubspec.yaml @@ -23,7 +23,7 @@ dev_dependencies: flutter_test: sdk: flutter integration_test: - path: ../integration_test + sdk: flutter pedantic: ^1.10.0 environment: diff --git a/packages/shared_preferences/shared_preferences/example/pubspec.yaml b/packages/shared_preferences/shared_preferences/example/pubspec.yaml index 84692d76e5a1..7a7b1ac7402f 100644 --- a/packages/shared_preferences/shared_preferences/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/example/pubspec.yaml @@ -16,7 +16,7 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: - path: ../../../integration_test + sdk: flutter pedantic: ^1.10.0 flutter: diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index 3f8391f188d7..ad809b2564bd 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -42,7 +42,7 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: - path: ../../integration_test + sdk: flutter pedantic: ^1.10.0 environment: diff --git a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml index dffdbd7526d2..a3a3cbced044 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml @@ -16,7 +16,7 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: - path: ../../../integration_test + sdk: flutter pedantic: ^1.10.0 flutter: diff --git a/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml index 7db361fccfd5..8ad710c6b984 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_macos/example/pubspec.yaml @@ -17,7 +17,7 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: - path: ../../../integration_test + sdk: flutter pedantic: ^1.10.0 flutter: diff --git a/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml index 6725259c4bdc..e83598703a4b 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml @@ -23,7 +23,7 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: - path: ../../../integration_test + sdk: flutter pedantic: ^1.10.0 flutter: diff --git a/packages/url_launcher/url_launcher/example/pubspec.yaml b/packages/url_launcher/url_launcher/example/pubspec.yaml index 0bc027de90a8..4ab235328e46 100644 --- a/packages/url_launcher/url_launcher/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher/example/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: dev_dependencies: integration_test: - path: ../../../integration_test + sdk: flutter flutter_driver: sdk: flutter pedantic: ^1.10.0 diff --git a/packages/url_launcher/url_launcher_linux/example/pubspec.yaml b/packages/url_launcher/url_launcher_linux/example/pubspec.yaml index 63c920fba614..e0c59fbbde54 100644 --- a/packages/url_launcher/url_launcher_linux/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_linux/example/pubspec.yaml @@ -15,7 +15,7 @@ dependencies: dev_dependencies: integration_test: - path: ../../../integration_test + sdk: flutter flutter_driver: sdk: flutter pedantic: ^1.10.0 diff --git a/packages/url_launcher/url_launcher_macos/example/pubspec.yaml b/packages/url_launcher/url_launcher_macos/example/pubspec.yaml index 40bb4eaba67a..595d1bc30dae 100644 --- a/packages/url_launcher/url_launcher_macos/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_macos/example/pubspec.yaml @@ -15,7 +15,7 @@ dependencies: dev_dependencies: integration_test: - path: ../../../integration_test + sdk: flutter flutter_driver: sdk: flutter pedantic: ^1.10.0 diff --git a/packages/url_launcher/url_launcher_windows/example/pubspec.yaml b/packages/url_launcher/url_launcher_windows/example/pubspec.yaml index 8a273ba65020..86ceeecc369f 100644 --- a/packages/url_launcher/url_launcher_windows/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_windows/example/pubspec.yaml @@ -15,7 +15,7 @@ dependencies: dev_dependencies: integration_test: - path: ../../../integration_test + sdk: flutter flutter_driver: sdk: flutter pedantic: ^1.10.0 diff --git a/packages/video_player/video_player/example/pubspec.yaml b/packages/video_player/video_player/example/pubspec.yaml index 4bfb3e5fefad..354f3d18df00 100644 --- a/packages/video_player/video_player/example/pubspec.yaml +++ b/packages/video_player/video_player/example/pubspec.yaml @@ -20,7 +20,7 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: - path: ../../../integration_test + sdk: flutter test: any pedantic: ^1.10.0 diff --git a/packages/webview_flutter/example/pubspec.yaml b/packages/webview_flutter/example/pubspec.yaml index d7688b720f3f..b70674197901 100644 --- a/packages/webview_flutter/example/pubspec.yaml +++ b/packages/webview_flutter/example/pubspec.yaml @@ -21,7 +21,7 @@ dev_dependencies: flutter_driver: sdk: flutter integration_test: - path: ../../integration_test + sdk: flutter pedantic: ^1.10.0 flutter: diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/pubspec.yaml b/packages/wifi_info_flutter/wifi_info_flutter/example/pubspec.yaml index bd424859abf2..57edbe86daea 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/pubspec.yaml +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/pubspec.yaml @@ -19,7 +19,7 @@ dependencies: dev_dependencies: integration_test: - path: ../../../integration_test + sdk: flutter flutter_test: sdk: flutter diff --git a/packages/wifi_info_flutter/wifi_info_flutter/pubspec.yaml b/packages/wifi_info_flutter/wifi_info_flutter/pubspec.yaml index 7b58d481f6c7..1742f9b86099 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/pubspec.yaml +++ b/packages/wifi_info_flutter/wifi_info_flutter/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: dev_dependencies: integration_test: - path: ../../integration_test + sdk: flutter flutter_test: sdk: flutter From aa8e61503f205a664b54e2cbcd2a62a02ce2010b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl?= <32639467+danielroek@users.noreply.github.com> Date: Fri, 19 Mar 2021 15:40:06 +0100 Subject: [PATCH 0282/1565] Moved quickactions to a subfolder (#3734) --- packages/quick_actions/example/android.iml | 12 ------------ .../example/quick_actions_example.iml | 15 --------------- .../example/quick_actions_example_android.iml | 12 ------------ .../{ => quick_actions}/CHANGELOG.md | 0 .../quick_actions/{ => quick_actions}/LICENSE | 0 .../quick_actions/{ => quick_actions}/README.md | 0 .../{ => quick_actions}/android/build.gradle | 0 .../android/gradle.properties | 0 .../{ => quick_actions}/android/settings.gradle | 0 .../android/src/main/AndroidManifest.xml | 0 .../quickactions/MethodCallHandlerImpl.java | 0 .../plugins/quickactions/QuickActionsPlugin.java | 0 .../{ => quick_actions}/example/README.md | 0 .../example/android/app/build.gradle | 0 .../app/gradle/wrapper/gradle-wrapper.properties | 0 .../android/app/src/main/AndroidManifest.xml | 0 .../quickactionsexample/EmbeddingV1Activity.java | 0 .../EmbeddingV1ActivityTest.java | 0 .../quickactionsexample/FlutterActivityTest.java | 0 .../main/res/drawable/ic_launcher_background.xml | 0 .../app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../src/main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../src/main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../android/app/src/main/res/values/styles.xml | 0 .../example/android/build.gradle | 0 .../example/android/gradle.properties | 0 .../gradle/wrapper/gradle-wrapper.properties | 0 .../example/android/settings.gradle | 0 .../integration_test/quick_actions_test.dart | 0 .../example/ios/Flutter/AppFrameworkInfo.plist | 0 .../example/ios/Flutter/Debug.xcconfig | 0 .../example/ios/Flutter/Release.xcconfig | 0 .../example/ios/Runner.xcodeproj/project.pbxproj | 0 .../xcshareddata/xcschemes/Runner.xcscheme | 0 .../xcschemes/RunnerUITests.xcscheme | 0 .../Runner.xcworkspace/contents.xcworkspacedata | 0 .../example/ios/Runner/AppDelegate.h | 0 .../example/ios/Runner/AppDelegate.m | 0 .../AppIcon.appiconset/Contents.json | 0 .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin .../AppIcon.appiconset/Icon-App-83.5x83.5@2x.png | Bin .../Runner/Base.lproj/LaunchScreen.storyboard | 0 .../ios/Runner/Base.lproj/Main.storyboard | 0 .../example/ios/Runner/Info.plist | 0 .../example/ios/Runner/main.m | 0 .../example/ios/RunnerUITests/Info.plist | 0 .../example/ios/RunnerUITests/RunnerUITests.m | 0 .../{ => quick_actions}/example/lib/main.dart | 0 .../{ => quick_actions}/example/pubspec.yaml | 0 .../example/test_driver/integration_test.dart | 0 .../{ => quick_actions}/ios/Assets/.gitkeep | 0 .../ios/Classes/FLTQuickActionsPlugin.h | 0 .../ios/Classes/FLTQuickActionsPlugin.m | 0 .../ios/quick_actions.podspec | 0 .../{ => quick_actions}/lib/quick_actions.dart | 0 .../{ => quick_actions}/pubspec.yaml | 0 .../test/quick_actions_test.dart | 0 packages/quick_actions/quick_actions_android.iml | 12 ------------ 72 files changed, 51 deletions(-) delete mode 100644 packages/quick_actions/example/android.iml delete mode 100644 packages/quick_actions/example/quick_actions_example.iml delete mode 100644 packages/quick_actions/example/quick_actions_example_android.iml rename packages/quick_actions/{ => quick_actions}/CHANGELOG.md (100%) rename packages/quick_actions/{ => quick_actions}/LICENSE (100%) rename packages/quick_actions/{ => quick_actions}/README.md (100%) rename packages/quick_actions/{ => quick_actions}/android/build.gradle (100%) rename packages/quick_actions/{ => quick_actions}/android/gradle.properties (100%) rename packages/quick_actions/{ => quick_actions}/android/settings.gradle (100%) rename packages/quick_actions/{ => quick_actions}/android/src/main/AndroidManifest.xml (100%) rename packages/quick_actions/{ => quick_actions}/android/src/main/java/io/flutter/plugins/quickactions/MethodCallHandlerImpl.java (100%) rename packages/quick_actions/{ => quick_actions}/android/src/main/java/io/flutter/plugins/quickactions/QuickActionsPlugin.java (100%) rename packages/quick_actions/{ => quick_actions}/example/README.md (100%) rename packages/quick_actions/{ => quick_actions}/example/android/app/build.gradle (100%) rename packages/quick_actions/{ => quick_actions}/example/android/app/gradle/wrapper/gradle-wrapper.properties (100%) rename packages/quick_actions/{ => quick_actions}/example/android/app/src/main/AndroidManifest.xml (100%) rename packages/quick_actions/{ => quick_actions}/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1Activity.java (100%) rename packages/quick_actions/{ => quick_actions}/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1ActivityTest.java (100%) rename packages/quick_actions/{ => quick_actions}/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/FlutterActivityTest.java (100%) rename packages/quick_actions/{ => quick_actions}/example/android/app/src/main/res/drawable/ic_launcher_background.xml (100%) rename packages/quick_actions/{ => quick_actions}/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename packages/quick_actions/{ => quick_actions}/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename packages/quick_actions/{ => quick_actions}/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename packages/quick_actions/{ => quick_actions}/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename packages/quick_actions/{ => quick_actions}/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename packages/quick_actions/{ => quick_actions}/example/android/app/src/main/res/values/styles.xml (100%) rename packages/quick_actions/{ => quick_actions}/example/android/build.gradle (100%) rename packages/quick_actions/{ => quick_actions}/example/android/gradle.properties (100%) rename packages/quick_actions/{ => quick_actions}/example/android/gradle/wrapper/gradle-wrapper.properties (100%) rename packages/quick_actions/{ => quick_actions}/example/android/settings.gradle (100%) rename packages/quick_actions/{ => quick_actions}/example/integration_test/quick_actions_test.dart (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Flutter/AppFrameworkInfo.plist (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Flutter/Debug.xcconfig (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Flutter/Release.xcconfig (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner.xcodeproj/project.pbxproj (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/RunnerUITests.xcscheme (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner.xcworkspace/contents.xcworkspacedata (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/AppDelegate.h (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/AppDelegate.m (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/Base.lproj/LaunchScreen.storyboard (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/Base.lproj/Main.storyboard (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/Info.plist (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/Runner/main.m (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/RunnerUITests/Info.plist (100%) rename packages/quick_actions/{ => quick_actions}/example/ios/RunnerUITests/RunnerUITests.m (100%) rename packages/quick_actions/{ => quick_actions}/example/lib/main.dart (100%) rename packages/quick_actions/{ => quick_actions}/example/pubspec.yaml (100%) rename packages/quick_actions/{ => quick_actions}/example/test_driver/integration_test.dart (100%) rename packages/quick_actions/{ => quick_actions}/ios/Assets/.gitkeep (100%) rename packages/quick_actions/{ => quick_actions}/ios/Classes/FLTQuickActionsPlugin.h (100%) rename packages/quick_actions/{ => quick_actions}/ios/Classes/FLTQuickActionsPlugin.m (100%) rename packages/quick_actions/{ => quick_actions}/ios/quick_actions.podspec (100%) rename packages/quick_actions/{ => quick_actions}/lib/quick_actions.dart (100%) rename packages/quick_actions/{ => quick_actions}/pubspec.yaml (100%) rename packages/quick_actions/{ => quick_actions}/test/quick_actions_test.dart (100%) delete mode 100644 packages/quick_actions/quick_actions_android.iml diff --git a/packages/quick_actions/example/android.iml b/packages/quick_actions/example/android.iml deleted file mode 100644 index 462b903e05b6..000000000000 --- a/packages/quick_actions/example/android.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/packages/quick_actions/example/quick_actions_example.iml b/packages/quick_actions/example/quick_actions_example.iml deleted file mode 100644 index 9d5dae19540c..000000000000 --- a/packages/quick_actions/example/quick_actions_example.iml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/quick_actions/example/quick_actions_example_android.iml b/packages/quick_actions/example/quick_actions_example_android.iml deleted file mode 100644 index 462b903e05b6..000000000000 --- a/packages/quick_actions/example/quick_actions_example_android.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/packages/quick_actions/CHANGELOG.md b/packages/quick_actions/quick_actions/CHANGELOG.md similarity index 100% rename from packages/quick_actions/CHANGELOG.md rename to packages/quick_actions/quick_actions/CHANGELOG.md diff --git a/packages/quick_actions/LICENSE b/packages/quick_actions/quick_actions/LICENSE similarity index 100% rename from packages/quick_actions/LICENSE rename to packages/quick_actions/quick_actions/LICENSE diff --git a/packages/quick_actions/README.md b/packages/quick_actions/quick_actions/README.md similarity index 100% rename from packages/quick_actions/README.md rename to packages/quick_actions/quick_actions/README.md diff --git a/packages/quick_actions/android/build.gradle b/packages/quick_actions/quick_actions/android/build.gradle similarity index 100% rename from packages/quick_actions/android/build.gradle rename to packages/quick_actions/quick_actions/android/build.gradle diff --git a/packages/quick_actions/android/gradle.properties b/packages/quick_actions/quick_actions/android/gradle.properties similarity index 100% rename from packages/quick_actions/android/gradle.properties rename to packages/quick_actions/quick_actions/android/gradle.properties diff --git a/packages/quick_actions/android/settings.gradle b/packages/quick_actions/quick_actions/android/settings.gradle similarity index 100% rename from packages/quick_actions/android/settings.gradle rename to packages/quick_actions/quick_actions/android/settings.gradle diff --git a/packages/quick_actions/android/src/main/AndroidManifest.xml b/packages/quick_actions/quick_actions/android/src/main/AndroidManifest.xml similarity index 100% rename from packages/quick_actions/android/src/main/AndroidManifest.xml rename to packages/quick_actions/quick_actions/android/src/main/AndroidManifest.xml diff --git a/packages/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/MethodCallHandlerImpl.java b/packages/quick_actions/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/MethodCallHandlerImpl.java similarity index 100% rename from packages/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/MethodCallHandlerImpl.java rename to packages/quick_actions/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/MethodCallHandlerImpl.java diff --git a/packages/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/QuickActionsPlugin.java b/packages/quick_actions/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/QuickActionsPlugin.java similarity index 100% rename from packages/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/QuickActionsPlugin.java rename to packages/quick_actions/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/QuickActionsPlugin.java diff --git a/packages/quick_actions/example/README.md b/packages/quick_actions/quick_actions/example/README.md similarity index 100% rename from packages/quick_actions/example/README.md rename to packages/quick_actions/quick_actions/example/README.md diff --git a/packages/quick_actions/example/android/app/build.gradle b/packages/quick_actions/quick_actions/example/android/app/build.gradle similarity index 100% rename from packages/quick_actions/example/android/app/build.gradle rename to packages/quick_actions/quick_actions/example/android/app/build.gradle diff --git a/packages/quick_actions/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/quick_actions/quick_actions/example/android/app/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from packages/quick_actions/example/android/app/gradle/wrapper/gradle-wrapper.properties rename to packages/quick_actions/quick_actions/example/android/app/gradle/wrapper/gradle-wrapper.properties diff --git a/packages/quick_actions/example/android/app/src/main/AndroidManifest.xml b/packages/quick_actions/quick_actions/example/android/app/src/main/AndroidManifest.xml similarity index 100% rename from packages/quick_actions/example/android/app/src/main/AndroidManifest.xml rename to packages/quick_actions/quick_actions/example/android/app/src/main/AndroidManifest.xml diff --git a/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1Activity.java b/packages/quick_actions/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1Activity.java similarity index 100% rename from packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1Activity.java rename to packages/quick_actions/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1Activity.java diff --git a/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1ActivityTest.java b/packages/quick_actions/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1ActivityTest.java similarity index 100% rename from packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1ActivityTest.java rename to packages/quick_actions/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1ActivityTest.java diff --git a/packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/FlutterActivityTest.java b/packages/quick_actions/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/FlutterActivityTest.java similarity index 100% rename from packages/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/FlutterActivityTest.java rename to packages/quick_actions/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/FlutterActivityTest.java diff --git a/packages/quick_actions/example/android/app/src/main/res/drawable/ic_launcher_background.xml b/packages/quick_actions/quick_actions/example/android/app/src/main/res/drawable/ic_launcher_background.xml similarity index 100% rename from packages/quick_actions/example/android/app/src/main/res/drawable/ic_launcher_background.xml rename to packages/quick_actions/quick_actions/example/android/app/src/main/res/drawable/ic_launcher_background.xml diff --git a/packages/quick_actions/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/packages/quick_actions/quick_actions/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from packages/quick_actions/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png rename to packages/quick_actions/quick_actions/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/packages/quick_actions/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/packages/quick_actions/quick_actions/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from packages/quick_actions/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png rename to packages/quick_actions/quick_actions/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/packages/quick_actions/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/packages/quick_actions/quick_actions/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from packages/quick_actions/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to packages/quick_actions/quick_actions/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/packages/quick_actions/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/packages/quick_actions/quick_actions/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from packages/quick_actions/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to packages/quick_actions/quick_actions/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/packages/quick_actions/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/packages/quick_actions/quick_actions/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from packages/quick_actions/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to packages/quick_actions/quick_actions/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/packages/quick_actions/example/android/app/src/main/res/values/styles.xml b/packages/quick_actions/quick_actions/example/android/app/src/main/res/values/styles.xml similarity index 100% rename from packages/quick_actions/example/android/app/src/main/res/values/styles.xml rename to packages/quick_actions/quick_actions/example/android/app/src/main/res/values/styles.xml diff --git a/packages/quick_actions/example/android/build.gradle b/packages/quick_actions/quick_actions/example/android/build.gradle similarity index 100% rename from packages/quick_actions/example/android/build.gradle rename to packages/quick_actions/quick_actions/example/android/build.gradle diff --git a/packages/quick_actions/example/android/gradle.properties b/packages/quick_actions/quick_actions/example/android/gradle.properties similarity index 100% rename from packages/quick_actions/example/android/gradle.properties rename to packages/quick_actions/quick_actions/example/android/gradle.properties diff --git a/packages/quick_actions/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/quick_actions/quick_actions/example/android/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from packages/quick_actions/example/android/gradle/wrapper/gradle-wrapper.properties rename to packages/quick_actions/quick_actions/example/android/gradle/wrapper/gradle-wrapper.properties diff --git a/packages/quick_actions/example/android/settings.gradle b/packages/quick_actions/quick_actions/example/android/settings.gradle similarity index 100% rename from packages/quick_actions/example/android/settings.gradle rename to packages/quick_actions/quick_actions/example/android/settings.gradle diff --git a/packages/quick_actions/example/integration_test/quick_actions_test.dart b/packages/quick_actions/quick_actions/example/integration_test/quick_actions_test.dart similarity index 100% rename from packages/quick_actions/example/integration_test/quick_actions_test.dart rename to packages/quick_actions/quick_actions/example/integration_test/quick_actions_test.dart diff --git a/packages/quick_actions/example/ios/Flutter/AppFrameworkInfo.plist b/packages/quick_actions/quick_actions/example/ios/Flutter/AppFrameworkInfo.plist similarity index 100% rename from packages/quick_actions/example/ios/Flutter/AppFrameworkInfo.plist rename to packages/quick_actions/quick_actions/example/ios/Flutter/AppFrameworkInfo.plist diff --git a/packages/quick_actions/example/ios/Flutter/Debug.xcconfig b/packages/quick_actions/quick_actions/example/ios/Flutter/Debug.xcconfig similarity index 100% rename from packages/quick_actions/example/ios/Flutter/Debug.xcconfig rename to packages/quick_actions/quick_actions/example/ios/Flutter/Debug.xcconfig diff --git a/packages/quick_actions/example/ios/Flutter/Release.xcconfig b/packages/quick_actions/quick_actions/example/ios/Flutter/Release.xcconfig similarity index 100% rename from packages/quick_actions/example/ios/Flutter/Release.xcconfig rename to packages/quick_actions/quick_actions/example/ios/Flutter/Release.xcconfig diff --git a/packages/quick_actions/example/ios/Runner.xcodeproj/project.pbxproj b/packages/quick_actions/quick_actions/example/ios/Runner.xcodeproj/project.pbxproj similarity index 100% rename from packages/quick_actions/example/ios/Runner.xcodeproj/project.pbxproj rename to packages/quick_actions/quick_actions/example/ios/Runner.xcodeproj/project.pbxproj diff --git a/packages/quick_actions/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/quick_actions/quick_actions/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme similarity index 100% rename from packages/quick_actions/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme rename to packages/quick_actions/quick_actions/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme diff --git a/packages/quick_actions/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/RunnerUITests.xcscheme b/packages/quick_actions/quick_actions/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/RunnerUITests.xcscheme similarity index 100% rename from packages/quick_actions/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/RunnerUITests.xcscheme rename to packages/quick_actions/quick_actions/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/RunnerUITests.xcscheme diff --git a/packages/quick_actions/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/quick_actions/quick_actions/example/ios/Runner.xcworkspace/contents.xcworkspacedata similarity index 100% rename from packages/quick_actions/example/ios/Runner.xcworkspace/contents.xcworkspacedata rename to packages/quick_actions/quick_actions/example/ios/Runner.xcworkspace/contents.xcworkspacedata diff --git a/packages/quick_actions/example/ios/Runner/AppDelegate.h b/packages/quick_actions/quick_actions/example/ios/Runner/AppDelegate.h similarity index 100% rename from packages/quick_actions/example/ios/Runner/AppDelegate.h rename to packages/quick_actions/quick_actions/example/ios/Runner/AppDelegate.h diff --git a/packages/quick_actions/example/ios/Runner/AppDelegate.m b/packages/quick_actions/quick_actions/example/ios/Runner/AppDelegate.m similarity index 100% rename from packages/quick_actions/example/ios/Runner/AppDelegate.m rename to packages/quick_actions/quick_actions/example/ios/Runner/AppDelegate.m diff --git a/packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json rename to packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png similarity index 100% rename from packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png rename to packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png diff --git a/packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png similarity index 100% rename from packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png rename to packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png diff --git a/packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png similarity index 100% rename from packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png rename to packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png diff --git a/packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png similarity index 100% rename from packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png rename to packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png diff --git a/packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png similarity index 100% rename from packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png rename to packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png diff --git a/packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png similarity index 100% rename from packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png rename to packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png diff --git a/packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png similarity index 100% rename from packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png rename to packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png diff --git a/packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png similarity index 100% rename from packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png rename to packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png diff --git a/packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png similarity index 100% rename from packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png rename to packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png diff --git a/packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png similarity index 100% rename from packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png rename to packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png diff --git a/packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png similarity index 100% rename from packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png rename to packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png diff --git a/packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png similarity index 100% rename from packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png rename to packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png diff --git a/packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png similarity index 100% rename from packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png rename to packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png diff --git a/packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png similarity index 100% rename from packages/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png rename to packages/quick_actions/quick_actions/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png diff --git a/packages/quick_actions/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/quick_actions/quick_actions/example/ios/Runner/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from packages/quick_actions/example/ios/Runner/Base.lproj/LaunchScreen.storyboard rename to packages/quick_actions/quick_actions/example/ios/Runner/Base.lproj/LaunchScreen.storyboard diff --git a/packages/quick_actions/example/ios/Runner/Base.lproj/Main.storyboard b/packages/quick_actions/quick_actions/example/ios/Runner/Base.lproj/Main.storyboard similarity index 100% rename from packages/quick_actions/example/ios/Runner/Base.lproj/Main.storyboard rename to packages/quick_actions/quick_actions/example/ios/Runner/Base.lproj/Main.storyboard diff --git a/packages/quick_actions/example/ios/Runner/Info.plist b/packages/quick_actions/quick_actions/example/ios/Runner/Info.plist similarity index 100% rename from packages/quick_actions/example/ios/Runner/Info.plist rename to packages/quick_actions/quick_actions/example/ios/Runner/Info.plist diff --git a/packages/quick_actions/example/ios/Runner/main.m b/packages/quick_actions/quick_actions/example/ios/Runner/main.m similarity index 100% rename from packages/quick_actions/example/ios/Runner/main.m rename to packages/quick_actions/quick_actions/example/ios/Runner/main.m diff --git a/packages/quick_actions/example/ios/RunnerUITests/Info.plist b/packages/quick_actions/quick_actions/example/ios/RunnerUITests/Info.plist similarity index 100% rename from packages/quick_actions/example/ios/RunnerUITests/Info.plist rename to packages/quick_actions/quick_actions/example/ios/RunnerUITests/Info.plist diff --git a/packages/quick_actions/example/ios/RunnerUITests/RunnerUITests.m b/packages/quick_actions/quick_actions/example/ios/RunnerUITests/RunnerUITests.m similarity index 100% rename from packages/quick_actions/example/ios/RunnerUITests/RunnerUITests.m rename to packages/quick_actions/quick_actions/example/ios/RunnerUITests/RunnerUITests.m diff --git a/packages/quick_actions/example/lib/main.dart b/packages/quick_actions/quick_actions/example/lib/main.dart similarity index 100% rename from packages/quick_actions/example/lib/main.dart rename to packages/quick_actions/quick_actions/example/lib/main.dart diff --git a/packages/quick_actions/example/pubspec.yaml b/packages/quick_actions/quick_actions/example/pubspec.yaml similarity index 100% rename from packages/quick_actions/example/pubspec.yaml rename to packages/quick_actions/quick_actions/example/pubspec.yaml diff --git a/packages/quick_actions/example/test_driver/integration_test.dart b/packages/quick_actions/quick_actions/example/test_driver/integration_test.dart similarity index 100% rename from packages/quick_actions/example/test_driver/integration_test.dart rename to packages/quick_actions/quick_actions/example/test_driver/integration_test.dart diff --git a/packages/quick_actions/ios/Assets/.gitkeep b/packages/quick_actions/quick_actions/ios/Assets/.gitkeep similarity index 100% rename from packages/quick_actions/ios/Assets/.gitkeep rename to packages/quick_actions/quick_actions/ios/Assets/.gitkeep diff --git a/packages/quick_actions/ios/Classes/FLTQuickActionsPlugin.h b/packages/quick_actions/quick_actions/ios/Classes/FLTQuickActionsPlugin.h similarity index 100% rename from packages/quick_actions/ios/Classes/FLTQuickActionsPlugin.h rename to packages/quick_actions/quick_actions/ios/Classes/FLTQuickActionsPlugin.h diff --git a/packages/quick_actions/ios/Classes/FLTQuickActionsPlugin.m b/packages/quick_actions/quick_actions/ios/Classes/FLTQuickActionsPlugin.m similarity index 100% rename from packages/quick_actions/ios/Classes/FLTQuickActionsPlugin.m rename to packages/quick_actions/quick_actions/ios/Classes/FLTQuickActionsPlugin.m diff --git a/packages/quick_actions/ios/quick_actions.podspec b/packages/quick_actions/quick_actions/ios/quick_actions.podspec similarity index 100% rename from packages/quick_actions/ios/quick_actions.podspec rename to packages/quick_actions/quick_actions/ios/quick_actions.podspec diff --git a/packages/quick_actions/lib/quick_actions.dart b/packages/quick_actions/quick_actions/lib/quick_actions.dart similarity index 100% rename from packages/quick_actions/lib/quick_actions.dart rename to packages/quick_actions/quick_actions/lib/quick_actions.dart diff --git a/packages/quick_actions/pubspec.yaml b/packages/quick_actions/quick_actions/pubspec.yaml similarity index 100% rename from packages/quick_actions/pubspec.yaml rename to packages/quick_actions/quick_actions/pubspec.yaml diff --git a/packages/quick_actions/test/quick_actions_test.dart b/packages/quick_actions/quick_actions/test/quick_actions_test.dart similarity index 100% rename from packages/quick_actions/test/quick_actions_test.dart rename to packages/quick_actions/quick_actions/test/quick_actions_test.dart diff --git a/packages/quick_actions/quick_actions_android.iml b/packages/quick_actions/quick_actions_android.iml deleted file mode 100644 index 462b903e05b6..000000000000 --- a/packages/quick_actions/quick_actions_android.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - From 67bdfcb5b6f49286dcc17a58107ddd1ab2b20472 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 19 Mar 2021 13:18:00 -0700 Subject: [PATCH 0283/1565] Standardize copyright year (#3737) Standardizes all first-party copyrights on a single year, as is done in flutter/flutter and flutter/engine. All code now uses 2013, which is the earliest year that was in any existing copyright notice. The script checks now enforce the exact format of first-party licenses and copyrights. Fixes flutter/flutter#78448 --- LICENSE | 2 +- packages/android_alarm_manager/LICENSE | 2 +- .../AlarmBroadcastReceiver.java | 2 +- .../androidalarmmanager/AlarmService.java | 2 +- .../AndroidAlarmManagerPlugin.java | 2 +- .../FlutterBackgroundExecutor.java | 2 +- .../PluginRegistrantException.java | 2 +- .../RebootBroadcastReceiver.java | 2 +- .../BackgroundExecutionTest.java | 2 +- .../DriverExtensionActivity.java | 2 +- .../androidalarmmanager/MainActivityTest.java | 2 +- .../Application.java | 2 +- .../EmbeddingV1Activity.java | 2 +- .../android_alarm_manager_test.dart | 2 +- .../example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../lib/android_alarm_manager.dart | 2 +- .../test/android_alarm_manager_test.dart | 2 +- packages/android_intent/LICENSE | 2 +- .../androidintent/AndroidIntentPlugin.java | 2 +- .../plugins/androidintent/IntentSender.java | 2 +- .../androidintent/MethodCallHandlerImpl.java | 2 +- .../MethodCallHandlerImplTest.java | 2 +- .../EmbeddingV1ActivityTest.java | 2 +- .../MainActivityTest.java | 2 +- .../EmbeddingV1Activity.java | 2 +- .../integration_test/android_intent_test.dart | 2 +- packages/android_intent/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../android_intent/lib/android_intent.dart | 2 +- packages/android_intent/lib/flag.dart | 2 +- .../test/android_intent_test.dart | 2 +- packages/battery/battery/LICENSE | 2 +- .../plugins/battery/BatteryPlugin.java | 2 +- .../battery/EmbedderV1ActivityTest.java | 2 +- .../plugins/battery/FlutterActivityTest.java | 2 +- .../batteryexample/EmbedderV1Activity.java | 2 +- .../battery/example/ios/Runner/AppDelegate.h | 2 +- .../battery/example/ios/Runner/AppDelegate.m | 2 +- .../battery/battery/example/ios/Runner/main.m | 2 +- .../battery/battery/example/lib/main.dart | 2 +- .../integration_test/battery_test.dart | 2 +- .../battery/ios/Classes/FLTBatteryPlugin.h | 2 +- .../battery/ios/Classes/FLTBatteryPlugin.m | 2 +- packages/battery/battery/lib/battery.dart | 2 +- .../battery/battery/test/battery_test.dart | 2 +- .../battery_platform_interface/LICENSE | 2 +- .../lib/battery_platform_interface.dart | 2 +- .../lib/enums/battery_state.dart | 2 +- .../method_channel_battery.dart | 2 +- .../test/method_channel_battery_test.dart | 2 +- packages/camera/camera/LICENSE | 2 +- .../io/flutter/plugins/camera/Camera.java | 2 +- .../plugins/camera/CameraPermissions.java | 2 +- .../flutter/plugins/camera/CameraPlugin.java | 2 +- .../flutter/plugins/camera/CameraRegions.java | 2 +- .../flutter/plugins/camera/CameraUtils.java | 2 +- .../io/flutter/plugins/camera/CameraZoom.java | 2 +- .../flutter/plugins/camera/DartMessenger.java | 2 +- .../camera/DeviceOrientationManager.java | 2 +- .../plugins/camera/MethodCallHandlerImpl.java | 2 +- .../plugins/camera/PictureCaptureRequest.java | 2 +- .../camera/media/MediaRecorderBuilder.java | 2 +- .../plugins/camera/types/ExposureMode.java | 2 +- .../plugins/camera/types/FlashMode.java | 2 +- .../plugins/camera/types/FocusMode.java | 2 +- .../camera/types/ResolutionPreset.java | 2 +- .../plugins/camera/CameraPermissionsTest.java | 2 +- .../plugins/camera/CameraRegionsTest.java | 2 +- .../plugins/camera/CameraUtilsTest.java | 2 +- .../plugins/camera/CameraZoomTest.java | 2 +- .../plugins/camera/DartMessengerTest.java | 2 +- .../camera/PictureCaptureRequestTest.java | 2 +- .../media/MediaRecorderBuilderTest.java | 2 +- .../camera/types/ExposureModeTest.java | 2 +- .../plugins/camera/types/FlashModeTest.java | 2 +- .../plugins/camera/types/FocusModeTest.java | 2 +- .../EmbeddingV1ActivityTest.java | 2 +- .../cameraexample/FlutterActivityTest.java | 2 +- .../cameraexample/EmbeddingV1Activity.java | 2 +- .../example/integration_test/camera_test.dart | 2 +- .../camera/example/ios/Runner/AppDelegate.h | 2 +- .../camera/example/ios/Runner/AppDelegate.m | 2 +- .../camera/camera/example/ios/Runner/main.m | 2 +- packages/camera/camera/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../camera/camera/ios/Classes/CameraPlugin.h | 2 +- .../camera/camera/ios/Classes/CameraPlugin.m | 2 +- .../camera/ios/Tests/CameraPluginTests.m | 2 +- packages/camera/camera/lib/camera.dart | 2 +- .../camera/lib/src/camera_controller.dart | 2 +- .../camera/camera/lib/src/camera_image.dart | 2 +- .../camera/camera/lib/src/camera_preview.dart | 2 +- .../camera/test/camera_image_stream_test.dart | 2 +- .../camera/camera/test/camera_image_test.dart | 2 +- packages/camera/camera/test/camera_test.dart | 2 +- .../camera/camera/test/camera_value_test.dart | 2 +- .../test/utils/method_channel_mock.dart | 2 +- .../camera/camera_platform_interface/LICENSE | 2 +- .../lib/camera_platform_interface.dart | 2 +- .../lib/src/events/camera_event.dart | 2 +- .../lib/src/events/device_event.dart | 2 +- .../method_channel/method_channel_camera.dart | 2 +- .../platform_interface/camera_platform.dart | 2 +- .../lib/src/types/camera_description.dart | 2 +- .../lib/src/types/camera_exception.dart | 2 +- .../lib/src/types/exposure_mode.dart | 2 +- .../lib/src/types/flash_mode.dart | 2 +- .../lib/src/types/focus_mode.dart | 2 +- .../lib/src/types/image_format_group.dart | 2 +- .../lib/src/types/resolution_preset.dart | 2 +- .../lib/src/types/types.dart | 2 +- .../lib/src/utils/utils.dart | 2 +- .../test/camera_platform_interface_test.dart | 2 +- .../test/events/camera_event_test.dart | 2 +- .../test/events/device_event_test.dart | 2 +- .../method_channel_camera_test.dart | 2 +- .../test/types/camera_description_test.dart | 2 +- .../test/types/camera_exception_test.dart | 2 +- .../test/types/exposure_mode_test.dart | 2 +- .../test/types/flash_mode_test.dart | 2 +- .../test/types/focus_mode_test.dart | 2 +- .../test/types/image_group_test.dart | 2 +- .../test/types/resolution_preset_test.dart | 2 +- .../test/utils/method_channel_mock.dart | 2 +- .../test/utils/utils_test.dart | 2 +- packages/connectivity/connectivity/LICENSE | 2 +- .../plugins/connectivity/Connectivity.java | 2 +- .../ConnectivityBroadcastReceiver.java | 2 +- .../ConnectivityMethodChannelHandler.java | 2 +- .../connectivity/ConnectivityPlugin.java | 2 +- .../EmbeddingV1Activity.java | 2 +- .../EmbeddingV1ActivityTest.java | 2 +- .../FlutterActivityTest.java | 2 +- .../connectivityexample/ActivityTest.java | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- .../connectivity/example/ios/Runner/main.m | 2 +- .../connectivity/example/lib/main.dart | 2 +- .../example/macos/Runner/AppDelegate.swift | 2 +- .../macos/Runner/MainFlutterWindow.swift | 2 +- .../integration_test/connectivity_test.dart | 2 +- .../test_driver/test/integration_test.dart | 2 +- .../connectivity/example/web/index.html | 2 +- .../integration_test/connectivity_test.dart | 2 +- .../ios/Classes/FLTConnectivityPlugin.h | 2 +- .../ios/Classes/FLTConnectivityPlugin.m | 2 +- .../connectivity/lib/connectivity.dart | 2 +- .../connectivity/test/connectivity_test.dart | 2 +- .../connectivity/connectivity_for_web/LICENSE | 2 +- .../network_information_test.dart | 2 +- .../src/connectivity_mocks.dart | 2 +- .../connectivity_for_web/example/run_test.sh | 2 +- .../test_driver/integration_driver.dart | 2 +- .../example/web/index.html | 2 +- .../lib/connectivity_for_web.dart | 2 +- .../src/dart_html_connectivity_plugin.dart | 2 +- ...k_information_api_connectivity_plugin.dart | 2 +- .../lib/src/utils/connectivity_result.dart | 2 +- .../test/tests_exist_elsewhere_test.dart | 2 +- .../connectivity/connectivity_macos/LICENSE | 2 +- .../connectivity_macos/example/lib/main.dart | 2 +- .../example/macos/Runner/AppDelegate.swift | 2 +- .../macos/Runner/MainFlutterWindow.swift | 2 +- .../integration_test/connectivity_test.dart | 2 +- .../test_driver/test/integration_test.dart | 2 +- .../macos/Classes/ConnectivityPlugin.swift | 2 +- .../macos/Classes/IPHelper.h | 2 +- .../connectivity_platform_interface/LICENSE | 2 +- .../lib/connectivity_platform_interface.dart | 2 +- .../lib/src/enums.dart | 2 +- .../lib/src/method_channel_connectivity.dart | 2 +- .../lib/src/utils.dart | 2 +- .../method_channel_connectivity_test.dart | 2 +- packages/device_info/device_info/LICENSE | 2 +- .../plugins/deviceinfo/DeviceInfoPlugin.java | 2 +- .../deviceinfo/MethodCallHandlerImpl.java | 2 +- .../EmbeddingV1Activity.java | 2 +- .../EmbeddingV1ActivityTest.java | 2 +- .../integration_test/device_info_test.dart | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- .../device_info/example/ios/Runner/main.m | 2 +- .../device_info/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../ios/Classes/FLTDeviceInfoPlugin.h | 2 +- .../ios/Classes/FLTDeviceInfoPlugin.m | 2 +- .../device_info/lib/device_info.dart | 2 +- .../device_info_platform_interface/LICENSE | 2 +- .../lib/device_info_platform_interface.dart | 2 +- .../method_channel_device_info.dart | 2 +- .../lib/model/android_device_info.dart | 2 +- .../lib/model/ios_device_info.dart | 2 +- .../test/method_channel_device_info_test.dart | 2 +- packages/espresso/LICENSE | 2 +- .../espresso/flutter/EspressoFlutter.java | 2 +- .../espresso/flutter/action/ActionUtil.java | 2 +- .../espresso/flutter/action/ClickAction.java | 2 +- .../flutter/action/FlutterActions.java | 2 +- .../flutter/action/FlutterScrollToAction.java | 2 +- .../flutter/action/FlutterTypeTextAction.java | 2 +- .../flutter/action/FlutterViewAction.java | 2 +- .../flutter/action/SyntheticClickAction.java | 2 +- .../flutter/action/WaitUntilIdleAction.java | 2 +- .../action/WidgetCoordinatesCalculator.java | 2 +- .../flutter/action/WidgetInfoFetcher.java | 2 +- .../espresso/flutter/api/FlutterAction.java | 2 +- .../flutter/api/FlutterTestingProtocol.java | 2 +- .../espresso/flutter/api/SyntheticAction.java | 2 +- .../espresso/flutter/api/WidgetAction.java | 2 +- .../espresso/flutter/api/WidgetAssertion.java | 2 +- .../espresso/flutter/api/WidgetMatcher.java | 2 +- .../flutter/assertion/FlutterAssertions.java | 2 +- .../assertion/FlutterViewAssertion.java | 2 +- .../espresso/flutter/common/Constants.java | 2 +- .../espresso/flutter/common/Duration.java | 2 +- .../AmbiguousWidgetMatcherException.java | 2 +- .../InvalidFlutterViewException.java | 2 +- .../exception/NoMatchingWidgetException.java | 2 +- .../internal/idgenerator/IdException.java | 2 +- .../internal/idgenerator/IdGenerator.java | 2 +- .../internal/idgenerator/IdGenerators.java | 2 +- .../internal/jsonrpc/JsonRpcClient.java | 2 +- .../internal/jsonrpc/message/ErrorObject.java | 2 +- .../jsonrpc/message/JsonRpcRequest.java | 2 +- .../jsonrpc/message/JsonRpcResponse.java | 2 +- .../internal/protocol/impl/DartVmService.java | 2 +- .../protocol/impl/DartVmServiceUtil.java | 2 +- .../impl/FlutterProtocolException.java | 2 +- .../protocol/impl/GetOffsetAction.java | 2 +- .../protocol/impl/GetOffsetResponse.java | 2 +- .../internal/protocol/impl/GetVmResponse.java | 2 +- .../impl/GetWidgetDiagnosticsAction.java | 2 +- .../impl/GetWidgetDiagnosticsResponse.java | 2 +- .../impl/NoPendingFrameCondition.java | 2 +- .../NoPendingPlatformMessagesCondition.java | 2 +- .../impl/NoTransientCallbacksCondition.java | 2 +- .../internal/protocol/impl/WaitCondition.java | 2 +- .../protocol/impl/WaitForConditionAction.java | 2 +- .../protocol/impl/WidgetInfoFactory.java | 2 +- .../flutter/matcher/FlutterMatchers.java | 2 +- .../matcher/IsDescendantOfMatcher.java | 2 +- .../flutter/matcher/IsExistingMatcher.java | 2 +- .../flutter/matcher/WithTextMatcher.java | 2 +- .../flutter/matcher/WithTooltipMatcher.java | 2 +- .../flutter/matcher/WithTypeMatcher.java | 2 +- .../flutter/matcher/WithValueKeyMatcher.java | 2 +- .../espresso/flutter/model/WidgetInfo.java | 2 +- .../flutter/model/WidgetInfoBuilder.java | 2 +- .../com/example/espresso/EspressoPlugin.java | 2 +- .../java/com/example/MainActivityTest.java | 2 +- .../espresso_example/MainActivity.java | 2 +- packages/espresso/example/lib/main.dart | 2 +- .../espresso/example/test_driver/example.dart | 2 +- packages/file_selector/file_selector/LICENSE | 2 +- .../example/lib/get_directory_page.dart | 2 +- .../file_selector/example/lib/home_page.dart | 2 +- .../file_selector/example/lib/main.dart | 2 +- .../example/lib/open_image_page.dart | 2 +- .../lib/open_multiple_images_page.dart | 2 +- .../example/lib/open_text_page.dart | 2 +- .../example/lib/save_text_page.dart | 2 +- .../file_selector/example/web/index.html | 2 +- .../file_selector/lib/file_selector.dart | 2 +- .../test/file_selector_test.dart | 2 +- .../file_selector_platform_interface/LICENSE | 2 +- .../lib/file_selector_platform_interface.dart | 2 +- .../method_channel_file_selector.dart | 2 +- .../file_selector_interface.dart | 2 +- .../lib/src/types/types.dart | 2 +- .../src/types/x_type_group/x_type_group.dart | 2 +- .../lib/src/web_helpers/web_helpers.dart | 2 +- ...file_selector_platform_interface_test.dart | 2 +- .../method_channel_file_selector_test.dart | 2 +- .../test/x_type_group_test.dart | 2 +- .../file_selector/file_selector_web/LICENSE | 2 +- .../integration_test/dom_helper_test.dart | 2 +- .../file_selector_web_test.dart | 2 +- .../file_selector_web/example/run_test.sh | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../file_selector_web/example/web/index.html | 2 +- .../lib/file_selector_web.dart | 2 +- .../file_selector_web/lib/src/dom_helper.dart | 2 +- .../file_selector_web/lib/src/utils.dart | 2 +- .../test/more_tests_exist_elsewhere_test.dart | 2 +- .../file_selector_web/test/utils_test.dart | 2 +- .../flutter_plugin_android_lifecycle/LICENSE | 2 +- .../lifecycle/FlutterLifecycleAdapter.java | 2 +- .../FlutterAndroidLifecyclePlugin.java | 2 +- .../FlutterLifecycleAdapterTest.java | 2 +- .../EmbeddingV1ActivityTest.java | 2 +- .../MainActivityTest.java | 2 +- .../EmbeddingV1Activity.java | 2 +- .../MainActivity.java | 2 +- ...flutter_plugin_android_lifecycle_test.dart | 2 +- .../example/lib/main.dart | 2 +- .../lib/flutter_plugin_android_lifecycle.dart | 2 +- .../google_maps_flutter/LICENSE | 2 +- .../plugins/googlemaps/CircleBuilder.java | 2 +- .../plugins/googlemaps/CircleController.java | 2 +- .../plugins/googlemaps/CircleOptionsSink.java | 2 +- .../plugins/googlemaps/CirclesController.java | 2 +- .../flutter/plugins/googlemaps/Convert.java | 2 +- .../plugins/googlemaps/GoogleMapBuilder.java | 2 +- .../googlemaps/GoogleMapController.java | 2 +- .../plugins/googlemaps/GoogleMapFactory.java | 2 +- .../plugins/googlemaps/GoogleMapListener.java | 2 +- .../googlemaps/GoogleMapOptionsSink.java | 2 +- .../plugins/googlemaps/GoogleMapsPlugin.java | 2 +- .../plugins/googlemaps/LifecycleProvider.java | 2 +- .../plugins/googlemaps/MarkerBuilder.java | 2 +- .../plugins/googlemaps/MarkerController.java | 2 +- .../plugins/googlemaps/MarkerOptionsSink.java | 2 +- .../plugins/googlemaps/MarkersController.java | 2 +- .../plugins/googlemaps/PolygonBuilder.java | 2 +- .../plugins/googlemaps/PolygonController.java | 2 +- .../googlemaps/PolygonOptionsSink.java | 2 +- .../googlemaps/PolygonsController.java | 2 +- .../plugins/googlemaps/PolylineBuilder.java | 2 +- .../googlemaps/PolylineController.java | 2 +- .../googlemaps/PolylineOptionsSink.java | 2 +- .../googlemaps/PolylinesController.java | 2 +- .../googlemaps/TileOverlayBuilder.java | 2 +- .../googlemaps/TileOverlayController.java | 2 +- .../plugins/googlemaps/TileOverlaySink.java | 2 +- .../googlemaps/TileOverlaysController.java | 2 +- .../googlemaps/TileProviderController.java | 2 +- .../plugins/googlemaps/CircleBuilderTest.java | 2 +- .../googlemaps/CircleControllerTest.java | 2 +- .../googlemaps/PolygonBuilderTest.java | 2 +- .../googlemaps/PolygonControllerTest.java | 2 +- .../googlemaps/PolylineBuilderTest.java | 2 +- .../googlemaps/PolylineControllerTest.java | 2 +- .../googlemaps/EmbeddingV1ActivityTest.java | 2 +- .../plugins/googlemaps/MainActivityTest.java | 2 +- .../EmbeddingV1Activity.java | 2 +- .../googlemaps/GoogleMapControllerTest.java | 2 +- .../google_map_inspector.dart | 2 +- .../integration_test/google_maps_test.dart | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- .../example/ios/Runner/main.m | 2 +- .../example/lib/animate_camera.dart | 2 +- .../example/lib/lite_mode.dart | 2 +- .../google_maps_flutter/example/lib/main.dart | 2 +- .../example/lib/map_click.dart | 2 +- .../example/lib/map_coordinates.dart | 2 +- .../example/lib/map_ui.dart | 2 +- .../example/lib/marker_icons.dart | 2 +- .../example/lib/move_camera.dart | 2 +- .../example/lib/padding.dart | 2 +- .../google_maps_flutter/example/lib/page.dart | 2 +- .../example/lib/place_circle.dart | 2 +- .../example/lib/place_marker.dart | 2 +- .../example/lib/place_polygon.dart | 2 +- .../example/lib/place_polyline.dart | 2 +- .../example/lib/scrolling_map.dart | 2 +- .../example/lib/snapshot.dart | 2 +- .../example/lib/tile_overlay.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../FLTGoogleMapTileOverlayController.h | 2 +- .../FLTGoogleMapTileOverlayController.m | 2 +- .../ios/Classes/FLTGoogleMapsPlugin.h | 2 +- .../ios/Classes/FLTGoogleMapsPlugin.m | 2 +- .../ios/Classes/GoogleMapCircleController.h | 2 +- .../ios/Classes/GoogleMapCircleController.m | 2 +- .../ios/Classes/GoogleMapController.h | 2 +- .../ios/Classes/GoogleMapController.m | 2 +- .../ios/Classes/GoogleMapMarkerController.h | 2 +- .../ios/Classes/GoogleMapMarkerController.m | 2 +- .../ios/Classes/GoogleMapPolygonController.h | 2 +- .../ios/Classes/GoogleMapPolygonController.m | 2 +- .../ios/Classes/GoogleMapPolylineController.h | 2 +- .../ios/Classes/GoogleMapPolylineController.m | 2 +- .../ios/Classes/JsonConversions.h | 2 +- .../ios/Classes/JsonConversions.m | 2 +- .../lib/google_maps_flutter.dart | 2 +- .../lib/src/controller.dart | 2 +- .../lib/src/google_map.dart | 2 +- .../test/android_google_map_test.dart | 2 +- .../test/circle_updates_test.dart | 2 +- .../test/fake_maps_controllers.dart | 2 +- .../test/google_map_test.dart | 2 +- .../test/map_creation_test.dart | 2 +- .../test/marker_updates_test.dart | 2 +- .../test/polygon_updates_test.dart | 2 +- .../test/polyline_updates_test.dart | 2 +- .../test/tile_overlay_updates_test.dart | 2 +- .../LICENSE | 2 +- ...oogle_maps_flutter_platform_interface.dart | 2 +- .../lib/src/events/map_event.dart | 2 +- .../method_channel_google_maps_flutter.dart | 2 +- .../google_maps_flutter_platform.dart | 2 +- .../lib/src/types/bitmap.dart | 2 +- .../lib/src/types/callbacks.dart | 2 +- .../lib/src/types/camera.dart | 2 +- .../lib/src/types/cap.dart | 2 +- .../lib/src/types/circle.dart | 2 +- .../lib/src/types/circle_updates.dart | 2 +- .../lib/src/types/joint_type.dart | 2 +- .../lib/src/types/location.dart | 2 +- .../lib/src/types/maps_object.dart | 2 +- .../lib/src/types/maps_object_updates.dart | 2 +- .../lib/src/types/marker.dart | 2 +- .../lib/src/types/marker_updates.dart | 2 +- .../lib/src/types/pattern_item.dart | 2 +- .../lib/src/types/polygon.dart | 2 +- .../lib/src/types/polygon_updates.dart | 2 +- .../lib/src/types/polyline.dart | 2 +- .../lib/src/types/polyline_updates.dart | 2 +- .../lib/src/types/screen_coordinate.dart | 2 +- .../lib/src/types/tile.dart | 2 +- .../lib/src/types/tile_overlay.dart | 2 +- .../lib/src/types/tile_overlay_updates.dart | 2 +- .../lib/src/types/tile_provider.dart | 2 +- .../lib/src/types/types.dart | 2 +- .../lib/src/types/ui.dart | 2 +- .../lib/src/types/utils/circle.dart | 2 +- .../lib/src/types/utils/maps_object.dart | 2 +- .../lib/src/types/utils/marker.dart | 2 +- .../lib/src/types/utils/polygon.dart | 2 +- .../lib/src/types/utils/polyline.dart | 2 +- .../lib/src/types/utils/tile_overlay.dart | 2 +- .../google_maps_flutter_platform_test.dart | 2 +- .../test/types/bitmap_test.dart | 2 +- .../test/types/camera_test.dart | 2 +- .../test/types/maps_object_test.dart | 2 +- .../test/types/maps_object_updates_test.dart | 2 +- .../test/types/test_maps_object.dart | 2 +- .../test/types/tile_overlay_test.dart | 2 +- .../test/types/tile_overlay_updates_test.dart | 2 +- .../test/types/tile_test.dart | 2 +- .../google_maps_flutter_web/LICENSE | 2 +- .../google_maps_controller_test.dart | 2 +- .../google_maps_plugin_test.dart | 2 +- .../example/integration_test/marker_test.dart | 2 +- .../integration_test/markers_test.dart | 2 +- .../resources/icon_image_base64.dart | 2 +- .../example/integration_test/shape_test.dart | 2 +- .../example/integration_test/shapes_test.dart | 2 +- .../example/run_test.sh | 2 +- .../test_driver/integration_driver.dart | 2 +- .../example/web/index.html | 2 +- .../lib/google_maps_flutter_web.dart | 2 +- .../lib/src/circle.dart | 2 +- .../lib/src/circles.dart | 2 +- .../lib/src/convert.dart | 2 +- .../lib/src/google_maps_controller.dart | 2 +- .../lib/src/google_maps_flutter_web.dart | 2 +- .../lib/src/marker.dart | 2 +- .../lib/src/markers.dart | 2 +- .../lib/src/polygon.dart | 2 +- .../lib/src/polygons.dart | 2 +- .../lib/src/polyline.dart | 2 +- .../lib/src/polylines.dart | 2 +- .../lib/src/shims/dart_ui.dart | 2 +- .../lib/src/shims/dart_ui_fake.dart | 2 +- .../lib/src/shims/dart_ui_real.dart | 2 +- .../lib/src/types.dart | 2 +- .../test/tests_exist_elsewhere_test.dart | 2 +- .../google_sign_in/google_sign_in/LICENSE | 2 +- .../googlesignin/BackgroundTaskRunner.java | 2 +- .../plugins/googlesignin/Executors.java | 2 +- .../googlesignin/GoogleSignInPlugin.java | 2 +- .../googlesignin/GoogleSignInWrapper.java | 2 +- .../EmbeddingV1Activity.java | 2 +- .../EmbeddingV1ActivityTest.java | 2 +- .../FlutterActivityTest.java | 2 +- .../googlesignin/GoogleSignInPluginTests.java | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- .../google_sign_in/example/ios/Runner/main.m | 2 +- .../google_sign_in/example/lib/main.dart | 2 +- .../google_sign_in/example/web/index.html | 2 +- .../integration_test/google_sign_in_test.dart | 2 +- .../ios/Classes/FLTGoogleSignInPlugin.h | 2 +- .../ios/Classes/FLTGoogleSignInPlugin.m | 2 +- .../ios/Tests/GoogleSignInPluginTest.m | 2 +- .../google_sign_in/lib/google_sign_in.dart | 2 +- .../google_sign_in/lib/src/common.dart | 2 +- .../google_sign_in/lib/src/fife.dart | 2 +- .../google_sign_in/lib/testing.dart | 2 +- .../google_sign_in/lib/widgets.dart | 2 +- .../google_sign_in/test/fife_test.dart | 2 +- .../test/google_sign_in_test.dart | 2 +- .../test_driver/integration_test.dart | 2 +- .../google_sign_in_platform_interface/LICENSE | 2 +- .../google_sign_in_platform_interface.dart | 2 +- .../src/method_channel_google_sign_in.dart | 2 +- .../lib/src/types.dart | 2 +- .../lib/src/utils.dart | 2 +- ...oogle_sign_in_platform_interface_test.dart | 2 +- .../method_channel_google_sign_in_test.dart | 2 +- .../google_sign_in/google_sign_in_web/LICENSE | 2 +- .../example/integration_test/auth2_test.dart | 2 +- .../integration_test/gapi_load_test.dart | 2 +- .../gapi_mocks/gapi_mocks.dart | 2 +- .../gapi_mocks/src/auth2_init.dart | 2 +- .../integration_test/gapi_mocks/src/gapi.dart | 2 +- .../gapi_mocks/src/google_user.dart | 2 +- .../gapi_mocks/src/test_iife.dart | 2 +- .../integration_test/gapi_utils_test.dart | 2 +- .../integration_test/src/test_utils.dart | 2 +- .../google_sign_in_web/example/run_test.sh | 2 +- .../test_driver/integration_driver.dart | 2 +- .../google_sign_in_web/example/web/index.html | 2 +- .../lib/google_sign_in_web.dart | 2 +- .../lib/src/generated/gapi.dart | 2 +- .../lib/src/generated/gapiauth2.dart | 2 +- .../google_sign_in_web/lib/src/load_gapi.dart | 2 +- .../google_sign_in_web/lib/src/utils.dart | 2 +- .../test/tests_exist_elsewhere_test.dart | 2 +- packages/image_picker/image_picker/LICENSE | 2 +- .../plugins/imagepicker/ExifDataCopier.java | 2 +- .../plugins/imagepicker/FileUtils.java | 2 +- .../plugins/imagepicker/ImagePickerCache.java | 2 +- .../imagepicker/ImagePickerDelegate.java | 2 +- .../imagepicker/ImagePickerFileProvider.java | 2 +- .../imagepicker/ImagePickerPlugin.java | 2 +- .../plugins/imagepicker/ImagePickerUtils.java | 2 +- .../plugins/imagepicker/ImageResizer.java | 2 +- .../EmbeddingV1Activity.java | 2 +- .../EmbeddingV1ActivityTest.java | 2 +- .../FlutterActivityTest.java | 2 +- .../plugins/imagepicker/FileUtilTest.java | 2 +- .../imagepicker/ImagePickerCacheTest.java | 2 +- .../imagepicker/ImagePickerDelegateTest.java | 2 +- .../imagepicker/ImagePickerPluginTest.java | 2 +- .../plugins/imagepicker/ImageResizerTest.java | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- .../image_picker/example/ios/Runner/main.m | 2 +- .../ImagePickerFromGalleryUITests.m | 2 +- .../image_picker/example/lib/main.dart | 2 +- .../test_driver/test/integration_test.dart | 2 +- .../image_picker/example/web/index.html | 2 +- .../old_image_picker_test.dart | 2 +- .../ios/Classes/FLTImagePickerImageUtil.h | 2 +- .../ios/Classes/FLTImagePickerImageUtil.m | 2 +- .../ios/Classes/FLTImagePickerMetaDataUtil.h | 2 +- .../ios/Classes/FLTImagePickerMetaDataUtil.m | 2 +- .../Classes/FLTImagePickerPhotoAssetUtil.h | 2 +- .../Classes/FLTImagePickerPhotoAssetUtil.m | 2 +- .../ios/Classes/FLTImagePickerPlugin.h | 2 +- .../ios/Classes/FLTImagePickerPlugin.m | 2 +- .../ios/Tests/ImagePickerPluginTests.m | 2 +- .../ios/Tests/ImagePickerTestImages.h | 2 +- .../ios/Tests/ImagePickerTestImages.m | 2 +- .../image_picker/ios/Tests/ImageUtilTests.m | 2 +- .../ios/Tests/MetaDataUtilTests.m | 2 +- .../ios/Tests/PhotoAssetUtilTests.m | 2 +- .../image_picker/lib/image_picker.dart | 2 +- .../image_picker/test/image_picker_test.dart | 2 +- .../image_picker/image_picker_for_web/LICENSE | 2 +- .../lib/image_picker_for_web.dart | 2 +- .../test/image_picker_for_web_test.dart | 2 +- .../image_picker_platform_interface/LICENSE | 2 +- .../lib/image_picker_platform_interface.dart | 2 +- .../method_channel_image_picker.dart | 2 +- .../image_picker_platform.dart | 2 +- .../lib/src/types/camera_device.dart | 2 +- .../lib/src/types/image_source.dart | 2 +- .../lib/src/types/picked_file/base.dart | 2 +- .../lib/src/types/picked_file/html.dart | 2 +- .../lib/src/types/picked_file/io.dart | 2 +- .../lib/src/types/picked_file/lost_data.dart | 2 +- .../src/types/picked_file/picked_file.dart | 2 +- .../src/types/picked_file/unsupported.dart | 2 +- .../lib/src/types/retrieve_type.dart | 2 +- .../lib/src/types/types.dart | 2 +- .../new_method_channel_image_picker_test.dart | 2 +- .../test/picked_file_html_test.dart | 2 +- .../test/picked_file_io_test.dart | 2 +- packages/in_app_purchase/LICENSE | 2 +- .../inapppurchase/BillingClientFactory.java | 2 +- .../BillingClientFactoryImpl.java | 2 +- .../inapppurchase/InAppPurchasePlugin.java | 2 +- .../inapppurchase/MethodCallHandlerImpl.java | 2 +- .../inapppurchase/PluginPurchaseListener.java | 2 +- .../plugins/inapppurchase/Translator.java | 2 +- .../EmbeddingV1Activity.java | 2 +- .../EmbeddingV1ActivityTest.java | 2 +- .../FlutterActivityTest.java | 2 +- .../InAppPurchasePluginTest.java | 2 +- .../inapppurchase/MethodCallHandlerTest.java | 2 +- .../plugins/inapppurchase/TranslatorTest.java | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- .../in_app_purchase/example/ios/Runner/main.m | 2 +- .../example/lib/consumable_store.dart | 2 +- .../in_app_purchase/example/lib/main.dart | 2 +- .../test_driver/test/integration_test.dart | 2 +- .../in_app_purchase_test.dart | 2 +- .../ios/Classes/FIAObjectTranslator.h | 2 +- .../ios/Classes/FIAObjectTranslator.m | 2 +- .../ios/Classes/FIAPReceiptManager.h | 2 +- .../ios/Classes/FIAPReceiptManager.m | 2 +- .../ios/Classes/FIAPRequestHandler.h | 2 +- .../ios/Classes/FIAPRequestHandler.m | 2 +- .../ios/Classes/FIAPaymentQueueHandler.h | 2 +- .../ios/Classes/FIAPaymentQueueHandler.m | 2 +- .../ios/Classes/InAppPurchasePlugin.h | 2 +- .../ios/Classes/InAppPurchasePlugin.m | 2 +- .../ios/Tests/InAppPurchasePluginTest.m | 2 +- .../ios/Tests/PaymentQueueTest.m | 2 +- .../ios/Tests/ProductRequestHandlerTest.m | 2 +- packages/in_app_purchase/ios/Tests/Stubs.h | 2 +- packages/in_app_purchase/ios/Tests/Stubs.m | 2 +- .../ios/Tests/TranslatorTest.m | 2 +- .../lib/billing_client_wrappers.dart | 2 +- .../in_app_purchase/lib/in_app_purchase.dart | 2 +- .../billing_client_wrapper.dart | 2 +- .../enum_converters.dart | 2 +- .../purchase_wrapper.dart | 2 +- .../sku_details_wrapper.dart | 2 +- packages/in_app_purchase/lib/src/channel.dart | 2 +- .../in_app_purchase/app_store_connection.dart | 2 +- .../google_play_connection.dart | 2 +- .../in_app_purchase_connection.dart | 2 +- .../src/in_app_purchase/product_details.dart | 2 +- .../src/in_app_purchase/purchase_details.dart | 2 +- .../store_kit_wrappers/enum_converters.dart | 2 +- .../sk_payment_queue_wrapper.dart | 2 +- .../sk_payment_transaction_wrappers.dart | 2 +- .../sk_product_wrapper.dart | 2 +- .../sk_receipt_manager.dart | 2 +- .../store_kit_wrappers/sk_request_maker.dart | 2 +- .../lib/store_kit_wrappers.dart | 2 +- .../billing_client_wrapper_test.dart | 2 +- .../purchase_wrapper_test.dart | 2 +- .../sku_details_wrapper_test.dart | 2 +- .../app_store_connection_test.dart | 2 +- .../google_play_connection_test.dart | 2 +- .../sk_methodchannel_apis_test.dart | 2 +- .../store_kit_wrappers/sk_product_test.dart | 2 +- .../sk_test_stub_objects.dart | 2 +- .../test/stub_in_app_purchase_platform.dart | 2 +- packages/integration_test/LICENSE | 2 +- .../integration_test/FlutterTestRunner.java | 2 +- .../IntegrationTestPlugin.java | 2 +- .../e2e_example/EmbedderV1ActivityTest.java | 2 +- .../e2e_example/FlutterActivityTest.java | 2 +- .../FlutterActivityWithPermissionTest.java | 2 +- .../e2e_example/EmbedderV1Activity.java | 2 +- .../integration_test/_example_test_io.dart | 2 +- .../integration_test/_example_test_web.dart | 2 +- .../integration_test/_extended_test_io.dart | 2 +- .../integration_test/_extended_test_web.dart | 2 +- .../integration_test/example_test.dart | 2 +- .../integration_test/extended_test.dart | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- .../example/ios/Runner/main.m | 2 +- .../example/ios/RunnerTests/RunnerTests.m | 2 +- .../integration_test/example/lib/main.dart | 2 +- .../integration_test/example/lib/my_app.dart | 2 +- .../example/lib/my_web_app.dart | 2 +- .../example/macos/Runner/AppDelegate.swift | 2 +- .../macos/Runner/MainFlutterWindow.swift | 2 +- .../extended_integration_test.dart | 2 +- .../example/test_driver/failure.dart | 2 +- .../example/test_driver/failure_test.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../integration_test/example/web/index.html | 2 +- .../ios/Classes/IntegrationTestIosTest.h | 2 +- .../ios/Classes/IntegrationTestIosTest.m | 2 +- .../ios/Classes/IntegrationTestPlugin.h | 2 +- .../ios/Classes/IntegrationTestPlugin.m | 2 +- .../integration_test/lib/_callback_io.dart | 2 +- .../integration_test/lib/_callback_web.dart | 2 +- .../integration_test/lib/_extension_io.dart | 2 +- .../integration_test/lib/_extension_web.dart | 2 +- packages/integration_test/lib/common.dart | 2 +- .../lib/integration_test.dart | 2 +- .../lib/integration_test_driver.dart | 2 +- .../lib/integration_test_driver_extended.dart | 2 +- .../test/binding_fail_test.dart | 2 +- .../integration_test/test/binding_test.dart | 2 +- .../test/data/fail_test_script.dart | 2 +- .../test/data/pass_test_script.dart | 2 +- .../test/data/pass_then_fail_test_script.dart | 2 +- .../test/response_serialization_test.dart | 2 +- packages/ios_platform_images/LICENSE | 2 +- .../example/ios/Runner/AppDelegate.swift | 2 +- .../ios/Runner/Runner-Bridging-Header.h | 2 +- .../ios_platform_images/example/lib/main.dart | 2 +- .../example/test/widget_test.dart | 2 +- .../ios/Classes/IosPlatformImagesPlugin.h | 2 +- .../ios/Classes/IosPlatformImagesPlugin.m | 2 +- .../lib/ios_platform_images.dart | 2 +- .../test/ios_platform_images_test.dart | 2 +- packages/local_auth/LICENSE | 2 +- .../localauth/AuthenticationHelper.java | 2 +- .../plugins/localauth/LocalAuthPlugin.java | 2 +- .../localauth/EmbeddingV1ActivityTest.java | 2 +- .../FlutterFragmentActivityTest.java | 2 +- .../localauthexample/EmbeddingV1Activity.java | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- packages/local_auth/example/ios/Runner/main.m | 2 +- packages/local_auth/example/lib/main.dart | 2 +- .../integration_test/local_auth_test.dart | 2 +- .../ios/Classes/FLTLocalAuthPlugin.h | 2 +- .../ios/Classes/FLTLocalAuthPlugin.m | 2 +- packages/local_auth/lib/auth_strings.dart | 2 +- packages/local_auth/lib/error_codes.dart | 2 +- packages/local_auth/lib/local_auth.dart | 2 +- packages/local_auth/test/local_auth_test.dart | 2 +- packages/package_info/LICENSE | 2 +- .../packageinfo/PackageInfoPlugin.java | 2 +- .../darwin/Classes/FLTPackageInfoPlugin.m | 2 +- .../EmbedderV1ActivityTest.java | 2 +- .../packageinfoexample/MainActivityTest.java | 2 +- .../EmbedderV1Activity.java | 2 +- .../integration_test/package_info_test.dart | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- .../package_info/example/ios/Runner/main.m | 2 +- packages/package_info/example/lib/main.dart | 2 +- .../example/macos/Runner/AppDelegate.swift | 2 +- .../macos/Runner/MainFlutterWindow.swift | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../ios/Classes/FLTPackageInfoPlugin.h | 2 +- packages/package_info/lib/package_info.dart | 2 +- .../macos/Classes/FLTPackageInfoPlugin.h | 2 +- .../package_info/test/package_info_test.dart | 2 +- packages/path_provider/path_provider/LICENSE | 2 +- .../pathprovider/PathProviderPlugin.java | 2 +- .../pathprovider/StorageDirectoryMapper.java | 2 +- .../StorageDirectoryMapperTest.java | 2 +- .../java/EmbeddingV1ActivityTest.java | 2 +- .../androidTest/java/MainActivityTest.java | 2 +- .../EmbeddingV1Activity.java | 2 +- .../integration_test/path_provider_test.dart | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- .../path_provider/example/ios/Runner/main.m | 2 +- .../path_provider/example/lib/main.dart | 2 +- .../path_provider/example/linux/main.cc | 2 +- .../example/linux/my_application.cc | 2 +- .../example/linux/my_application.h | 2 +- .../example/macos/Runner/AppDelegate.swift | 2 +- .../macos/Runner/MainFlutterWindow.swift | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../example/windows/runner/flutter_window.cpp | 2 +- .../example/windows/runner/flutter_window.h | 2 +- .../example/windows/runner/main.cpp | 2 +- .../example/windows/runner/run_loop.cpp | 2 +- .../example/windows/runner/run_loop.h | 2 +- .../example/windows/runner/utils.cpp | 2 +- .../example/windows/runner/utils.h | 2 +- .../example/windows/runner/win32_window.cpp | 2 +- .../example/windows/runner/win32_window.h | 2 +- .../integration_test/path_provider_test.dart | 2 +- .../ios/Classes/FLTPathProviderPlugin.h | 2 +- .../ios/Classes/FLTPathProviderPlugin.m | 2 +- .../path_provider/lib/path_provider.dart | 2 +- .../test/path_provider_test.dart | 2 +- .../path_provider/path_provider_linux/LICENSE | 2 +- .../integration_test/path_provider_test.dart | 2 +- .../path_provider_linux/example/lib/main.dart | 2 +- .../path_provider_linux/example/linux/main.cc | 2 +- .../example/linux/my_application.cc | 2 +- .../example/linux/my_application.h | 2 +- .../example/test/widget_test.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../lib/path_provider_linux.dart | 2 +- .../test/path_provider_linux_test.dart | 2 +- .../path_provider/path_provider_macos/LICENSE | 2 +- .../integration_test/path_provider_test.dart | 2 +- .../path_provider_macos/example/lib/main.dart | 2 +- .../example/macos/Runner/AppDelegate.swift | 2 +- .../macos/Runner/MainFlutterWindow.swift | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../macos/Classes/PathProviderPlugin.swift | 2 +- .../path_provider_platform_interface/LICENSE | 2 +- .../lib/path_provider_platform_interface.dart | 2 +- .../lib/src/enums.dart | 2 +- .../lib/src/method_channel_path_provider.dart | 2 +- .../method_channel_path_provider_test.dart | 2 +- .../path_provider_windows/LICENSE | 2 +- .../integration_test/path_provider_test.dart | 2 +- .../example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../example/windows/runner/flutter_window.cpp | 2 +- .../example/windows/runner/flutter_window.h | 2 +- .../example/windows/runner/main.cpp | 2 +- .../example/windows/runner/run_loop.cpp | 2 +- .../example/windows/runner/run_loop.h | 2 +- .../example/windows/runner/utils.cpp | 2 +- .../example/windows/runner/utils.h | 2 +- .../example/windows/runner/win32_window.cpp | 2 +- .../example/windows/runner/win32_window.h | 2 +- .../lib/path_provider_windows.dart | 2 +- .../lib/src/folders.dart | 2 +- .../lib/src/folders_stub.dart | 2 +- .../lib/src/path_provider_windows_real.dart | 2 +- .../lib/src/path_provider_windows_stub.dart | 2 +- .../test/path_provider_windows_test.dart | 2 +- packages/plugin_platform_interface/LICENSE | 2 +- .../lib/plugin_platform_interface.dart | 2 +- .../test/plugin_platform_interface_test.dart | 2 +- packages/quick_actions/quick_actions/LICENSE | 2 +- .../quickactions/MethodCallHandlerImpl.java | 2 +- .../quickactions/QuickActionsPlugin.java | 2 +- .../EmbeddingV1Activity.java | 2 +- .../EmbeddingV1ActivityTest.java | 2 +- .../FlutterActivityTest.java | 2 +- .../integration_test/quick_actions_test.dart | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- .../quick_actions/example/ios/Runner/main.m | 2 +- .../example/ios/RunnerUITests/RunnerUITests.m | 2 +- .../quick_actions/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../ios/Classes/FLTQuickActionsPlugin.h | 2 +- .../ios/Classes/FLTQuickActionsPlugin.m | 2 +- .../quick_actions/lib/quick_actions.dart | 2 +- .../test/quick_actions_test.dart | 2 +- packages/sensors/LICENSE | 2 +- .../plugins/sensors/SensorsPlugin.java | 2 +- .../plugins/sensors/StreamHandlerImpl.java | 2 +- .../sensorsexample/EmbeddingV1Activity.java | 2 +- .../EmbeddingV1ActivityTest.java | 2 +- .../sensorsexample/FlutterActivityTest.java | 2 +- .../sensors/example/ios/Runner/AppDelegate.h | 2 +- .../sensors/example/ios/Runner/AppDelegate.m | 2 +- packages/sensors/example/ios/Runner/main.m | 2 +- packages/sensors/example/lib/main.dart | 2 +- packages/sensors/example/lib/snake.dart | 2 +- .../test_driver/test/integration_test.dart | 2 +- .../integration_test/sensors_test.dart | 2 +- .../sensors/ios/Classes/FLTSensorsPlugin.h | 2 +- .../sensors/ios/Classes/FLTSensorsPlugin.m | 2 +- packages/sensors/lib/sensors.dart | 2 +- packages/sensors/test/sensors_test.dart | 2 +- packages/share/LICENSE | 2 +- .../plugins/share/MethodCallHandler.java | 2 +- .../java/io/flutter/plugins/share/Share.java | 2 +- .../plugins/share/ShareFileProvider.java | 2 +- .../io/flutter/plugins/share/SharePlugin.java | 2 +- .../shareexample/EmbeddingV1Activity.java | 2 +- .../shareexample/EmbeddingV1ActivityTest.java | 2 +- .../shareexample/FlutterActivityTest.java | 2 +- .../share/example/ios/Runner/AppDelegate.h | 2 +- .../share/example/ios/Runner/AppDelegate.m | 2 +- packages/share/example/ios/Runner/main.m | 2 +- .../RunnerUITests/FLTShareExampleUITests.m | 2 +- .../share/example/lib/image_previews.dart | 2 +- packages/share/example/lib/main.dart | 2 +- .../test_driver/test/integration_test.dart | 2 +- .../share/integration_test/share_test.dart | 2 +- packages/share/ios/Classes/FLTSharePlugin.h | 2 +- packages/share/ios/Classes/FLTSharePlugin.m | 2 +- packages/share/lib/share.dart | 2 +- packages/share/test/share_test.dart | 2 +- .../shared_preferences/LICENSE | 2 +- .../MethodCallHandlerImpl.java | 2 +- .../SharedPreferencesPlugin.java | 2 +- .../shared_preferences_test.dart | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- .../example/ios/Runner/AppDelegate.swift | 2 +- .../ios/Runner/Runner-Bridging-Header.h | 2 +- .../example/ios/Runner/main.m | 2 +- .../shared_preferences/example/lib/main.dart | 2 +- .../shared_preferences/example/linux/main.cc | 2 +- .../example/linux/my_application.cc | 2 +- .../example/linux/my_application.h | 2 +- .../example/macos/Runner/AppDelegate.swift | 2 +- .../macos/Runner/MainFlutterWindow.swift | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../shared_preferences/example/web/index.html | 2 +- .../example/windows/runner/flutter_window.cpp | 2 +- .../example/windows/runner/flutter_window.h | 2 +- .../example/windows/runner/main.cpp | 2 +- .../example/windows/runner/run_loop.cpp | 2 +- .../example/windows/runner/run_loop.h | 2 +- .../example/windows/runner/utils.cpp | 2 +- .../example/windows/runner/utils.h | 2 +- .../example/windows/runner/win32_window.cpp | 2 +- .../example/windows/runner/win32_window.h | 2 +- .../ios/Classes/FLTSharedPreferencesPlugin.h | 2 +- .../ios/Classes/FLTSharedPreferencesPlugin.m | 2 +- .../lib/shared_preferences.dart | 2 +- .../test/shared_preferences_test.dart | 2 +- .../shared_preferences_linux/LICENSE | 2 +- .../shared_preferences_test.dart | 2 +- .../example/lib/main.dart | 2 +- .../example/linux/main.cc | 2 +- .../example/linux/my_application.cc | 2 +- .../example/linux/my_application.h | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../lib/shared_preferences_linux.dart | 2 +- .../test/shared_preferences_linux_test.dart | 2 +- .../shared_preferences_macos/LICENSE | 2 +- .../shared_preferences_test.dart | 2 +- .../example/lib/main.dart | 2 +- .../example/macos/Runner/AppDelegate.swift | 2 +- .../macos/Runner/MainFlutterWindow.swift | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../Classes/SharedPreferencesPlugin.swift | 2 +- .../LICENSE | 2 +- .../method_channel_shared_preferences.dart | 2 +- ...shared_preferences_platform_interface.dart | 2 +- ...ethod_channel_shared_preferences_test.dart | 2 +- ...d_preferences_platform_interface_test.dart | 2 +- .../shared_preferences_web/LICENSE | 2 +- .../lib/shared_preferences_web.dart | 2 +- .../test/shared_preferences_web_test.dart | 2 +- .../shared_preferences_windows/LICENSE | 2 +- .../example/LICENSE | 2 +- .../shared_preferences_test.dart | 2 +- .../example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../example/windows/runner/flutter_window.cpp | 2 +- .../example/windows/runner/flutter_window.h | 2 +- .../example/windows/runner/main.cpp | 2 +- .../example/windows/runner/run_loop.cpp | 2 +- .../example/windows/runner/run_loop.h | 2 +- .../example/windows/runner/utils.cpp | 2 +- .../example/windows/runner/utils.h | 2 +- .../example/windows/runner/win32_window.cpp | 2 +- .../example/windows/runner/win32_window.h | 2 +- .../lib/shared_preferences_windows.dart | 2 +- .../test/shared_preferences_windows_test.dart | 2 +- packages/url_launcher/url_launcher/LICENSE | 2 +- .../urllauncher/MethodCallHandlerImpl.java | 2 +- .../plugins/urllauncher/UrlLauncher.java | 2 +- .../urllauncher/UrlLauncherPlugin.java | 2 +- .../plugins/urllauncher/WebViewActivity.java | 2 +- .../MethodCallHandlerImplTest.java | 2 +- .../EmbeddingV1ActivityTest.java | 2 +- .../urllauncherexample/MainActivityTest.java | 2 +- .../EmbeddingV1Activity.java | 2 +- .../integration_test/url_launcher_test.dart | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- .../url_launcher/example/ios/Runner/main.m | 2 +- .../url_launcher/example/lib/main.dart | 2 +- .../url_launcher/example/linux/main.cc | 2 +- .../example/linux/my_application.cc | 2 +- .../example/linux/my_application.h | 2 +- .../example/macos/Runner/AppDelegate.swift | 2 +- .../macos/Runner/MainFlutterWindow.swift | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../url_launcher/example/web/index.html | 2 +- .../example/windows/runner/flutter_window.cpp | 2 +- .../example/windows/runner/flutter_window.h | 2 +- .../example/windows/runner/main.cpp | 2 +- .../example/windows/runner/run_loop.cpp | 2 +- .../example/windows/runner/run_loop.h | 2 +- .../example/windows/runner/utils.cpp | 2 +- .../example/windows/runner/utils.h | 2 +- .../example/windows/runner/win32_window.cpp | 2 +- .../example/windows/runner/win32_window.h | 2 +- .../ios/Classes/FLTURLLauncherPlugin.h | 2 +- .../ios/Classes/FLTURLLauncherPlugin.m | 2 +- .../url_launcher/url_launcher/lib/link.dart | 2 +- .../url_launcher/lib/src/link.dart | 2 +- .../url_launcher/lib/url_launcher.dart | 2 +- .../url_launcher/test/link_test.dart | 2 +- .../test/mock_url_launcher_platform.dart | 2 +- .../url_launcher/test/url_launcher_test.dart | 2 +- .../url_launcher/url_launcher_linux/LICENSE | 2 +- .../integration_test/url_launcher_test.dart | 2 +- .../url_launcher_linux/example/lib/main.dart | 2 +- .../url_launcher_linux/example/linux/main.cc | 2 +- .../example/linux/my_application.cc | 2 +- .../example/linux/my_application.h | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../url_launcher_linux/url_launcher_plugin.h | 2 +- .../linux/url_launcher_plugin.cc | 2 +- .../url_launcher/url_launcher_macos/LICENSE | 2 +- .../integration_test/url_launcher_test.dart | 2 +- .../url_launcher_macos/example/lib/main.dart | 2 +- .../example/macos/Runner/AppDelegate.swift | 2 +- .../macos/Runner/MainFlutterWindow.swift | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../macos/Classes/UrlLauncherPlugin.swift | 2 +- .../url_launcher_platform_interface/LICENSE | 2 +- .../lib/link.dart | 2 +- .../lib/method_channel_url_launcher.dart | 2 +- .../lib/url_launcher_platform_interface.dart | 2 +- .../test/link_test.dart | 2 +- .../method_channel_url_launcher_test.dart | 2 +- .../url_launcher/url_launcher_web/LICENSE | 2 +- .../integration_test/link_widget_test.dart | 2 +- .../url_launcher_web_test.dart | 2 +- .../url_launcher_web_test.mocks.dart | 2 +- .../url_launcher_web/example/run_test.sh | 2 +- .../test_driver/integration_test_driver.dart | 2 +- .../url_launcher_web/example/web/index.html | 2 +- .../url_launcher_web/lib/src/link.dart | 2 +- .../lib/src/shims/dart_ui.dart | 2 +- .../lib/src/shims/dart_ui_fake.dart | 2 +- .../lib/src/shims/dart_ui_real.dart | 2 +- .../lib/url_launcher_web.dart | 2 +- .../test/tests_exist_elsewhere_test.dart | 2 +- .../url_launcher/url_launcher_windows/LICENSE | 2 +- .../integration_test/url_launcher_test.dart | 2 +- .../example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../example/windows/runner/flutter_window.cpp | 2 +- .../example/windows/runner/flutter_window.h | 2 +- .../example/windows/runner/main.cpp | 2 +- .../example/windows/runner/run_loop.cpp | 2 +- .../example/windows/runner/run_loop.h | 2 +- .../example/windows/runner/utils.cpp | 2 +- .../example/windows/runner/utils.h | 2 +- .../example/windows/runner/win32_window.cpp | 2 +- .../example/windows/runner/win32_window.h | 2 +- .../url_launcher_plugin.h | 2 +- .../windows/url_launcher_plugin.cpp | 2 +- packages/video_player/video_player/LICENSE | 2 +- .../videoplayer/CustomSSLSocketFactory.java | 2 +- .../flutter/plugins/videoplayer/Messages.java | 2 +- .../plugins/videoplayer/QueuingEventSink.java | 2 +- .../plugins/videoplayer/VideoPlayer.java | 2 +- .../videoplayer/VideoPlayerOptions.java | 2 +- .../videoplayer/VideoPlayerPlugin.java | 2 +- .../EmbeddingV1Activity.java | 2 +- .../FlutterActivityTest.java | 2 +- .../integration_test/video_player_test.dart | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- .../video_player/example/ios/Runner/main.m | 2 +- .../video_player/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../example/test_driver/video_player.dart | 2 +- .../test_driver/video_player_test.dart | 2 +- .../video_player/example/web/index.html | 2 +- .../ios/Classes/FLTVideoPlayerPlugin.h | 2 +- .../ios/Classes/FLTVideoPlayerPlugin.m | 2 +- .../video_player/ios/Classes/messages.h | 2 +- .../video_player/ios/Classes/messages.m | 2 +- .../lib/src/closed_caption_file.dart | 2 +- .../video_player/lib/src/sub_rip.dart | 2 +- .../video_player/lib/video_player.dart | 2 +- .../video_player/pigeons/messages.dart | 2 +- .../test/closed_caption_file_test.dart | 2 +- .../video_player/test/sub_rip_file_test.dart | 2 +- .../video_player_initialization_test.dart | 2 +- .../video_player/test/video_player_test.dart | 2 +- .../video_player_platform_interface/LICENSE | 2 +- .../lib/messages.dart | 2 +- .../lib/method_channel_video_player.dart | 2 +- .../lib/test.dart | 2 +- .../lib/video_player_platform_interface.dart | 2 +- .../method_channel_video_player_test.dart | 2 +- .../video_player/video_player_web/LICENSE | 2 +- .../lib/src/shims/dart_ui.dart | 2 +- .../lib/src/shims/dart_ui_fake.dart | 2 +- .../lib/src/shims/dart_ui_real.dart | 2 +- .../lib/video_player_web.dart | 2 +- .../test/video_player_web_test.dart | 2 +- packages/webview_flutter/LICENSE | 2 +- .../webviewflutter/DisplayListenerProxy.java | 2 +- .../webviewflutter/FlutterCookieManager.java | 2 +- .../webviewflutter/FlutterWebView.java | 2 +- .../webviewflutter/FlutterWebViewClient.java | 2 +- .../webviewflutter/InputAwareWebView.java | 2 +- .../webviewflutter/JavaScriptChannel.java | 2 +- ...readedInputConnectionProxyAdapterView.java | 2 +- .../webviewflutter/WebViewFactory.java | 2 +- .../webviewflutter/WebViewFlutterPlugin.java | 2 +- .../EmbeddingV1ActivityTest.java | 2 +- .../MainActivityTest.java | 2 +- .../EmbeddingV1Activity.java | 2 +- .../webview_flutter_test.dart | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- .../webview_flutter/example/ios/Runner/main.m | 2 +- .../webview_flutter/example/lib/main.dart | 2 +- .../example/test_driver/integration_test.dart | 2 +- .../ios/Classes/FLTCookieManager.h | 2 +- .../ios/Classes/FLTCookieManager.m | 2 +- .../ios/Classes/FLTWKNavigationDelegate.h | 2 +- .../ios/Classes/FLTWKNavigationDelegate.m | 2 +- .../ios/Classes/FLTWKProgressionDelegate.h | 2 +- .../ios/Classes/FLTWKProgressionDelegate.m | 2 +- .../ios/Classes/FLTWebViewFlutterPlugin.h | 2 +- .../ios/Classes/FLTWebViewFlutterPlugin.m | 2 +- .../ios/Classes/FlutterWebView.h | 2 +- .../ios/Classes/FlutterWebView.m | 2 +- .../ios/Classes/JavaScriptChannelHandler.h | 2 +- .../ios/Classes/JavaScriptChannelHandler.m | 2 +- .../ios/Tests/FLTWKNavigationDelegateTests.m | 2 +- .../ios/Tests/FLTWebViewTests.m | 2 +- .../lib/platform_interface.dart | 2 +- .../lib/src/webview_android.dart | 2 +- .../lib/src/webview_cupertino.dart | 2 +- .../lib/src/webview_method_channel.dart | 2 +- .../webview_flutter/lib/webview_flutter.dart | 2 +- .../test/webview_flutter_test.dart | 2 +- .../wifi_info_flutter/LICENSE | 2 +- .../wifi_info_flutter/WifiInfoFlutter.java | 2 +- .../WifiInfoFlutterMethodChannelHandler.java | 2 +- .../WifiInfoFlutterPlugin.java | 2 +- .../MainActivity.java | 2 +- .../example/ios/Runner/AppDelegate.h | 2 +- .../example/ios/Runner/AppDelegate.m | 2 +- .../example/ios/Runner/main.m | 2 +- .../wifi_info_flutter/example/lib/main.dart | 2 +- .../integration_test/wifi_info_test.dart | 2 +- .../test_driver/test/integration_test.dart | 2 +- .../integration_test/wifi_info_test.dart | 2 +- .../ios/Classes/FLTWifiInfoLocationHandler.h | 2 +- .../ios/Classes/FLTWifiInfoLocationHandler.m | 2 +- .../ios/Classes/WifiInfoFlutterPlugin.h | 2 +- .../ios/Classes/WifiInfoFlutterPlugin.m | 2 +- .../lib/wifi_info_flutter.dart | 2 +- .../test/wifi_info_flutter_test.dart | 2 +- .../LICENSE | 2 +- .../lib/src/enums.dart | 2 +- .../src/method_channel_wifi_info_flutter.dart | 2 +- .../wifi_info_flutter_platform_interface.dart | 2 +- ...method_channel_wifi_info_flutter_test.dart | 2 +- script/build_all_plugins_app.sh | 2 +- script/check_publish.sh | 2 +- script/common.sh | 2 +- script/incremental_build.sh | 2 +- script/tool/lib/src/analyze_command.dart | 2 +- .../tool/lib/src/build_examples_command.dart | 2 +- script/tool/lib/src/common.dart | 2 +- .../src/create_all_plugins_app_command.dart | 2 +- .../tool/lib/src/drive_examples_command.dart | 2 +- .../lib/src/firebase_test_lab_command.dart | 2 +- script/tool/lib/src/format_command.dart | 2 +- script/tool/lib/src/java_test_command.dart | 2 +- .../tool/lib/src/license_check_command.dart | 140 ++++++++---------- .../tool/lib/src/lint_podspecs_command.dart | 2 +- script/tool/lib/src/list_command.dart | 2 +- script/tool/lib/src/main.dart | 2 +- .../tool/lib/src/publish_check_command.dart | 2 +- .../tool/lib/src/publish_plugin_command.dart | 2 +- script/tool/lib/src/test_command.dart | 2 +- .../tool/lib/src/version_check_command.dart | 2 +- script/tool/lib/src/xctest_command.dart | 2 +- script/tool/test/analyze_command_test.dart | 2 +- .../test/build_examples_command_test.dart | 2 +- script/tool/test/common_test.dart | 2 +- .../test/drive_examples_command_test.dart | 2 +- script/tool/test/firebase_test_lab_test.dart | 2 +- .../tool/test/license_check_command_test.dart | 56 ++++--- .../tool/test/lint_podspecs_command_test.dart | 2 +- script/tool/test/list_command_test.dart | 2 +- script/tool/test/mocks.dart | 2 +- .../test/publish_plugin_command_test.dart | 2 +- script/tool/test/test_command_test.dart | 2 +- script/tool/test/util.dart | 2 +- script/tool/test/version_check_test.dart | 2 +- script/tool/test/xctest_command_test.dart | 2 +- 1153 files changed, 1248 insertions(+), 1250 deletions(-) diff --git a/LICENSE b/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/android_alarm_manager/LICENSE b/packages/android_alarm_manager/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/android_alarm_manager/LICENSE +++ b/packages/android_alarm_manager/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmBroadcastReceiver.java b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmBroadcastReceiver.java index 0b8a1455f9ae..c471643628bc 100644 --- a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmBroadcastReceiver.java +++ b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmBroadcastReceiver.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmService.java b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmService.java index 5311911a3d7d..d333a4950026 100644 --- a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmService.java +++ b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmService.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AndroidAlarmManagerPlugin.java b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AndroidAlarmManagerPlugin.java index 1587bca71a80..fd3a9c5e87dd 100644 --- a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AndroidAlarmManagerPlugin.java +++ b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AndroidAlarmManagerPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/FlutterBackgroundExecutor.java b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/FlutterBackgroundExecutor.java index fc438753f3cc..d9c40bfe7181 100644 --- a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/FlutterBackgroundExecutor.java +++ b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/FlutterBackgroundExecutor.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/PluginRegistrantException.java b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/PluginRegistrantException.java index f38c2b8b0461..afbc1c71bd3f 100644 --- a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/PluginRegistrantException.java +++ b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/PluginRegistrantException.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/RebootBroadcastReceiver.java b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/RebootBroadcastReceiver.java index 5f5c5cacd86f..9135755863a1 100644 --- a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/RebootBroadcastReceiver.java +++ b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/RebootBroadcastReceiver.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/BackgroundExecutionTest.java b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/BackgroundExecutionTest.java index 457599b0da91..d6927232fb80 100644 --- a/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/BackgroundExecutionTest.java +++ b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/BackgroundExecutionTest.java @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/DriverExtensionActivity.java b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/DriverExtensionActivity.java index 57c3f4122578..9a57f2c1d914 100644 --- a/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/DriverExtensionActivity.java +++ b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/DriverExtensionActivity.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/MainActivityTest.java b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/MainActivityTest.java index 82503c9d54c5..0272c14a8328 100644 --- a/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/MainActivityTest.java +++ b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/MainActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/Application.java b/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/Application.java index e2b3e8aae73d..fc83d38128c4 100644 --- a/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/Application.java +++ b/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/Application.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/EmbeddingV1Activity.java b/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/EmbeddingV1Activity.java index 8e77dbd1b46b..fa4b1422f474 100644 --- a/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/EmbeddingV1Activity.java +++ b/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart b/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart index 67dcb520a3a2..37b5659f09f4 100644 --- a/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart +++ b/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_alarm_manager/example/lib/main.dart b/packages/android_alarm_manager/example/lib/main.dart index ff164a6275b3..75648b8ded5f 100644 --- a/packages/android_alarm_manager/example/lib/main.dart +++ b/packages/android_alarm_manager/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_alarm_manager/example/test_driver/integration_test.dart b/packages/android_alarm_manager/example/test_driver/integration_test.dart index 88461d1c79a1..c08f4a817f6c 100644 --- a/packages/android_alarm_manager/example/test_driver/integration_test.dart +++ b/packages/android_alarm_manager/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_alarm_manager/lib/android_alarm_manager.dart b/packages/android_alarm_manager/lib/android_alarm_manager.dart index e074dfb3af36..e4e3855933ca 100644 --- a/packages/android_alarm_manager/lib/android_alarm_manager.dart +++ b/packages/android_alarm_manager/lib/android_alarm_manager.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_alarm_manager/test/android_alarm_manager_test.dart b/packages/android_alarm_manager/test/android_alarm_manager_test.dart index 4b340f563fd4..908bb957c0f2 100644 --- a/packages/android_alarm_manager/test/android_alarm_manager_test.dart +++ b/packages/android_alarm_manager/test/android_alarm_manager_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_intent/LICENSE b/packages/android_intent/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/android_intent/LICENSE +++ b/packages/android_intent/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java index ff73b6de5485..883d05922874 100644 --- a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java +++ b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/IntentSender.java b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/IntentSender.java index 1c9aa9ac6b02..2c05a914c888 100644 --- a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/IntentSender.java +++ b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/IntentSender.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/MethodCallHandlerImpl.java b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/MethodCallHandlerImpl.java index 9bdcbec08465..bcd843b64228 100644 --- a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/MethodCallHandlerImpl.java +++ b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/MethodCallHandlerImpl.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java b/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java index bf3fdf976d9d..0ea03a0690f1 100644 --- a/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java +++ b/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/EmbeddingV1ActivityTest.java b/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/EmbeddingV1ActivityTest.java index a370318927ba..36f8444dea62 100644 --- a/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/EmbeddingV1ActivityTest.java +++ b/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/MainActivityTest.java b/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/MainActivityTest.java index f7cddca2832f..d9ba10729001 100644 --- a/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/MainActivityTest.java +++ b/packages/android_intent/example/android/app/src/androidTestDebug/java/io/flutter/plugins/androidintentexample/MainActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_intent/example/android/app/src/main/java/io/flutter/plugins/androidintentexample/EmbeddingV1Activity.java b/packages/android_intent/example/android/app/src/main/java/io/flutter/plugins/androidintentexample/EmbeddingV1Activity.java index 87e822274f85..5906a8940236 100644 --- a/packages/android_intent/example/android/app/src/main/java/io/flutter/plugins/androidintentexample/EmbeddingV1Activity.java +++ b/packages/android_intent/example/android/app/src/main/java/io/flutter/plugins/androidintentexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_intent/example/integration_test/android_intent_test.dart b/packages/android_intent/example/integration_test/android_intent_test.dart index 28de6b785c70..5ae86cba6a03 100644 --- a/packages/android_intent/example/integration_test/android_intent_test.dart +++ b/packages/android_intent/example/integration_test/android_intent_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_intent/example/lib/main.dart b/packages/android_intent/example/lib/main.dart index 99413c1d5701..c2276d080aa4 100644 --- a/packages/android_intent/example/lib/main.dart +++ b/packages/android_intent/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_intent/example/test_driver/integration_test.dart b/packages/android_intent/example/test_driver/integration_test.dart index 993729f6ac3d..cc91e52ef2ef 100644 --- a/packages/android_intent/example/test_driver/integration_test.dart +++ b/packages/android_intent/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_intent/lib/android_intent.dart b/packages/android_intent/lib/android_intent.dart index 698a584ce7ea..80208833c6be 100644 --- a/packages/android_intent/lib/android_intent.dart +++ b/packages/android_intent/lib/android_intent.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_intent/lib/flag.dart b/packages/android_intent/lib/flag.dart index 147c6a1d932c..771a89ff83a7 100644 --- a/packages/android_intent/lib/flag.dart +++ b/packages/android_intent/lib/flag.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/android_intent/test/android_intent_test.dart b/packages/android_intent/test/android_intent_test.dart index 95ff345395cf..00bcc7664908 100644 --- a/packages/android_intent/test/android_intent_test.dart +++ b/packages/android_intent/test/android_intent_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/battery/battery/LICENSE b/packages/battery/battery/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/battery/battery/LICENSE +++ b/packages/battery/battery/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/battery/battery/android/src/main/java/io/flutter/plugins/battery/BatteryPlugin.java b/packages/battery/battery/android/src/main/java/io/flutter/plugins/battery/BatteryPlugin.java index 92405a9900d3..7f2e1efbeede 100644 --- a/packages/battery/battery/android/src/main/java/io/flutter/plugins/battery/BatteryPlugin.java +++ b/packages/battery/battery/android/src/main/java/io/flutter/plugins/battery/BatteryPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/battery/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/EmbedderV1ActivityTest.java b/packages/battery/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/EmbedderV1ActivityTest.java index 3c4eabeaf23f..c939be4281da 100644 --- a/packages/battery/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/EmbedderV1ActivityTest.java +++ b/packages/battery/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/EmbedderV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/battery/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/FlutterActivityTest.java b/packages/battery/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/FlutterActivityTest.java index 2fec9365b756..267271f70f42 100644 --- a/packages/battery/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/FlutterActivityTest.java +++ b/packages/battery/battery/example/android/app/src/androidTest/java/io/flutter/plugins/battery/FlutterActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/battery/battery/example/android/app/src/main/java/io/flutter/plugins/batteryexample/EmbedderV1Activity.java b/packages/battery/battery/example/android/app/src/main/java/io/flutter/plugins/batteryexample/EmbedderV1Activity.java index 6877a5013737..2b9e538bbe47 100644 --- a/packages/battery/battery/example/android/app/src/main/java/io/flutter/plugins/batteryexample/EmbedderV1Activity.java +++ b/packages/battery/battery/example/android/app/src/main/java/io/flutter/plugins/batteryexample/EmbedderV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/battery/battery/example/ios/Runner/AppDelegate.h b/packages/battery/battery/example/ios/Runner/AppDelegate.h index 31fc381e7066..0681d288bb70 100644 --- a/packages/battery/battery/example/ios/Runner/AppDelegate.h +++ b/packages/battery/battery/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/battery/battery/example/ios/Runner/AppDelegate.m b/packages/battery/battery/example/ios/Runner/AppDelegate.m index abfe2106b092..b790a0a52635 100644 --- a/packages/battery/battery/example/ios/Runner/AppDelegate.m +++ b/packages/battery/battery/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/battery/battery/example/ios/Runner/main.m b/packages/battery/battery/example/ios/Runner/main.m index f451b14cb751..f97b9ef5c8a1 100644 --- a/packages/battery/battery/example/ios/Runner/main.m +++ b/packages/battery/battery/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/battery/battery/example/lib/main.dart b/packages/battery/battery/example/lib/main.dart index 8c0edec04f74..b139d0d8e4be 100644 --- a/packages/battery/battery/example/lib/main.dart +++ b/packages/battery/battery/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/battery/battery/integration_test/battery_test.dart b/packages/battery/battery/integration_test/battery_test.dart index 4912f3f81fd3..24f5a5adc7f9 100644 --- a/packages/battery/battery/integration_test/battery_test.dart +++ b/packages/battery/battery/integration_test/battery_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/battery/battery/ios/Classes/FLTBatteryPlugin.h b/packages/battery/battery/ios/Classes/FLTBatteryPlugin.h index b555de48ebf4..fd6a3e964d83 100644 --- a/packages/battery/battery/ios/Classes/FLTBatteryPlugin.h +++ b/packages/battery/battery/ios/Classes/FLTBatteryPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/battery/battery/ios/Classes/FLTBatteryPlugin.m b/packages/battery/battery/ios/Classes/FLTBatteryPlugin.m index 151dbda1ce32..558d395bb9c0 100644 --- a/packages/battery/battery/ios/Classes/FLTBatteryPlugin.m +++ b/packages/battery/battery/ios/Classes/FLTBatteryPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/battery/battery/lib/battery.dart b/packages/battery/battery/lib/battery.dart index 8781979a7eac..92e54be095fe 100644 --- a/packages/battery/battery/lib/battery.dart +++ b/packages/battery/battery/lib/battery.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/battery/battery/test/battery_test.dart b/packages/battery/battery/test/battery_test.dart index 5db0798d906e..8870acb775de 100644 --- a/packages/battery/battery/test/battery_test.dart +++ b/packages/battery/battery/test/battery_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/battery/battery_platform_interface/LICENSE b/packages/battery/battery_platform_interface/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/battery/battery_platform_interface/LICENSE +++ b/packages/battery/battery_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/battery/battery_platform_interface/lib/battery_platform_interface.dart b/packages/battery/battery_platform_interface/lib/battery_platform_interface.dart index c839b02bc18d..548edf8257f5 100644 --- a/packages/battery/battery_platform_interface/lib/battery_platform_interface.dart +++ b/packages/battery/battery_platform_interface/lib/battery_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/battery/battery_platform_interface/lib/enums/battery_state.dart b/packages/battery/battery_platform_interface/lib/enums/battery_state.dart index b8458224df4a..a525e78ccdf5 100644 --- a/packages/battery/battery_platform_interface/lib/enums/battery_state.dart +++ b/packages/battery/battery_platform_interface/lib/enums/battery_state.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/battery/battery_platform_interface/lib/method_channel/method_channel_battery.dart b/packages/battery/battery_platform_interface/lib/method_channel/method_channel_battery.dart index 8f38b6616702..1d0a8329c257 100644 --- a/packages/battery/battery_platform_interface/lib/method_channel/method_channel_battery.dart +++ b/packages/battery/battery_platform_interface/lib/method_channel/method_channel_battery.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/battery/battery_platform_interface/test/method_channel_battery_test.dart b/packages/battery/battery_platform_interface/test/method_channel_battery_test.dart index 0e36e0a1fbba..6a312ee73ef2 100644 --- a/packages/battery/battery_platform_interface/test/method_channel_battery_test.dart +++ b/packages/battery/battery_platform_interface/test/method_channel_battery_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/LICENSE b/packages/camera/camera/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/camera/camera/LICENSE +++ b/packages/camera/camera/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 4faedf3aa0c2..4c1370f2f3cb 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPermissions.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPermissions.java index 4442fce9b2fd..7d60e0fffa5c 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPermissions.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPermissions.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java index 849ca3ccc489..75730ab41711 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegions.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegions.java index 67030ebe9667..60c866cd82d5 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegions.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraRegions.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java index 4ad260f7347f..b4d4689f2b4e 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraZoom.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraZoom.java index ff3f04ade0fd..42ad6d76dcfc 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraZoom.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraZoom.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java index 8e7be0937000..164a529ffa8b 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java index af1a0c2082c5..634596dde8bb 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DeviceOrientationManager.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java index c1afd64febec..040225ed5ff3 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java index 4a6fafff50c8..4c11e2d40e62 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/PictureCaptureRequest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/media/MediaRecorderBuilder.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/media/MediaRecorderBuilder.java index 9873a3c12972..a78c2b47b7ad 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/media/MediaRecorderBuilder.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/media/MediaRecorderBuilder.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ExposureMode.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ExposureMode.java index fd2475649b89..0bd23945e3f7 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ExposureMode.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ExposureMode.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java index 3880874779be..d7b661380098 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FlashMode.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FocusMode.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FocusMode.java index d4e8348ab8ed..c879593d4f21 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FocusMode.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/FocusMode.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ResolutionPreset.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ResolutionPreset.java index 1c2ce8b0c8aa..a70d85688037 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ResolutionPreset.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/types/ResolutionPreset.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraPermissionsTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraPermissionsTest.java index 930b5ad08ab3..ecb96a88f31a 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraPermissionsTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraPermissionsTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionsTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionsTest.java index d0074d295ca2..6a04b14fe21e 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionsTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraRegionsTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraUtilsTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraUtilsTest.java index aa89669459bb..b97192b889cf 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraUtilsTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraUtilsTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraZoomTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraZoomTest.java index 445174b3b357..1385c2e36949 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraZoomTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/CameraZoomTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java index ff77b32cd1d0..ed6fd56a3c34 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java index 8542fc615c35..f257a7f7fd4b 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/PictureCaptureRequestTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/media/MediaRecorderBuilderTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/media/MediaRecorderBuilderTest.java index 04eb3e031cca..9b8b54cc959c 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/media/MediaRecorderBuilderTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/media/MediaRecorderBuilderTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/ExposureModeTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/ExposureModeTest.java index 600c426063e2..5f4bd9f89ec7 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/ExposureModeTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/ExposureModeTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java index 8b812b4b011d..5a53648bc51e 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FlashModeTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FocusModeTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FocusModeTest.java index 114aaa342e9b..58e6d7ce3306 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FocusModeTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/types/FocusModeTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/EmbeddingV1ActivityTest.java b/packages/camera/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/EmbeddingV1ActivityTest.java index 08ae8e4274af..9cd4ef60991b 100644 --- a/packages/camera/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/EmbeddingV1ActivityTest.java +++ b/packages/camera/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/FlutterActivityTest.java b/packages/camera/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/FlutterActivityTest.java index 4f30e83a138c..32acc1ba9c15 100644 --- a/packages/camera/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/FlutterActivityTest.java +++ b/packages/camera/camera/example/android/app/src/androidTestDebug/java/io/flutter/plugins/cameraexample/FlutterActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/example/android/app/src/main/java/io/flutter/plugins/cameraexample/EmbeddingV1Activity.java b/packages/camera/camera/example/android/app/src/main/java/io/flutter/plugins/cameraexample/EmbeddingV1Activity.java index e30d5ec7b07b..406e1417e3af 100644 --- a/packages/camera/camera/example/android/app/src/main/java/io/flutter/plugins/cameraexample/EmbeddingV1Activity.java +++ b/packages/camera/camera/example/android/app/src/main/java/io/flutter/plugins/cameraexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/example/integration_test/camera_test.dart b/packages/camera/camera/example/integration_test/camera_test.dart index 1b08200ed68d..7767ac0c6979 100644 --- a/packages/camera/camera/example/integration_test/camera_test.dart +++ b/packages/camera/camera/example/integration_test/camera_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/example/ios/Runner/AppDelegate.h b/packages/camera/camera/example/ios/Runner/AppDelegate.h index 31fc381e7066..0681d288bb70 100644 --- a/packages/camera/camera/example/ios/Runner/AppDelegate.h +++ b/packages/camera/camera/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/example/ios/Runner/AppDelegate.m b/packages/camera/camera/example/ios/Runner/AppDelegate.m index 2147d3d605ac..30b87969f44a 100644 --- a/packages/camera/camera/example/ios/Runner/AppDelegate.m +++ b/packages/camera/camera/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/example/ios/Runner/main.m b/packages/camera/camera/example/ios/Runner/main.m index f451b14cb751..f97b9ef5c8a1 100644 --- a/packages/camera/camera/example/ios/Runner/main.m +++ b/packages/camera/camera/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/example/lib/main.dart b/packages/camera/camera/example/lib/main.dart index 0148ce41d725..536e95de9c8b 100644 --- a/packages/camera/camera/example/lib/main.dart +++ b/packages/camera/camera/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/example/test_driver/integration_test.dart b/packages/camera/camera/example/test_driver/integration_test.dart index 0ad951cb063d..fac399066292 100644 --- a/packages/camera/camera/example/test_driver/integration_test.dart +++ b/packages/camera/camera/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.h b/packages/camera/camera/ios/Classes/CameraPlugin.h index f42084125e6c..f13d810445bc 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.h +++ b/packages/camera/camera/ios/Classes/CameraPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index 308ca886a45f..e867491fcf8f 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/ios/Tests/CameraPluginTests.m b/packages/camera/camera/ios/Tests/CameraPluginTests.m index 3d8443901672..25496d539dc8 100644 --- a/packages/camera/camera/ios/Tests/CameraPluginTests.m +++ b/packages/camera/camera/ios/Tests/CameraPluginTests.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/lib/camera.dart b/packages/camera/camera/lib/camera.dart index daab70128ada..1e24efbd3dc6 100644 --- a/packages/camera/camera/lib/camera.dart +++ b/packages/camera/camera/lib/camera.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index f7710d45c7fd..3284a9b01fa2 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/lib/src/camera_image.dart b/packages/camera/camera/lib/src/camera_image.dart index fd551082bc83..411c7e86db41 100644 --- a/packages/camera/camera/lib/src/camera_image.dart +++ b/packages/camera/camera/lib/src/camera_image.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/lib/src/camera_preview.dart b/packages/camera/camera/lib/src/camera_preview.dart index caa8c04885c7..517751b7bf64 100644 --- a/packages/camera/camera/lib/src/camera_preview.dart +++ b/packages/camera/camera/lib/src/camera_preview.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/test/camera_image_stream_test.dart b/packages/camera/camera/test/camera_image_stream_test.dart index 6832466a25ba..d971103b3636 100644 --- a/packages/camera/camera/test/camera_image_stream_test.dart +++ b/packages/camera/camera/test/camera_image_stream_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/test/camera_image_test.dart b/packages/camera/camera/test/camera_image_test.dart index 40d7194e36d1..2d827d983f3a 100644 --- a/packages/camera/camera/test/camera_image_test.dart +++ b/packages/camera/camera/test/camera_image_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index 272587e9955b..26382a9b7d60 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/test/camera_value_test.dart b/packages/camera/camera/test/camera_value_test.dart index f1809fc61167..e0378cca2cb9 100644 --- a/packages/camera/camera/test/camera_value_test.dart +++ b/packages/camera/camera/test/camera_value_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera/test/utils/method_channel_mock.dart b/packages/camera/camera/test/utils/method_channel_mock.dart index 6e0b28e224d8..60d8def6a2e3 100644 --- a/packages/camera/camera/test/utils/method_channel_mock.dart +++ b/packages/camera/camera/test/utils/method_channel_mock.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/LICENSE b/packages/camera/camera_platform_interface/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/camera/camera_platform_interface/LICENSE +++ b/packages/camera/camera_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/camera/camera_platform_interface/lib/camera_platform_interface.dart b/packages/camera/camera_platform_interface/lib/camera_platform_interface.dart index b7a7b2ff29b8..3ec66dd54894 100644 --- a/packages/camera/camera_platform_interface/lib/camera_platform_interface.dart +++ b/packages/camera/camera_platform_interface/lib/camera_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart b/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart index 137a0002ef17..591d5a336356 100644 --- a/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart +++ b/packages/camera/camera_platform_interface/lib/src/events/camera_event.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/lib/src/events/device_event.dart b/packages/camera/camera_platform_interface/lib/src/events/device_event.dart index a4edbef0d317..c6cedd135fed 100644 --- a/packages/camera/camera_platform_interface/lib/src/events/device_event.dart +++ b/packages/camera/camera_platform_interface/lib/src/events/device_event.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart index 321104e695e9..c6c363a56d65 100644 --- a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart +++ b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart index 92e3587ee04b..4437d3b0593a 100644 --- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart +++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/lib/src/types/camera_description.dart b/packages/camera/camera_platform_interface/lib/src/types/camera_description.dart index dffb5d1bff01..98a39fd6c65e 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/camera_description.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/camera_description.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/lib/src/types/camera_exception.dart b/packages/camera/camera_platform_interface/lib/src/types/camera_exception.dart index f8da81392b43..d112f9f6f6e3 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/camera_exception.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/camera_exception.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart b/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart index a1cfbfcc08a5..1debd19b3a26 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/exposure_mode.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/lib/src/types/flash_mode.dart b/packages/camera/camera_platform_interface/lib/src/types/flash_mode.dart index e851857a26d6..b9f146d373d3 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/flash_mode.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/flash_mode.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/lib/src/types/focus_mode.dart b/packages/camera/camera_platform_interface/lib/src/types/focus_mode.dart index 76d429463a29..60a419155149 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/focus_mode.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/focus_mode.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart index 3c07dfe0faca..edbf7d24098c 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/lib/src/types/resolution_preset.dart b/packages/camera/camera_platform_interface/lib/src/types/resolution_preset.dart index cabeb6a0b9cc..1724f6c97517 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/resolution_preset.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/resolution_preset.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/lib/src/types/types.dart b/packages/camera/camera_platform_interface/lib/src/types/types.dart index 5b9999ece037..0927458299df 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/types.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/types.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/lib/src/utils/utils.dart b/packages/camera/camera_platform_interface/lib/src/utils/utils.dart index b8703d603801..8c455867762f 100644 --- a/packages/camera/camera_platform_interface/lib/src/utils/utils.dart +++ b/packages/camera/camera_platform_interface/lib/src/utils/utils.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart b/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart index b3d61a467373..c8f38efc4e2d 100644 --- a/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart +++ b/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/test/events/camera_event_test.dart b/packages/camera/camera_platform_interface/test/events/camera_event_test.dart index 120cafc238c3..637358f557c3 100644 --- a/packages/camera/camera_platform_interface/test/events/camera_event_test.dart +++ b/packages/camera/camera_platform_interface/test/events/camera_event_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/test/events/device_event_test.dart b/packages/camera/camera_platform_interface/test/events/device_event_test.dart index 950a12e21484..f7cb657725a9 100644 --- a/packages/camera/camera_platform_interface/test/events/device_event_test.dart +++ b/packages/camera/camera_platform_interface/test/events/device_event_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart index ea7e9787a817..8a618545535b 100644 --- a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart +++ b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/test/types/camera_description_test.dart b/packages/camera/camera_platform_interface/test/types/camera_description_test.dart index a098df07b094..11a5210e831b 100644 --- a/packages/camera/camera_platform_interface/test/types/camera_description_test.dart +++ b/packages/camera/camera_platform_interface/test/types/camera_description_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/test/types/camera_exception_test.dart b/packages/camera/camera_platform_interface/test/types/camera_exception_test.dart index 338238e0bb75..5fb753fb3616 100644 --- a/packages/camera/camera_platform_interface/test/types/camera_exception_test.dart +++ b/packages/camera/camera_platform_interface/test/types/camera_exception_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/test/types/exposure_mode_test.dart b/packages/camera/camera_platform_interface/test/types/exposure_mode_test.dart index b8e77fe5df80..659b75e017f1 100644 --- a/packages/camera/camera_platform_interface/test/types/exposure_mode_test.dart +++ b/packages/camera/camera_platform_interface/test/types/exposure_mode_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/test/types/flash_mode_test.dart b/packages/camera/camera_platform_interface/test/types/flash_mode_test.dart index 8c6903087fdd..d313bcf52b77 100644 --- a/packages/camera/camera_platform_interface/test/types/flash_mode_test.dart +++ b/packages/camera/camera_platform_interface/test/types/flash_mode_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/test/types/focus_mode_test.dart b/packages/camera/camera_platform_interface/test/types/focus_mode_test.dart index 5ce379400e37..866f8ce07909 100644 --- a/packages/camera/camera_platform_interface/test/types/focus_mode_test.dart +++ b/packages/camera/camera_platform_interface/test/types/focus_mode_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/test/types/image_group_test.dart b/packages/camera/camera_platform_interface/test/types/image_group_test.dart index 9ae4b9bb4c3c..89585cc1ae35 100644 --- a/packages/camera/camera_platform_interface/test/types/image_group_test.dart +++ b/packages/camera/camera_platform_interface/test/types/image_group_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/test/types/resolution_preset_test.dart b/packages/camera/camera_platform_interface/test/types/resolution_preset_test.dart index 4da08cf2f0b7..55a4ac56cd9d 100644 --- a/packages/camera/camera_platform_interface/test/types/resolution_preset_test.dart +++ b/packages/camera/camera_platform_interface/test/types/resolution_preset_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/test/utils/method_channel_mock.dart b/packages/camera/camera_platform_interface/test/utils/method_channel_mock.dart index 6e0b28e224d8..60d8def6a2e3 100644 --- a/packages/camera/camera_platform_interface/test/utils/method_channel_mock.dart +++ b/packages/camera/camera_platform_interface/test/utils/method_channel_mock.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/camera/camera_platform_interface/test/utils/utils_test.dart b/packages/camera/camera_platform_interface/test/utils/utils_test.dart index d99f9ab01443..f1960eeb2e72 100644 --- a/packages/camera/camera_platform_interface/test/utils/utils_test.dart +++ b/packages/camera/camera_platform_interface/test/utils/utils_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/LICENSE b/packages/connectivity/connectivity/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/connectivity/connectivity/LICENSE +++ b/packages/connectivity/connectivity/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/Connectivity.java b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/Connectivity.java index f2f16ae61629..d7e254e84595 100644 --- a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/Connectivity.java +++ b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/Connectivity.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java index e44e7b4e8f5d..fbda187bd188 100644 --- a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java +++ b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityMethodChannelHandler.java b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityMethodChannelHandler.java index 3f8541ed1c54..06275498c4a9 100644 --- a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityMethodChannelHandler.java +++ b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityMethodChannelHandler.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityPlugin.java b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityPlugin.java index 91d00839145f..2287a0a30b86 100644 --- a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityPlugin.java +++ b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1Activity.java b/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1Activity.java index 89438471ace3..8329fa29e431 100644 --- a/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1Activity.java +++ b/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java b/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java index 1667a7317c68..e2bd59408d4b 100644 --- a/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java +++ b/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/FlutterActivityTest.java b/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/FlutterActivityTest.java index 8d7f9d0c460f..330f0050a1d8 100644 --- a/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/FlutterActivityTest.java +++ b/packages/connectivity/connectivity/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/FlutterActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/example/android/app/src/test/java/io/flutter/plugins/connectivityexample/ActivityTest.java b/packages/connectivity/connectivity/example/android/app/src/test/java/io/flutter/plugins/connectivityexample/ActivityTest.java index b531a2db2897..2cf03dd3c2f5 100644 --- a/packages/connectivity/connectivity/example/android/app/src/test/java/io/flutter/plugins/connectivityexample/ActivityTest.java +++ b/packages/connectivity/connectivity/example/android/app/src/test/java/io/flutter/plugins/connectivityexample/ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/example/ios/Runner/AppDelegate.h b/packages/connectivity/connectivity/example/ios/Runner/AppDelegate.h index 31fc381e7066..0681d288bb70 100644 --- a/packages/connectivity/connectivity/example/ios/Runner/AppDelegate.h +++ b/packages/connectivity/connectivity/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/example/ios/Runner/AppDelegate.m b/packages/connectivity/connectivity/example/ios/Runner/AppDelegate.m index 2147d3d605ac..30b87969f44a 100644 --- a/packages/connectivity/connectivity/example/ios/Runner/AppDelegate.m +++ b/packages/connectivity/connectivity/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/example/ios/Runner/main.m b/packages/connectivity/connectivity/example/ios/Runner/main.m index f451b14cb751..f97b9ef5c8a1 100644 --- a/packages/connectivity/connectivity/example/ios/Runner/main.m +++ b/packages/connectivity/connectivity/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/example/lib/main.dart b/packages/connectivity/connectivity/example/lib/main.dart index 6f6356f0fc2b..b6a6882cb12e 100644 --- a/packages/connectivity/connectivity/example/lib/main.dart +++ b/packages/connectivity/connectivity/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/example/macos/Runner/AppDelegate.swift b/packages/connectivity/connectivity/example/macos/Runner/AppDelegate.swift index ca19fe95f8cf..5cec4c48f620 100644 --- a/packages/connectivity/connectivity/example/macos/Runner/AppDelegate.swift +++ b/packages/connectivity/connectivity/example/macos/Runner/AppDelegate.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/example/macos/Runner/MainFlutterWindow.swift b/packages/connectivity/connectivity/example/macos/Runner/MainFlutterWindow.swift index 2ce11b78604b..32aaeedceb1f 100644 --- a/packages/connectivity/connectivity/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/connectivity/connectivity/example/macos/Runner/MainFlutterWindow.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/example/test_driver/integration_test/connectivity_test.dart b/packages/connectivity/connectivity/example/test_driver/integration_test/connectivity_test.dart index 13c9d4b5e8fb..454ddd4c351b 100644 --- a/packages/connectivity/connectivity/example/test_driver/integration_test/connectivity_test.dart +++ b/packages/connectivity/connectivity/example/test_driver/integration_test/connectivity_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/example/test_driver/test/integration_test.dart b/packages/connectivity/connectivity/example/test_driver/test/integration_test.dart index 9887033fc5dd..79c1875f85d2 100644 --- a/packages/connectivity/connectivity/example/test_driver/test/integration_test.dart +++ b/packages/connectivity/connectivity/example/test_driver/test/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/example/web/index.html b/packages/connectivity/connectivity/example/web/index.html index 97b1100c4244..c6fa1623be95 100644 --- a/packages/connectivity/connectivity/example/web/index.html +++ b/packages/connectivity/connectivity/example/web/index.html @@ -1,5 +1,5 @@ - diff --git a/packages/connectivity/connectivity/integration_test/connectivity_test.dart b/packages/connectivity/connectivity/integration_test/connectivity_test.dart index 13c9d4b5e8fb..454ddd4c351b 100644 --- a/packages/connectivity/connectivity/integration_test/connectivity_test.dart +++ b/packages/connectivity/connectivity/integration_test/connectivity_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/ios/Classes/FLTConnectivityPlugin.h b/packages/connectivity/connectivity/ios/Classes/FLTConnectivityPlugin.h index bb0ff07dc712..aec76adc0b58 100644 --- a/packages/connectivity/connectivity/ios/Classes/FLTConnectivityPlugin.h +++ b/packages/connectivity/connectivity/ios/Classes/FLTConnectivityPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/ios/Classes/FLTConnectivityPlugin.m b/packages/connectivity/connectivity/ios/Classes/FLTConnectivityPlugin.m index 241d01c1b007..ac37c2359137 100644 --- a/packages/connectivity/connectivity/ios/Classes/FLTConnectivityPlugin.m +++ b/packages/connectivity/connectivity/ios/Classes/FLTConnectivityPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/lib/connectivity.dart b/packages/connectivity/connectivity/lib/connectivity.dart index e4199d55f699..1b819d7470d2 100644 --- a/packages/connectivity/connectivity/lib/connectivity.dart +++ b/packages/connectivity/connectivity/lib/connectivity.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity/test/connectivity_test.dart b/packages/connectivity/connectivity/test/connectivity_test.dart index cde833c9d71e..e6c253e0d49a 100644 --- a/packages/connectivity/connectivity/test/connectivity_test.dart +++ b/packages/connectivity/connectivity/test/connectivity_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_for_web/LICENSE b/packages/connectivity/connectivity_for_web/LICENSE index 1d7bbaf70add..c6823b81eb84 100644 --- a/packages/connectivity/connectivity_for_web/LICENSE +++ b/packages/connectivity/connectivity_for_web/LICENSE @@ -1,4 +1,4 @@ -Copyright 2016 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/connectivity/connectivity_for_web/example/integration_test/network_information_test.dart b/packages/connectivity/connectivity_for_web/example/integration_test/network_information_test.dart index 1f4a1d5d8f60..e6faa30da4dc 100644 --- a/packages/connectivity/connectivity_for_web/example/integration_test/network_information_test.dart +++ b/packages/connectivity/connectivity_for_web/example/integration_test/network_information_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart b/packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart index 390a66556d10..556b6fe6fca0 100644 --- a/packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart +++ b/packages/connectivity/connectivity_for_web/example/integration_test/src/connectivity_mocks.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_for_web/example/run_test.sh b/packages/connectivity/connectivity_for_web/example/run_test.sh index 9bfce94f63b2..dbf0ec55fd8f 100755 --- a/packages/connectivity/connectivity_for_web/example/run_test.sh +++ b/packages/connectivity/connectivity_for_web/example/run_test.sh @@ -1,5 +1,5 @@ #!/usr/bin/bash -# Copyright 2017 The Flutter Authors. All rights reserved. +# Copyright 2013 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. diff --git a/packages/connectivity/connectivity_for_web/example/test_driver/integration_driver.dart b/packages/connectivity/connectivity_for_web/example/test_driver/integration_driver.dart index 0dd5f694f16b..f26b6a310cfe 100644 --- a/packages/connectivity/connectivity_for_web/example/test_driver/integration_driver.dart +++ b/packages/connectivity/connectivity_for_web/example/test_driver/integration_driver.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_for_web/example/web/index.html b/packages/connectivity/connectivity_for_web/example/web/index.html index 27464c33811a..7fb138cc90fa 100644 --- a/packages/connectivity/connectivity_for_web/example/web/index.html +++ b/packages/connectivity/connectivity_for_web/example/web/index.html @@ -1,5 +1,5 @@ - diff --git a/packages/connectivity/connectivity_for_web/lib/connectivity_for_web.dart b/packages/connectivity/connectivity_for_web/lib/connectivity_for_web.dart index 14de31db1125..d1c6811f5349 100644 --- a/packages/connectivity/connectivity_for_web/lib/connectivity_for_web.dart +++ b/packages/connectivity/connectivity_for_web/lib/connectivity_for_web.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart b/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart index 09fbeaf7fd0d..475ec0d675b7 100644 --- a/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart +++ b/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart b/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart index 2b319b1fb5ab..6554f7a8c124 100644 --- a/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart +++ b/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart b/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart index 9f1b111eccd3..691bd6da3bfb 100644 --- a/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart +++ b/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_for_web/test/tests_exist_elsewhere_test.dart b/packages/connectivity/connectivity_for_web/test/tests_exist_elsewhere_test.dart index 64d8e547e485..442c50144727 100644 --- a/packages/connectivity/connectivity_for_web/test/tests_exist_elsewhere_test.dart +++ b/packages/connectivity/connectivity_for_web/test/tests_exist_elsewhere_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_macos/LICENSE b/packages/connectivity/connectivity_macos/LICENSE index b257ce7c224c..c6823b81eb84 100644 --- a/packages/connectivity/connectivity_macos/LICENSE +++ b/packages/connectivity/connectivity_macos/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/connectivity/connectivity_macos/example/lib/main.dart b/packages/connectivity/connectivity_macos/example/lib/main.dart index 97baf2678fd3..d0e07341fe92 100644 --- a/packages/connectivity/connectivity_macos/example/lib/main.dart +++ b/packages/connectivity/connectivity_macos/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_macos/example/macos/Runner/AppDelegate.swift b/packages/connectivity/connectivity_macos/example/macos/Runner/AppDelegate.swift index ca19fe95f8cf..5cec4c48f620 100644 --- a/packages/connectivity/connectivity_macos/example/macos/Runner/AppDelegate.swift +++ b/packages/connectivity/connectivity_macos/example/macos/Runner/AppDelegate.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_macos/example/macos/Runner/MainFlutterWindow.swift b/packages/connectivity/connectivity_macos/example/macos/Runner/MainFlutterWindow.swift index 2ce11b78604b..32aaeedceb1f 100644 --- a/packages/connectivity/connectivity_macos/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/connectivity/connectivity_macos/example/macos/Runner/MainFlutterWindow.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_macos/example/test_driver/integration_test/connectivity_test.dart b/packages/connectivity/connectivity_macos/example/test_driver/integration_test/connectivity_test.dart index d38614076190..c6b05c73cde9 100644 --- a/packages/connectivity/connectivity_macos/example/test_driver/integration_test/connectivity_test.dart +++ b/packages/connectivity/connectivity_macos/example/test_driver/integration_test/connectivity_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_macos/example/test_driver/test/integration_test.dart b/packages/connectivity/connectivity_macos/example/test_driver/test/integration_test.dart index 49af1cbb81a5..9647a12d77ce 100644 --- a/packages/connectivity/connectivity_macos/example/test_driver/test/integration_test.dart +++ b/packages/connectivity/connectivity_macos/example/test_driver/test/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_macos/macos/Classes/ConnectivityPlugin.swift b/packages/connectivity/connectivity_macos/macos/Classes/ConnectivityPlugin.swift index 302c6d7d55e3..69efe80df5ac 100644 --- a/packages/connectivity/connectivity_macos/macos/Classes/ConnectivityPlugin.swift +++ b/packages/connectivity/connectivity_macos/macos/Classes/ConnectivityPlugin.swift @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_macos/macos/Classes/IPHelper.h b/packages/connectivity/connectivity_macos/macos/Classes/IPHelper.h index a1bc4ce12179..e5370fb349c3 100644 --- a/packages/connectivity/connectivity_macos/macos/Classes/IPHelper.h +++ b/packages/connectivity/connectivity_macos/macos/Classes/IPHelper.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_platform_interface/LICENSE b/packages/connectivity/connectivity_platform_interface/LICENSE index 67c7e2c52e46..c6823b81eb84 100644 --- a/packages/connectivity/connectivity_platform_interface/LICENSE +++ b/packages/connectivity/connectivity_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/connectivity/connectivity_platform_interface/lib/connectivity_platform_interface.dart b/packages/connectivity/connectivity_platform_interface/lib/connectivity_platform_interface.dart index b137509f650a..6667b353a4aa 100644 --- a/packages/connectivity/connectivity_platform_interface/lib/connectivity_platform_interface.dart +++ b/packages/connectivity/connectivity_platform_interface/lib/connectivity_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart b/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart index 9c8398f2f67a..b77f54cf60b2 100644 --- a/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart +++ b/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_platform_interface/lib/src/method_channel_connectivity.dart b/packages/connectivity/connectivity_platform_interface/lib/src/method_channel_connectivity.dart index f04eb9193fb5..bdf820ac3ba7 100644 --- a/packages/connectivity/connectivity_platform_interface/lib/src/method_channel_connectivity.dart +++ b/packages/connectivity/connectivity_platform_interface/lib/src/method_channel_connectivity.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart b/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart index 5c62c61220ec..3b5b753f6c29 100644 --- a/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart +++ b/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/connectivity/connectivity_platform_interface/test/method_channel_connectivity_test.dart b/packages/connectivity/connectivity_platform_interface/test/method_channel_connectivity_test.dart index 5ae66acabc36..38f4ac38b156 100644 --- a/packages/connectivity/connectivity_platform_interface/test/method_channel_connectivity_test.dart +++ b/packages/connectivity/connectivity_platform_interface/test/method_channel_connectivity_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/device_info/device_info/LICENSE b/packages/device_info/device_info/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/device_info/device_info/LICENSE +++ b/packages/device_info/device_info/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java b/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java index 28fdc888560b..9b766d7f8381 100644 --- a/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java +++ b/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java b/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java index fb44bc821e6d..531e5db0c237 100644 --- a/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java +++ b/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java b/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java index 6be74796a0b6..86966cd137bb 100644 --- a/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java +++ b/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1ActivityTest.java b/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1ActivityTest.java index ca680684e3ea..a9babfe803ae 100644 --- a/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1ActivityTest.java +++ b/packages/device_info/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/device_info/device_info/example/integration_test/device_info_test.dart b/packages/device_info/device_info/example/integration_test/device_info_test.dart index 9fbb682df2e8..abb2b5ea0b03 100644 --- a/packages/device_info/device_info/example/integration_test/device_info_test.dart +++ b/packages/device_info/device_info/example/integration_test/device_info_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/device_info/device_info/example/ios/Runner/AppDelegate.h b/packages/device_info/device_info/example/ios/Runner/AppDelegate.h index 31fc381e7066..0681d288bb70 100644 --- a/packages/device_info/device_info/example/ios/Runner/AppDelegate.h +++ b/packages/device_info/device_info/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/device_info/device_info/example/ios/Runner/AppDelegate.m b/packages/device_info/device_info/example/ios/Runner/AppDelegate.m index 2147d3d605ac..30b87969f44a 100644 --- a/packages/device_info/device_info/example/ios/Runner/AppDelegate.m +++ b/packages/device_info/device_info/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/device_info/device_info/example/ios/Runner/main.m b/packages/device_info/device_info/example/ios/Runner/main.m index f451b14cb751..f97b9ef5c8a1 100644 --- a/packages/device_info/device_info/example/ios/Runner/main.m +++ b/packages/device_info/device_info/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/device_info/device_info/example/lib/main.dart b/packages/device_info/device_info/example/lib/main.dart index 24129aa04b1c..44e3fb4ee2f7 100644 --- a/packages/device_info/device_info/example/lib/main.dart +++ b/packages/device_info/device_info/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/device_info/device_info/example/test_driver/integration_test.dart b/packages/device_info/device_info/example/test_driver/integration_test.dart index 29b5b21a5941..156ecae508c1 100644 --- a/packages/device_info/device_info/example/test_driver/integration_test.dart +++ b/packages/device_info/device_info/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.h b/packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.h index e4e287c584d5..511b5b893fcb 100644 --- a/packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.h +++ b/packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.m b/packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.m index bc2d172c576e..3d4d25ad9c6e 100644 --- a/packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.m +++ b/packages/device_info/device_info/ios/Classes/FLTDeviceInfoPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/device_info/device_info/lib/device_info.dart b/packages/device_info/device_info/lib/device_info.dart index a357844cf2d9..1153ac6f7da6 100644 --- a/packages/device_info/device_info/lib/device_info.dart +++ b/packages/device_info/device_info/lib/device_info.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/device_info/device_info_platform_interface/LICENSE b/packages/device_info/device_info_platform_interface/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/device_info/device_info_platform_interface/LICENSE +++ b/packages/device_info/device_info_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/device_info/device_info_platform_interface/lib/device_info_platform_interface.dart b/packages/device_info/device_info_platform_interface/lib/device_info_platform_interface.dart index 676207ba07fe..a40363b2dcb6 100644 --- a/packages/device_info/device_info_platform_interface/lib/device_info_platform_interface.dart +++ b/packages/device_info/device_info_platform_interface/lib/device_info_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/device_info/device_info_platform_interface/lib/method_channel/method_channel_device_info.dart b/packages/device_info/device_info_platform_interface/lib/method_channel/method_channel_device_info.dart index d9eb455684e7..3c19e57f66a8 100644 --- a/packages/device_info/device_info_platform_interface/lib/method_channel/method_channel_device_info.dart +++ b/packages/device_info/device_info_platform_interface/lib/method_channel/method_channel_device_info.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/device_info/device_info_platform_interface/lib/model/android_device_info.dart b/packages/device_info/device_info_platform_interface/lib/model/android_device_info.dart index 00195a8f42b2..961d373e2dea 100644 --- a/packages/device_info/device_info_platform_interface/lib/model/android_device_info.dart +++ b/packages/device_info/device_info_platform_interface/lib/model/android_device_info.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/device_info/device_info_platform_interface/lib/model/ios_device_info.dart b/packages/device_info/device_info_platform_interface/lib/model/ios_device_info.dart index e779ddc8a129..17c96a3e250a 100644 --- a/packages/device_info/device_info_platform_interface/lib/model/ios_device_info.dart +++ b/packages/device_info/device_info_platform_interface/lib/model/ios_device_info.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart b/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart index cc0b4b4d10a7..14ed7c0aefb4 100644 --- a/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart +++ b/packages/device_info/device_info_platform_interface/test/method_channel_device_info_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/LICENSE b/packages/espresso/LICENSE index b257ce7c224c..c6823b81eb84 100644 --- a/packages/espresso/LICENSE +++ b/packages/espresso/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/EspressoFlutter.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/EspressoFlutter.java index 89233e64799f..3ba1762117c3 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/EspressoFlutter.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/EspressoFlutter.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/ActionUtil.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/ActionUtil.java index 8ab4c4a137cf..73f8c111b6cf 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/ActionUtil.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/ActionUtil.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/ClickAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/ClickAction.java index 949c1e1cffbd..d2e251e887e3 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/ClickAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/ClickAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterActions.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterActions.java index 3fdcb08eb525..2f0c171e780d 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterActions.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterActions.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterScrollToAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterScrollToAction.java index 4462ff6d6646..04692155fc80 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterScrollToAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterScrollToAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterTypeTextAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterTypeTextAction.java index b0b744773066..3de8aec56622 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterTypeTextAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterTypeTextAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterViewAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterViewAction.java index 0d8d94844d97..7031915f1ca1 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterViewAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/FlutterViewAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/SyntheticClickAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/SyntheticClickAction.java index ddc347defa55..fa238cbe76c0 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/SyntheticClickAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/SyntheticClickAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WaitUntilIdleAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WaitUntilIdleAction.java index 054c00e86d60..a4c2c95bade4 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WaitUntilIdleAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WaitUntilIdleAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WidgetCoordinatesCalculator.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WidgetCoordinatesCalculator.java index 0ef5a5761dc3..13de56e5a616 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WidgetCoordinatesCalculator.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WidgetCoordinatesCalculator.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WidgetInfoFetcher.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WidgetInfoFetcher.java index 3e5f48d56983..d922b1fb33ae 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WidgetInfoFetcher.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/action/WidgetInfoFetcher.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/FlutterAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/FlutterAction.java index 3f1d3a23d99a..71e851d2a959 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/FlutterAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/FlutterAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/FlutterTestingProtocol.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/FlutterTestingProtocol.java index 54be97652157..68429bfbdcd0 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/FlutterTestingProtocol.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/FlutterTestingProtocol.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/SyntheticAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/SyntheticAction.java index 0d2f0cbf49cf..41af3e99dfda 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/SyntheticAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/SyntheticAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetAction.java index b04cb0cb1d8a..012066cc3f80 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetAssertion.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetAssertion.java index d69972b09b3f..9cd36f1df363 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetAssertion.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetAssertion.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetMatcher.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetMatcher.java index a8e0b6a07c75..5c983c118ede 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetMatcher.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/api/WidgetMatcher.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/assertion/FlutterAssertions.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/assertion/FlutterAssertions.java index 6573f2a2a705..0a6b2b791545 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/assertion/FlutterAssertions.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/assertion/FlutterAssertions.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/assertion/FlutterViewAssertion.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/assertion/FlutterViewAssertion.java index 6bc81b5862e4..1233e9f35edf 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/assertion/FlutterViewAssertion.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/assertion/FlutterViewAssertion.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/common/Constants.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/common/Constants.java index 170830fc7abb..359d50ae4fba 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/common/Constants.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/common/Constants.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/common/Duration.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/common/Duration.java index 1d7bac224ec6..086ee47ad52c 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/common/Duration.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/common/Duration.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/AmbiguousWidgetMatcherException.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/AmbiguousWidgetMatcherException.java index adf2e39db0b8..c0f1a06f5733 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/AmbiguousWidgetMatcherException.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/AmbiguousWidgetMatcherException.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/InvalidFlutterViewException.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/InvalidFlutterViewException.java index 16c49220e0b9..d2d32869dd66 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/InvalidFlutterViewException.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/InvalidFlutterViewException.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/NoMatchingWidgetException.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/NoMatchingWidgetException.java index 55ce0f4e3935..756710f790c5 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/NoMatchingWidgetException.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/exception/NoMatchingWidgetException.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdException.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdException.java index 5be422184fe6..94c2d86db922 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdException.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdException.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdGenerator.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdGenerator.java index ee6d693d97ee..23d02373e856 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdGenerator.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdGenerator.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdGenerators.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdGenerators.java index 28d6816b7306..d14d8c50eaac 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdGenerators.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/idgenerator/IdGenerators.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/JsonRpcClient.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/JsonRpcClient.java index 7b5f8458a8f5..743c138fbf09 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/JsonRpcClient.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/JsonRpcClient.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/ErrorObject.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/ErrorObject.java index bf31679d7b3b..877dffbe9ade 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/ErrorObject.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/ErrorObject.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/JsonRpcRequest.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/JsonRpcRequest.java index 6eff736b5434..09bc7bbfe770 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/JsonRpcRequest.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/JsonRpcRequest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/JsonRpcResponse.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/JsonRpcResponse.java index 45b376a3f793..460aaa48a17c 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/JsonRpcResponse.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/jsonrpc/message/JsonRpcResponse.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/DartVmService.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/DartVmService.java index 7e3b277558c9..a1cdd977066c 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/DartVmService.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/DartVmService.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/DartVmServiceUtil.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/DartVmServiceUtil.java index 2534cc4d4736..63c62c4f5046 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/DartVmServiceUtil.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/DartVmServiceUtil.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/FlutterProtocolException.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/FlutterProtocolException.java index b2b182f10640..26865a31098f 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/FlutterProtocolException.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/FlutterProtocolException.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetOffsetAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetOffsetAction.java index 4dbf78836223..d668d4a303f7 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetOffsetAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetOffsetAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetOffsetResponse.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetOffsetResponse.java index 202f774f5d6b..a86cccbf1b6d 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetOffsetResponse.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetOffsetResponse.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetVmResponse.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetVmResponse.java index e3f97afb97fa..94cac364ddc7 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetVmResponse.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetVmResponse.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetWidgetDiagnosticsAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetWidgetDiagnosticsAction.java index 4753dd3dc451..6aa030a1d669 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetWidgetDiagnosticsAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetWidgetDiagnosticsAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetWidgetDiagnosticsResponse.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetWidgetDiagnosticsResponse.java index 6ee27de06705..b0c8b4246b8a 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetWidgetDiagnosticsResponse.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/GetWidgetDiagnosticsResponse.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoPendingFrameCondition.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoPendingFrameCondition.java index 64c37d31a782..2051f947f619 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoPendingFrameCondition.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoPendingFrameCondition.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoPendingPlatformMessagesCondition.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoPendingPlatformMessagesCondition.java index 7969ef851b3e..9145e5cd4aac 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoPendingPlatformMessagesCondition.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoPendingPlatformMessagesCondition.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoTransientCallbacksCondition.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoTransientCallbacksCondition.java index d4eb77810d0b..35aa5385fba9 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoTransientCallbacksCondition.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/NoTransientCallbacksCondition.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WaitCondition.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WaitCondition.java index 5baba66b89cb..868a877bbb1c 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WaitCondition.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WaitCondition.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WaitForConditionAction.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WaitForConditionAction.java index 2880130e8438..b8ca1846c8c3 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WaitForConditionAction.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WaitForConditionAction.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WidgetInfoFactory.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WidgetInfoFactory.java index 264f6cb77e5d..46269678b97b 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WidgetInfoFactory.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/internal/protocol/impl/WidgetInfoFactory.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/FlutterMatchers.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/FlutterMatchers.java index 634e2197ee94..9db88665f8e7 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/FlutterMatchers.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/FlutterMatchers.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/IsDescendantOfMatcher.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/IsDescendantOfMatcher.java index 947a0f79cad4..81c33d9b2fdb 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/IsDescendantOfMatcher.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/IsDescendantOfMatcher.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/IsExistingMatcher.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/IsExistingMatcher.java index 843d331d10a3..f077254be8f6 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/IsExistingMatcher.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/IsExistingMatcher.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTextMatcher.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTextMatcher.java index 711a835a45a5..99d630bbb1c4 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTextMatcher.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTextMatcher.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTooltipMatcher.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTooltipMatcher.java index fde9cd805ce8..78c14673a55d 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTooltipMatcher.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTooltipMatcher.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTypeMatcher.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTypeMatcher.java index b30fdf38674c..cea0572ed1b6 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTypeMatcher.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithTypeMatcher.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithValueKeyMatcher.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithValueKeyMatcher.java index 719f8adcab4d..fba9ec5dc5ac 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithValueKeyMatcher.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/matcher/WithValueKeyMatcher.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/model/WidgetInfo.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/model/WidgetInfo.java index 5b90a0002b53..9d8671fbcf2e 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/model/WidgetInfo.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/model/WidgetInfo.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/model/WidgetInfoBuilder.java b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/model/WidgetInfoBuilder.java index c119278af645..029111a6cb9b 100644 --- a/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/model/WidgetInfoBuilder.java +++ b/packages/espresso/android/src/main/java/androidx/test/espresso/flutter/model/WidgetInfoBuilder.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/android/src/main/java/com/example/espresso/EspressoPlugin.java b/packages/espresso/android/src/main/java/com/example/espresso/EspressoPlugin.java index 634b5fe53ad7..6c8620b3ca14 100644 --- a/packages/espresso/android/src/main/java/com/example/espresso/EspressoPlugin.java +++ b/packages/espresso/android/src/main/java/com/example/espresso/EspressoPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/example/android/app/src/androidTest/java/com/example/MainActivityTest.java b/packages/espresso/example/android/app/src/androidTest/java/com/example/MainActivityTest.java index 8a432809e9cb..739d49c1f9b0 100644 --- a/packages/espresso/example/android/app/src/androidTest/java/com/example/MainActivityTest.java +++ b/packages/espresso/example/android/app/src/androidTest/java/com/example/MainActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/example/android/app/src/main/java/com/example/espresso_example/MainActivity.java b/packages/espresso/example/android/app/src/main/java/com/example/espresso_example/MainActivity.java index ff62ed2521d5..7b2675e21399 100644 --- a/packages/espresso/example/android/app/src/main/java/com/example/espresso_example/MainActivity.java +++ b/packages/espresso/example/android/app/src/main/java/com/example/espresso_example/MainActivity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/example/lib/main.dart b/packages/espresso/example/lib/main.dart index 2ab6632113d5..de9387ee2fd9 100644 --- a/packages/espresso/example/lib/main.dart +++ b/packages/espresso/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/espresso/example/test_driver/example.dart b/packages/espresso/example/test_driver/example.dart index 42acdeb61a2c..630db5e25420 100644 --- a/packages/espresso/example/test_driver/example.dart +++ b/packages/espresso/example/test_driver/example.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector/LICENSE b/packages/file_selector/file_selector/LICENSE index 67c7e2c52e46..c6823b81eb84 100644 --- a/packages/file_selector/file_selector/LICENSE +++ b/packages/file_selector/file_selector/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/file_selector/file_selector/example/lib/get_directory_page.dart b/packages/file_selector/file_selector/example/lib/get_directory_page.dart index be278f374fa8..6022559ce40e 100644 --- a/packages/file_selector/file_selector/example/lib/get_directory_page.dart +++ b/packages/file_selector/file_selector/example/lib/get_directory_page.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector/example/lib/home_page.dart b/packages/file_selector/file_selector/example/lib/home_page.dart index 842094c9acaa..ab0b5c32187c 100644 --- a/packages/file_selector/file_selector/example/lib/home_page.dart +++ b/packages/file_selector/file_selector/example/lib/home_page.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector/example/lib/main.dart b/packages/file_selector/file_selector/example/lib/main.dart index e355109d1799..bd4c9b7ab853 100644 --- a/packages/file_selector/file_selector/example/lib/main.dart +++ b/packages/file_selector/file_selector/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector/example/lib/open_image_page.dart b/packages/file_selector/file_selector/example/lib/open_image_page.dart index da11ead1c09f..ae0d5ad4eefb 100644 --- a/packages/file_selector/file_selector/example/lib/open_image_page.dart +++ b/packages/file_selector/file_selector/example/lib/open_image_page.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart b/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart index d91d126c940f..5bf080eff450 100644 --- a/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart +++ b/packages/file_selector/file_selector/example/lib/open_multiple_images_page.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector/example/lib/open_text_page.dart b/packages/file_selector/file_selector/example/lib/open_text_page.dart index 52296abd4379..8451378f7baa 100644 --- a/packages/file_selector/file_selector/example/lib/open_text_page.dart +++ b/packages/file_selector/file_selector/example/lib/open_text_page.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector/example/lib/save_text_page.dart b/packages/file_selector/file_selector/example/lib/save_text_page.dart index 982692bc40f8..1610fc05164d 100644 --- a/packages/file_selector/file_selector/example/lib/save_text_page.dart +++ b/packages/file_selector/file_selector/example/lib/save_text_page.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector/example/web/index.html b/packages/file_selector/file_selector/example/web/index.html index 97b1100c4244..c6fa1623be95 100644 --- a/packages/file_selector/file_selector/example/web/index.html +++ b/packages/file_selector/file_selector/example/web/index.html @@ -1,5 +1,5 @@ - diff --git a/packages/file_selector/file_selector/lib/file_selector.dart b/packages/file_selector/file_selector/lib/file_selector.dart index cdb2bf9c726d..c2803d60c972 100644 --- a/packages/file_selector/file_selector/lib/file_selector.dart +++ b/packages/file_selector/file_selector/lib/file_selector.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector/test/file_selector_test.dart b/packages/file_selector/file_selector/test/file_selector_test.dart index b16f234bb3b8..6d5e215eeb01 100644 --- a/packages/file_selector/file_selector/test/file_selector_test.dart +++ b/packages/file_selector/file_selector/test/file_selector_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector_platform_interface/LICENSE b/packages/file_selector/file_selector_platform_interface/LICENSE index 67c7e2c52e46..c6823b81eb84 100644 --- a/packages/file_selector/file_selector_platform_interface/LICENSE +++ b/packages/file_selector/file_selector_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/file_selector/file_selector_platform_interface/lib/file_selector_platform_interface.dart b/packages/file_selector/file_selector_platform_interface/lib/file_selector_platform_interface.dart index dcd87aaed4a7..5e9a9fefa0bc 100644 --- a/packages/file_selector/file_selector_platform_interface/lib/file_selector_platform_interface.dart +++ b/packages/file_selector/file_selector_platform_interface/lib/file_selector_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector_platform_interface/lib/src/method_channel/method_channel_file_selector.dart b/packages/file_selector/file_selector_platform_interface/lib/src/method_channel/method_channel_file_selector.dart index e14239f51690..34017acc90e0 100644 --- a/packages/file_selector/file_selector_platform_interface/lib/src/method_channel/method_channel_file_selector.dart +++ b/packages/file_selector/file_selector_platform_interface/lib/src/method_channel/method_channel_file_selector.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector_platform_interface/lib/src/platform_interface/file_selector_interface.dart b/packages/file_selector/file_selector_platform_interface/lib/src/platform_interface/file_selector_interface.dart index 0be02c2185dd..54a6557c4428 100644 --- a/packages/file_selector/file_selector_platform_interface/lib/src/platform_interface/file_selector_interface.dart +++ b/packages/file_selector/file_selector_platform_interface/lib/src/platform_interface/file_selector_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector_platform_interface/lib/src/types/types.dart b/packages/file_selector/file_selector_platform_interface/lib/src/types/types.dart index 65a0bdcd1583..9caee27c3e35 100644 --- a/packages/file_selector/file_selector_platform_interface/lib/src/types/types.dart +++ b/packages/file_selector/file_selector_platform_interface/lib/src/types/types.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector_platform_interface/lib/src/types/x_type_group/x_type_group.dart b/packages/file_selector/file_selector_platform_interface/lib/src/types/x_type_group/x_type_group.dart index 7b3cb12be9f1..3e3326379610 100644 --- a/packages/file_selector/file_selector_platform_interface/lib/src/types/x_type_group/x_type_group.dart +++ b/packages/file_selector/file_selector_platform_interface/lib/src/types/x_type_group/x_type_group.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector_platform_interface/lib/src/web_helpers/web_helpers.dart b/packages/file_selector/file_selector_platform_interface/lib/src/web_helpers/web_helpers.dart index f9e33aed1389..0f157ed0be5a 100644 --- a/packages/file_selector/file_selector_platform_interface/lib/src/web_helpers/web_helpers.dart +++ b/packages/file_selector/file_selector_platform_interface/lib/src/web_helpers/web_helpers.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector_platform_interface/test/file_selector_platform_interface_test.dart b/packages/file_selector/file_selector_platform_interface/test/file_selector_platform_interface_test.dart index 56f6ae91bf28..f5b609c93ed3 100644 --- a/packages/file_selector/file_selector_platform_interface/test/file_selector_platform_interface_test.dart +++ b/packages/file_selector/file_selector_platform_interface/test/file_selector_platform_interface_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector_platform_interface/test/method_channel_file_selector_test.dart b/packages/file_selector/file_selector_platform_interface/test/method_channel_file_selector_test.dart index c863ad361112..96a3c2d4f4c9 100644 --- a/packages/file_selector/file_selector_platform_interface/test/method_channel_file_selector_test.dart +++ b/packages/file_selector/file_selector_platform_interface/test/method_channel_file_selector_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector_platform_interface/test/x_type_group_test.dart b/packages/file_selector/file_selector_platform_interface/test/x_type_group_test.dart index 21bbac5d0f90..e85a4929e411 100644 --- a/packages/file_selector/file_selector_platform_interface/test/x_type_group_test.dart +++ b/packages/file_selector/file_selector_platform_interface/test/x_type_group_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector_web/LICENSE b/packages/file_selector/file_selector_web/LICENSE index 67c7e2c52e46..c6823b81eb84 100644 --- a/packages/file_selector/file_selector_web/LICENSE +++ b/packages/file_selector/file_selector_web/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/file_selector/file_selector_web/example/integration_test/dom_helper_test.dart b/packages/file_selector/file_selector_web/example/integration_test/dom_helper_test.dart index 274aed93659e..f000574861ab 100644 --- a/packages/file_selector/file_selector_web/example/integration_test/dom_helper_test.dart +++ b/packages/file_selector/file_selector_web/example/integration_test/dom_helper_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector_web/example/integration_test/file_selector_web_test.dart b/packages/file_selector/file_selector_web/example/integration_test/file_selector_web_test.dart index ea9569bf00a9..c16aa1cf454e 100644 --- a/packages/file_selector/file_selector_web/example/integration_test/file_selector_web_test.dart +++ b/packages/file_selector/file_selector_web/example/integration_test/file_selector_web_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector_web/example/run_test.sh b/packages/file_selector/file_selector_web/example/run_test.sh index a381127c2716..0542b53cd6c9 100755 --- a/packages/file_selector/file_selector_web/example/run_test.sh +++ b/packages/file_selector/file_selector_web/example/run_test.sh @@ -1,5 +1,5 @@ #!/usr/bin/bash -# Copyright 2017 The Flutter Authors. All rights reserved. +# Copyright 2013 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. diff --git a/packages/file_selector/file_selector_web/example/test_driver/integration_test.dart b/packages/file_selector/file_selector_web/example/test_driver/integration_test.dart index 44d6ed9c64bc..4f10f2a522f3 100644 --- a/packages/file_selector/file_selector_web/example/test_driver/integration_test.dart +++ b/packages/file_selector/file_selector_web/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector_web/example/web/index.html b/packages/file_selector/file_selector_web/example/web/index.html index dc8d0cfe0428..dc9f89762aec 100644 --- a/packages/file_selector/file_selector_web/example/web/index.html +++ b/packages/file_selector/file_selector_web/example/web/index.html @@ -1,5 +1,5 @@ - diff --git a/packages/file_selector/file_selector_web/lib/file_selector_web.dart b/packages/file_selector/file_selector_web/lib/file_selector_web.dart index cf95e403effc..f7c10b36a186 100644 --- a/packages/file_selector/file_selector_web/lib/file_selector_web.dart +++ b/packages/file_selector/file_selector_web/lib/file_selector_web.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector_web/lib/src/dom_helper.dart b/packages/file_selector/file_selector_web/lib/src/dom_helper.dart index 5c578b6f4639..0d251af9cc7f 100644 --- a/packages/file_selector/file_selector_web/lib/src/dom_helper.dart +++ b/packages/file_selector/file_selector_web/lib/src/dom_helper.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector_web/lib/src/utils.dart b/packages/file_selector/file_selector_web/lib/src/utils.dart index 6be58c2aa0ec..e52c00d1c223 100644 --- a/packages/file_selector/file_selector_web/lib/src/utils.dart +++ b/packages/file_selector/file_selector_web/lib/src/utils.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector_web/test/more_tests_exist_elsewhere_test.dart b/packages/file_selector/file_selector_web/test/more_tests_exist_elsewhere_test.dart index 6aaf4475d537..37c6eb644c9b 100644 --- a/packages/file_selector/file_selector_web/test/more_tests_exist_elsewhere_test.dart +++ b/packages/file_selector/file_selector_web/test/more_tests_exist_elsewhere_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/file_selector/file_selector_web/test/utils_test.dart b/packages/file_selector/file_selector_web/test/utils_test.dart index e3e47c00f176..2951af24dff9 100644 --- a/packages/file_selector/file_selector_web/test/utils_test.dart +++ b/packages/file_selector/file_selector_web/test/utils_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/flutter_plugin_android_lifecycle/LICENSE b/packages/flutter_plugin_android_lifecycle/LICENSE index b257ce7c224c..c6823b81eb84 100644 --- a/packages/flutter_plugin_android_lifecycle/LICENSE +++ b/packages/flutter_plugin_android_lifecycle/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapter.java b/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapter.java index 3c91bb744d5c..05490eb93e46 100644 --- a/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapter.java +++ b/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapter.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle/FlutterAndroidLifecyclePlugin.java b/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle/FlutterAndroidLifecyclePlugin.java index fa90a210ffd2..e3b8ea2a6318 100644 --- a/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle/FlutterAndroidLifecyclePlugin.java +++ b/packages/flutter_plugin_android_lifecycle/android/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle/FlutterAndroidLifecyclePlugin.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. // diff --git a/packages/flutter_plugin_android_lifecycle/android/src/test/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapterTest.java b/packages/flutter_plugin_android_lifecycle/android/src/test/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapterTest.java index c184b1ad88db..08bb3d7266e8 100644 --- a/packages/flutter_plugin_android_lifecycle/android/src/test/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapterTest.java +++ b/packages/flutter_plugin_android_lifecycle/android/src/test/java/io/flutter/embedding/engine/plugins/lifecycle/FlutterLifecycleAdapterTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/EmbeddingV1ActivityTest.java b/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/EmbeddingV1ActivityTest.java index 89b9192c1676..84173f4a9c0f 100644 --- a/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/EmbeddingV1ActivityTest.java +++ b/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/MainActivityTest.java b/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/MainActivityTest.java index 22bc3fe68d46..66a606ca00a9 100644 --- a/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/MainActivityTest.java +++ b/packages/flutter_plugin_android_lifecycle/example/android/app/src/androidTest/java/io/flutter/plugins/flutter_plugin_android_lifecycle/MainActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/EmbeddingV1Activity.java b/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/EmbeddingV1Activity.java index 5859e177b2fc..e6ab004fccf6 100644 --- a/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/EmbeddingV1Activity.java +++ b/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/MainActivity.java b/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/MainActivity.java index a05da9ebb71a..1726aecbeddb 100644 --- a/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/MainActivity.java +++ b/packages/flutter_plugin_android_lifecycle/example/android/app/src/main/java/io/flutter/plugins/flutter_plugin_android_lifecycle_example/MainActivity.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. 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 8890f14925ab..b9861166147c 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 @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/flutter_plugin_android_lifecycle/example/lib/main.dart b/packages/flutter_plugin_android_lifecycle/example/lib/main.dart index d9ee842364a6..c019590b2a7c 100644 --- a/packages/flutter_plugin_android_lifecycle/example/lib/main.dart +++ b/packages/flutter_plugin_android_lifecycle/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/flutter_plugin_android_lifecycle/lib/flutter_plugin_android_lifecycle.dart b/packages/flutter_plugin_android_lifecycle/lib/flutter_plugin_android_lifecycle.dart index 38bb867225d1..340b06832f19 100644 --- a/packages/flutter_plugin_android_lifecycle/lib/flutter_plugin_android_lifecycle.dart +++ b/packages/flutter_plugin_android_lifecycle/lib/flutter_plugin_android_lifecycle.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/LICENSE b/packages/google_maps_flutter/google_maps_flutter/LICENSE index 050e2c7cac4f..c6823b81eb84 100644 --- a/packages/google_maps_flutter/google_maps_flutter/LICENSE +++ b/packages/google_maps_flutter/google_maps_flutter/LICENSE @@ -1,4 +1,4 @@ -Copyright 2018 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleBuilder.java index 230659d2bf71..b52017523e3c 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleBuilder.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleController.java index 27accafd9bd9..6ecc86220c0d 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleController.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleOptionsSink.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleOptionsSink.java index 51e6c2194ab7..719fc77660ae 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleOptionsSink.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CircleOptionsSink.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CirclesController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CirclesController.java index d9661e9e80f8..d128d9544b1f 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CirclesController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/CirclesController.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java index 30e7339f3de5..72c6959fe55e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java index 8d3414edfc4c..ad5179a69a45 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java index 92d0e044e577..05e016c32e27 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java index 96cfee088ad3..ca9ac184a76e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapListener.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapListener.java index c240f89deddb..0a5c3ec67e27 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapListener.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapListener.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java index 4ed31fabdab0..17f0d970a4ef 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java index 0a0a17a05f47..763cd9e3e72e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/LifecycleProvider.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/LifecycleProvider.java index 0e06321e7267..a3b6c0a3adf0 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/LifecycleProvider.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/LifecycleProvider.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerBuilder.java index 69637a12bff0..ecc5f01bc87c 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerBuilder.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerController.java index 667254ea9d7f..5c568a1c9a1e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerController.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerOptionsSink.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerOptionsSink.java index 25ed42927189..88c970c1f14b 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerOptionsSink.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkerOptionsSink.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkersController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkersController.java index 8a9897886f11..189cba03c1cd 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkersController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/MarkersController.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonBuilder.java index 149c1246f596..072fa746958f 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonBuilder.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonController.java index 3fe58f2fb900..e66f05e18f93 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonController.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonOptionsSink.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonOptionsSink.java index 6b4aea89efc1..e9b0ec1413a2 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonOptionsSink.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonOptionsSink.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonsController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonsController.java index 734525b2b0a3..6f855db07996 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonsController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolygonsController.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineBuilder.java index 2a8718710262..9120a1618237 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineBuilder.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineController.java index 172c807eb2a2..8bd84f5906f2 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineController.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineOptionsSink.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineOptionsSink.java index d05059860d68..5b3f193617cb 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineOptionsSink.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylineOptionsSink.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylinesController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylinesController.java index b6f3a90f4745..399634933dc9 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylinesController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/PolylinesController.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayBuilder.java index cbe6cfbd5e51..ecbc2f8f9ee1 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayBuilder.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayController.java index 9f07d7e6859f..7405b5fcc496 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlayController.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaySink.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaySink.java index b32ae8fb6f67..d167af7d4a6d 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaySink.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaySink.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java index f72dd7d6c1af..82a3edcb32c0 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileOverlaysController.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileProviderController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileProviderController.java index e760fafca8b7..f05d04550994 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileProviderController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/TileProviderController.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleBuilderTest.java b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleBuilderTest.java index 5b24902e17f1..269c35ebd864 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleBuilderTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleBuilderTest.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleControllerTest.java b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleControllerTest.java index 33765e71e7a1..72a8cab626b5 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/CircleControllerTest.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonBuilderTest.java b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonBuilderTest.java index 0d167a5dbe1e..c781afc0ede9 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonBuilderTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonBuilderTest.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonControllerTest.java b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonControllerTest.java index f4a0248240a4..29234b6adb42 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolygonControllerTest.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineBuilderTest.java b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineBuilderTest.java index bca2ebe5b8ce..9e2e9e81b829 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineBuilderTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineBuilderTest.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineControllerTest.java b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineControllerTest.java index 7cfa33acbd7c..bb7653aa2293 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/test/java/io/flutter/plugins/googlemaps/PolylineControllerTest.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/EmbeddingV1ActivityTest.java b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/EmbeddingV1ActivityTest.java index 5ade4367835a..9da7185b8ace 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/EmbeddingV1ActivityTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/MainActivityTest.java b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/MainActivityTest.java index 7c624bb556a9..fccd4c95c3ac 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/MainActivityTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/androidTest/java/io/flutter/plugins/googlemaps/MainActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/main/java/io/flutter/plugins/googlemapsexample/EmbeddingV1Activity.java b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/main/java/io/flutter/plugins/googlemapsexample/EmbeddingV1Activity.java index 9924fa03e3aa..cecf76a690e0 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/main/java/io/flutter/plugins/googlemapsexample/EmbeddingV1Activity.java +++ b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/main/java/io/flutter/plugins/googlemapsexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java index 7b81f287a9d1..2a81479988e0 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart index 02e1ac430e2e..fa19705d8287 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_map_inspector.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. // @dart=2.9 diff --git a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart index 0230a2157297..e50231293775 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. // @dart=2.9 diff --git a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/AppDelegate.h b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/AppDelegate.h index 8e973d51585b..9bc6c56e34f9 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/AppDelegate.h +++ b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/AppDelegate.m b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/AppDelegate.m index b22c283d4704..d050cf771c8f 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/AppDelegate.m +++ b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/main.m b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/main.m index f451b14cb751..f97b9ef5c8a1 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/main.m +++ b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/animate_camera.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/animate_camera.dart index 6581bc0af7b8..cc5fd257dfd3 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/animate_camera.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/animate_camera.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/lite_mode.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/lite_mode.dart index cb7fe0b861d8..f6d6f54e135a 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/lite_mode.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/lite_mode.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart index 9a6cf91a987d..15b14db0357a 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_click.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_click.dart index cea5c3ee3d35..a46fc5fba420 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_click.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_click.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_coordinates.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_coordinates.dart index 4819fcbd577b..99ab16802fea 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_coordinates.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_coordinates.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_ui.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_ui.dart index 703523efc2ec..2e0d2d188a3f 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_ui.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_ui.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/marker_icons.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/marker_icons.dart index d37fe5fb2203..da57b83a7e4f 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/marker_icons.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/marker_icons.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/move_camera.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/move_camera.dart index add70fbdd7a8..f8274196770d 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/move_camera.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/move_camera.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/padding.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/padding.dart index fa35ae0c90f3..d90005fa6998 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/padding.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/padding.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/page.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/page.dart index 536cbbc361d3..fb6eb3260f6d 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/page.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/page.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_circle.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_circle.dart index 9885747e7cba..a4953428f088 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_circle.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_circle.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart index 8ba85eff1b37..4e9f4c14ebd0 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_marker.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart index 192416a92e01..476084defa75 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polygon.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart index 7f24979b5ed1..aeb9bf1b11eb 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/scrolling_map.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/scrolling_map.dart index 684a66b993ef..9611d36bc8e8 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/scrolling_map.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/scrolling_map.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/snapshot.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/snapshot.dart index fadfc1775f31..c85048f5b5aa 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/snapshot.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/snapshot.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart index a8cb34133dcf..a367511cb72f 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/test_driver/integration_test.dart b/packages/google_maps_flutter/google_maps_flutter/example/test_driver/integration_test.dart index 80715b0ee874..ab30698581d0 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/test_driver/integration_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. // @dart=2.9 diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h index 5ef5eb86dfbb..356a13faba62 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m index 68884c650ecb..fb391380c92c 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.h index ca815956de9a..953c0557ff20 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.m index 2b345a1ddee2..7ce2cf1c204d 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.h index 2a8022a3ef2a..2e7a9967ebd3 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m index 25c0f37b427b..bdf36484aaf7 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.h index f261722cf7e1..a8cebb983347 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m index a823c4bbe660..bf47dfab12b7 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.h index 468c399e808f..d3e835435ed9 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m index a6d395b0c505..6a9fb885afac 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h index ad611a759548..b123ac0a3d68 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m index 445e4aebde1d..5ad8d4d3bc0e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.h index c0f46070c945..f7fafc2f065f 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m index 0d54cf13c458..8c70d2c161ba 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.h index a0e09f7b6fe2..6ede4dbaf8b4 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m index d2fd2c1c82eb..592d7e825b38 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart b/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart index 11f674b197a3..93bb0566dd1f 100644 --- a/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart +++ b/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart index 529950566ccc..ba18c5ffc17b 100644 --- a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart index 82549c3b491a..26b9d6b83c84 100644 --- a/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart +++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/test/android_google_map_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/android_google_map_test.dart index e6ac4331a935..8ee845469e25 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/android_google_map_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/android_google_map_test.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/test/circle_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/circle_updates_test.dart index d39173197d31..e0d1180a0abb 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/circle_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/circle_updates_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart b/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart index 5871745fc1da..37270ea34d29 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/test/google_map_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/google_map_test.dart index 0718d59a674b..2b754afbd359 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/google_map_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/google_map_test.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart index c90c47d0a038..6e0f5ed3e4f5 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/map_creation_test.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/test/marker_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/marker_updates_test.dart index ec3a89b72886..e295393fe15a 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/marker_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/marker_updates_test.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/test/polygon_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/polygon_updates_test.dart index f4df8ac137ad..79c63c1c5459 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/polygon_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/polygon_updates_test.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/test/polyline_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/polyline_updates_test.dart index c82693cad9c8..01eb2e2ce724 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/polyline_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/polyline_updates_test.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart index c7f5ef8e8286..35732da29726 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/tile_overlay_updates_test.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/LICENSE b/packages/google_maps_flutter/google_maps_flutter_platform_interface/LICENSE index 050e2c7cac4f..c6823b81eb84 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/LICENSE +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2018 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/google_maps_flutter_platform_interface.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/google_maps_flutter_platform_interface.dart index 3b01002e8d92..650a839cb676 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/google_maps_flutter_platform_interface.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/google_maps_flutter_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/events/map_event.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/events/map_event.dart index 9afc6db8cb94..be426483193d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/events/map_event.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/events/map_event.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart index dee04c92db14..80a71b4edd2b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart index c38a87f5a5c0..425e040ee812 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart index 0f2192fda1db..d3dc37e327fe 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/callbacks.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/callbacks.dart index 62b535bec08e..3b484c1feb05 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/callbacks.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/callbacks.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart index a4d762e87f48..7cb6369e7f59 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart index 9580a89189b8..f5f43209d828 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/cap.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart index 8d1d9ac7dbb6..1845195b31c6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle_updates.dart index b063a6bec0d6..f3fdbb447c94 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle_updates.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/circle_updates.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/joint_type.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/joint_type.dart index 5dc15b394fd8..64e7a3d8cbdc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/joint_type.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/joint_type.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/location.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/location.dart index cd9d0ee6993f..42c66e036fd7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/location.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/location.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart index d8cdfdce9f48..77d958be01e2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object_updates.dart index 0d94b77b48f4..2e2eefa3d32e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object_updates.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/maps_object_updates.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart index 014e5515e6cb..0d1b780c24d2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker_updates.dart index 8c0a1336ad32..27257c628033 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker_updates.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker_updates.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/pattern_item.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/pattern_item.dart index 89422a3423ec..89f29d25e4cc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/pattern_item.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/pattern_item.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart index 78e25c1f91cf..569bd4c1f553 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon_updates.dart index cb5b2a1faf6a..8b62141ce03c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon_updates.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polygon_updates.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart index f4d70dc1dcf8..c324aeb5f492 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline_updates.dart index 2fddcfe26619..30cd99f73229 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline_updates.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/polyline_updates.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/screen_coordinate.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/screen_coordinate.dart index efbd77942a46..8c9c083913ce 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/screen_coordinate.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/screen_coordinate.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile.dart index 4aa07669c2e7..d602b127f06c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart index d430623cdafe..55dca55f9d8e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay_updates.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay_updates.dart index 914aacdc8393..e40db7da10fe 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay_updates.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay_updates.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_provider.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_provider.dart index eb87bb6bb15d..dfe6937e24a4 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_provider.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_provider.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart index c49ad7c47171..5e2e4c234ccf 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/ui.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/ui.dart index 3490c121acbc..38c34fcfd27f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/ui.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/ui.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/circle.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/circle.dart index e0374269daea..bf1754fdf399 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/circle.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/circle.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/maps_object.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/maps_object.dart index 4418638353ce..da5a49825c7f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/maps_object.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/maps_object.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/marker.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/marker.dart index 1c112a68ceb9..4be3f2a2f9a4 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/marker.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polygon.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polygon.dart index 53e946e11943..ba4ce7d6f55f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polygon.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polyline.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polyline.dart index 0b163f7b84ee..8c188b021b2f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/polyline.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/tile_overlay.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/tile_overlay.dart index 9f8c51906abd..fae61a4b4433 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/tile_overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/utils/tile_overlay.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart index be20335e834b..73cea10ec2d9 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/bitmap_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/bitmap_test.dart index 81ca300a6955..6d02b2c630df 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/bitmap_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/bitmap_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart index aa48b7b74760..11665d904556 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart index 4f9fc7cca2dd..c2ca2bdda5b7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart index 252303076a04..f09f70fd769e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/maps_object_updates_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart index 077f823a1e05..b95ae50a8f08 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/test_maps_object.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart index ddcb693cc217..a17f86d4f19a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart index f2054c676d41..05be14e1ba0b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_updates_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart index f7f0c285168a..653958474185 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/LICENSE b/packages/google_maps_flutter/google_maps_flutter_web/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/LICENSE +++ b/packages/google_maps_flutter/google_maps_flutter_web/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index 11d054a64c42..fd4df2ee4fd8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart index b33d8ae69205..dee37618c940 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart index a8858bedcdab..1a85f3bb28e1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart index e8526d9f314a..e9e458c85685 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/resources/icon_image_base64.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/resources/icon_image_base64.dart index 66814d8df7ca..6010f0107031 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/resources/icon_image_base64.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/resources/icon_image_base64.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart index 91ad7dfac90f..0c351971af7c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart index 3735bd06a5c8..9bb3599311d2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh b/packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh index 9bfce94f63b2..dbf0ec55fd8f 100755 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh @@ -1,5 +1,5 @@ #!/usr/bin/bash -# Copyright 2017 The Flutter Authors. All rights reserved. +# Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/test_driver/integration_driver.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/test_driver/integration_driver.dart index dba91905cd68..f26b6a310cfe 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/test_driver/integration_driver.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/test_driver/integration_driver.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html index 03feba172d74..d48ebfe62c37 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html @@ -1,5 +1,5 @@ - diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart index df2d04853c8a..0aa563ccb889 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart index ea24d4d6ab15..84bae1b98e2e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart index 6463c9e11ba1..659d8ac823a6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index ca15df56cbd0..c875bf782474 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index 7ccce3bde370..cc8d79a6226d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart index 92ee16ad3d49..5e95a538c07a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart index c0efc6b5bdda..62238fc2d86b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart index a3128043d575..bc9827a20270 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart index 3cb5638846df..4ce1f022e586 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart index bb232d0d94a7..4671e6d77a87 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart index cf9de5b36d33..bf1dbb222555 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart index 9fbcf119100e..e91b82fd1947 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui.dart index ec93f431138b..5eacec5fe867 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_fake.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_fake.dart index 2a8c7f5f5c6e..f2862af8b704 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_fake.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_fake.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_real.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_real.dart index b6c2f8812a1b..276b768c76c5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_real.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_real.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart index 0393cb205200..10b5199a894e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/test/tests_exist_elsewhere_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/test/tests_exist_elsewhere_test.dart index ab69a33ba215..442c50144727 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/test/tests_exist_elsewhere_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/test/tests_exist_elsewhere_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/LICENSE b/packages/google_sign_in/google_sign_in/LICENSE index 1d7bbaf70add..c6823b81eb84 100644 --- a/packages/google_sign_in/google_sign_in/LICENSE +++ b/packages/google_sign_in/google_sign_in/LICENSE @@ -1,4 +1,4 @@ -Copyright 2016 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/BackgroundTaskRunner.java b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/BackgroundTaskRunner.java index 95bc0153e41a..b13ec7e3412a 100755 --- a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/BackgroundTaskRunner.java +++ b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/BackgroundTaskRunner.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/Executors.java b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/Executors.java index 008a33c30052..824c6da8ec9f 100755 --- a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/Executors.java +++ b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/Executors.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java index 351ed731cccd..3a63f785aa9f 100755 --- a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java +++ b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInWrapper.java b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInWrapper.java index 3c84968f986c..5af0b50136ce 100644 --- a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInWrapper.java +++ b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInWrapper.java @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1Activity.java b/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1Activity.java index 215136625dc2..f61bb72ba9da 100644 --- a/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1Activity.java +++ b/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java b/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java index 893a13d2379b..cfd2fcec9ec3 100644 --- a/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java +++ b/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java b/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java index 6ab856eca8bd..36787ffd9910 100644 --- a/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java +++ b/packages/google_sign_in/google_sign_in/example/android/app/src/main/java/io/flutter/plugins/googlesigninexample/FlutterActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/example/android/app/src/test/java/io/flutter/plugins/googlesignin/GoogleSignInPluginTests.java b/packages/google_sign_in/google_sign_in/example/android/app/src/test/java/io/flutter/plugins/googlesignin/GoogleSignInPluginTests.java index b2a13a712823..f1058760e2de 100644 --- a/packages/google_sign_in/google_sign_in/example/android/app/src/test/java/io/flutter/plugins/googlesignin/GoogleSignInPluginTests.java +++ b/packages/google_sign_in/google_sign_in/example/android/app/src/test/java/io/flutter/plugins/googlesignin/GoogleSignInPluginTests.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/example/ios/Runner/AppDelegate.h b/packages/google_sign_in/google_sign_in/example/ios/Runner/AppDelegate.h index 31fc381e7066..0681d288bb70 100644 --- a/packages/google_sign_in/google_sign_in/example/ios/Runner/AppDelegate.h +++ b/packages/google_sign_in/google_sign_in/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/example/ios/Runner/AppDelegate.m b/packages/google_sign_in/google_sign_in/example/ios/Runner/AppDelegate.m index 2147d3d605ac..30b87969f44a 100644 --- a/packages/google_sign_in/google_sign_in/example/ios/Runner/AppDelegate.m +++ b/packages/google_sign_in/google_sign_in/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/example/ios/Runner/main.m b/packages/google_sign_in/google_sign_in/example/ios/Runner/main.m index f451b14cb751..f97b9ef5c8a1 100644 --- a/packages/google_sign_in/google_sign_in/example/ios/Runner/main.m +++ b/packages/google_sign_in/google_sign_in/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/example/lib/main.dart b/packages/google_sign_in/google_sign_in/example/lib/main.dart index c87063297373..c677d4e75bc3 100755 --- a/packages/google_sign_in/google_sign_in/example/lib/main.dart +++ b/packages/google_sign_in/google_sign_in/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/example/web/index.html b/packages/google_sign_in/google_sign_in/example/web/index.html index 187eeb5ff8ff..5710c936c2ed 100644 --- a/packages/google_sign_in/google_sign_in/example/web/index.html +++ b/packages/google_sign_in/google_sign_in/example/web/index.html @@ -1,5 +1,5 @@ - diff --git a/packages/google_sign_in/google_sign_in/integration_test/google_sign_in_test.dart b/packages/google_sign_in/google_sign_in/integration_test/google_sign_in_test.dart index d3896b57174c..7a1522346e37 100644 --- a/packages/google_sign_in/google_sign_in/integration_test/google_sign_in_test.dart +++ b/packages/google_sign_in/google_sign_in/integration_test/google_sign_in_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.h b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.h index 6447e9243483..cb6b51aab1bf 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.h +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m index 23584fd36922..757578bb3a50 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/ios/Tests/GoogleSignInPluginTest.m b/packages/google_sign_in/google_sign_in/ios/Tests/GoogleSignInPluginTest.m index d00ef82237c0..adbf61326c8d 100644 --- a/packages/google_sign_in/google_sign_in/ios/Tests/GoogleSignInPluginTest.m +++ b/packages/google_sign_in/google_sign_in/ios/Tests/GoogleSignInPluginTest.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart b/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart index 2e094a8b1575..6584156cc070 100644 --- a/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart +++ b/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/lib/src/common.dart b/packages/google_sign_in/google_sign_in/lib/src/common.dart index e341a27a740d..068403e74629 100644 --- a/packages/google_sign_in/google_sign_in/lib/src/common.dart +++ b/packages/google_sign_in/google_sign_in/lib/src/common.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/lib/src/fife.dart b/packages/google_sign_in/google_sign_in/lib/src/fife.dart index 14ecf5fd6083..ff048e249590 100644 --- a/packages/google_sign_in/google_sign_in/lib/src/fife.dart +++ b/packages/google_sign_in/google_sign_in/lib/src/fife.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/lib/testing.dart b/packages/google_sign_in/google_sign_in/lib/testing.dart index ed0ca4f2de7c..c4d2da3089a5 100644 --- a/packages/google_sign_in/google_sign_in/lib/testing.dart +++ b/packages/google_sign_in/google_sign_in/lib/testing.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/lib/widgets.dart b/packages/google_sign_in/google_sign_in/lib/widgets.dart index c3537ab90394..18f9973454f6 100644 --- a/packages/google_sign_in/google_sign_in/lib/widgets.dart +++ b/packages/google_sign_in/google_sign_in/lib/widgets.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/test/fife_test.dart b/packages/google_sign_in/google_sign_in/test/fife_test.dart index bfc4937a7c64..c81454ef0a8c 100644 --- a/packages/google_sign_in/google_sign_in/test/fife_test.dart +++ b/packages/google_sign_in/google_sign_in/test/fife_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart index 4eb45a5dc38e..f642bcd2eaf8 100755 --- a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart +++ b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in/test_driver/integration_test.dart b/packages/google_sign_in/google_sign_in/test_driver/integration_test.dart index c85665696a0f..257b0d3c0930 100644 --- a/packages/google_sign_in/google_sign_in/test_driver/integration_test.dart +++ b/packages/google_sign_in/google_sign_in/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_platform_interface/LICENSE b/packages/google_sign_in/google_sign_in_platform_interface/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/LICENSE +++ b/packages/google_sign_in/google_sign_in_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart b/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart index 560b72088978..42038879e90b 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart index b2718d0f08b0..23c35ac240b9 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/types.dart b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/types.dart index e20d44fae473..61231d1b70b9 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/types.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/types.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/utils.dart b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/utils.dart index 14701897933a..4a70ec4d25ef 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/utils.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/utils.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_platform_interface/test/google_sign_in_platform_interface_test.dart b/packages/google_sign_in/google_sign_in_platform_interface/test/google_sign_in_platform_interface_test.dart index e49f6a1074e2..b3ac51b7fa52 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/test/google_sign_in_platform_interface_test.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/test/google_sign_in_platform_interface_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart b/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart index dbc5bb00f17f..390c12583a79 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_web/LICENSE b/packages/google_sign_in/google_sign_in_web/LICENSE index 1d7bbaf70add..c6823b81eb84 100644 --- a/packages/google_sign_in/google_sign_in_web/LICENSE +++ b/packages/google_sign_in/google_sign_in_web/LICENSE @@ -1,4 +1,4 @@ -Copyright 2016 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/auth2_test.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/auth2_test.dart index 0df203f2f4d8..e1a97cee6cf7 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/auth2_test.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/auth2_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_load_test.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_load_test.dart index 0e0363bdd760..5da42283367f 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_load_test.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_load_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/gapi_mocks.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/gapi_mocks.dart index eb77900d27b6..43eb9a55d06b 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/gapi_mocks.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/gapi_mocks.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/auth2_init.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/auth2_init.dart index acda5d525a91..2a085ccf3588 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/auth2_init.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/auth2_init.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/gapi.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/gapi.dart index 587920494692..0e652c647a38 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/gapi.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/gapi.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/google_user.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/google_user.dart index 98e978641d3d..e5e6eb262502 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/google_user.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/google_user.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/test_iife.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/test_iife.dart index 277dfa39104a..c5aac367c1de 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/test_iife.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_mocks/src/test_iife.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_utils_test.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_utils_test.dart index 2b439c9c74fb..1447093d4115 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_utils_test.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/gapi_utils_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/integration_test/src/test_utils.dart b/packages/google_sign_in/google_sign_in_web/example/integration_test/src/test_utils.dart index f01c801dcb14..89f9b55f3ddf 100644 --- a/packages/google_sign_in/google_sign_in_web/example/integration_test/src/test_utils.dart +++ b/packages/google_sign_in/google_sign_in_web/example/integration_test/src/test_utils.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/run_test.sh b/packages/google_sign_in/google_sign_in_web/example/run_test.sh index d6b5dbb18ae9..fe30bc8652d0 100755 --- a/packages/google_sign_in/google_sign_in_web/example/run_test.sh +++ b/packages/google_sign_in/google_sign_in_web/example/run_test.sh @@ -1,5 +1,5 @@ #!/usr/bin/bash -# Copyright 2017 The Flutter Authors. All rights reserved. +# Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/test_driver/integration_driver.dart b/packages/google_sign_in/google_sign_in_web/example/test_driver/integration_driver.dart index dba91905cd68..f26b6a310cfe 100644 --- a/packages/google_sign_in/google_sign_in_web/example/test_driver/integration_driver.dart +++ b/packages/google_sign_in/google_sign_in_web/example/test_driver/integration_driver.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_web/example/web/index.html b/packages/google_sign_in/google_sign_in_web/example/web/index.html index 59a832b5de4c..9e1284771b82 100644 --- a/packages/google_sign_in/google_sign_in_web/example/web/index.html +++ b/packages/google_sign_in/google_sign_in_web/example/web/index.html @@ -1,5 +1,5 @@ - diff --git a/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart b/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart index 320dad4ea220..f40b42b1881e 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart index d2c00a840597..a7ee1cdd3314 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart index b42486b9fd7f..0dec17dbd19c 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/load_gapi.dart b/packages/google_sign_in/google_sign_in_web/lib/src/load_gapi.dart index 5aad2d9c52ba..6d8c566f0412 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/load_gapi.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/load_gapi.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/utils.dart b/packages/google_sign_in/google_sign_in_web/lib/src/utils.dart index 12cdd0a3162b..bcfefc2054b4 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/utils.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/utils.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/google_sign_in/google_sign_in_web/test/tests_exist_elsewhere_test.dart b/packages/google_sign_in/google_sign_in_web/test/tests_exist_elsewhere_test.dart index 64d8e547e485..442c50144727 100644 --- a/packages/google_sign_in/google_sign_in_web/test/tests_exist_elsewhere_test.dart +++ b/packages/google_sign_in/google_sign_in_web/test/tests_exist_elsewhere_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/LICENSE b/packages/image_picker/image_picker/LICENSE index 7cd0a6f3b98f..0be8bbc3e68d 100644 --- a/packages/image_picker/image_picker/LICENSE +++ b/packages/image_picker/image_picker/LICENSE @@ -1,6 +1,6 @@ image_picker -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ExifDataCopier.java b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ExifDataCopier.java index 08b010072585..eada546f029a 100644 --- a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ExifDataCopier.java +++ b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ExifDataCopier.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/FileUtils.java b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/FileUtils.java index 19e304ea9eee..1f51a226c7e2 100644 --- a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/FileUtils.java +++ b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/FileUtils.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerCache.java b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerCache.java index 45ba6de0ee6b..3df0a4108b5c 100644 --- a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerCache.java +++ b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerCache.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java index ff7f1534a586..29d7c8529a99 100644 --- a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java +++ b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerFileProvider.java b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerFileProvider.java index ca7f6b064b39..7416665c49c1 100644 --- a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerFileProvider.java +++ b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerFileProvider.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java index 74556f9cd6cc..98b64101bed7 100644 --- a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java +++ b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerUtils.java b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerUtils.java index 65b05e7ac3cc..ba9878925575 100644 --- a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerUtils.java +++ b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerUtils.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImageResizer.java b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImageResizer.java index 27a145567a31..2a93785678af 100644 --- a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImageResizer.java +++ b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImageResizer.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1Activity.java b/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1Activity.java index 215fcfdb9212..b9d2808a4486 100644 --- a/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1Activity.java +++ b/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1ActivityTest.java b/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1ActivityTest.java index 34a827eed3ae..7d790563abae 100644 --- a/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1ActivityTest.java +++ b/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/FlutterActivityTest.java b/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/FlutterActivityTest.java index cfe112e39cb2..1ca37ce5feb7 100644 --- a/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/FlutterActivityTest.java +++ b/packages/image_picker/image_picker/example/android/app/src/main/java/io/flutter/plugins/imagepickerexample/FlutterActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/FileUtilTest.java b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/FileUtilTest.java index bd705d2374e5..32e3ebc6183d 100644 --- a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/FileUtilTest.java +++ b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/FileUtilTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerCacheTest.java b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerCacheTest.java index 51733a503a92..92070e7a65c5 100644 --- a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerCacheTest.java +++ b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerCacheTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java index 858d929dbc5d..a6858f2bd3b0 100644 --- a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java +++ b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerPluginTest.java b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerPluginTest.java index 27bc57bd2dcd..2e50a220c752 100644 --- a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerPluginTest.java +++ b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerPluginTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImageResizerTest.java b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImageResizerTest.java index 4968d844f824..73cfef9e88ea 100644 --- a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImageResizerTest.java +++ b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImageResizerTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/example/ios/Runner/AppDelegate.h b/packages/image_picker/image_picker/example/ios/Runner/AppDelegate.h index 31fc381e7066..0681d288bb70 100644 --- a/packages/image_picker/image_picker/example/ios/Runner/AppDelegate.h +++ b/packages/image_picker/image_picker/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/example/ios/Runner/AppDelegate.m b/packages/image_picker/image_picker/example/ios/Runner/AppDelegate.m index abfe2106b092..b790a0a52635 100644 --- a/packages/image_picker/image_picker/example/ios/Runner/AppDelegate.m +++ b/packages/image_picker/image_picker/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/example/ios/Runner/main.m b/packages/image_picker/image_picker/example/ios/Runner/main.m index f451b14cb751..f97b9ef5c8a1 100644 --- a/packages/image_picker/image_picker/example/ios/Runner/main.m +++ b/packages/image_picker/image_picker/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m b/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m index 68ca6304e17e..a3ca1a1f8892 100644 --- a/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m +++ b/packages/image_picker/image_picker/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/example/lib/main.dart b/packages/image_picker/image_picker/example/lib/main.dart index 54e3a1ae4cd2..ff9f4a03cebc 100755 --- a/packages/image_picker/image_picker/example/lib/main.dart +++ b/packages/image_picker/image_picker/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/example/test_driver/test/integration_test.dart b/packages/image_picker/image_picker/example/test_driver/test/integration_test.dart index b02d7d397106..4c4c006068b8 100644 --- a/packages/image_picker/image_picker/example/test_driver/test/integration_test.dart +++ b/packages/image_picker/image_picker/example/test_driver/test/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/example/web/index.html b/packages/image_picker/image_picker/example/web/index.html index a692cdb87e02..b05fdf840323 100644 --- a/packages/image_picker/image_picker/example/web/index.html +++ b/packages/image_picker/image_picker/example/web/index.html @@ -1,5 +1,5 @@ - diff --git a/packages/image_picker/image_picker/integration_test/old_image_picker_test.dart b/packages/image_picker/image_picker/integration_test/old_image_picker_test.dart index 953acd1a8da3..528c8b9f127a 100644 --- a/packages/image_picker/image_picker/integration_test/old_image_picker_test.dart +++ b/packages/image_picker/image_picker/integration_test/old_image_picker_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerImageUtil.h b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerImageUtil.h index e809744f76d9..02b58d38a12e 100644 --- a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerImageUtil.h +++ b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerImageUtil.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerImageUtil.m b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerImageUtil.m index ab765208d0bc..2f6ead7317b9 100644 --- a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerImageUtil.m +++ b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerImageUtil.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.h b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.h index 9f7c19aae1b4..d5a20ffc6d2e 100644 --- a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.h +++ b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.m b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.m index 9786f61e1e67..1419584a4675 100644 --- a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.m +++ b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.h b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.h index 1e6fda2cf786..ce37ff715caf 100644 --- a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.h +++ b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.m b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.m index f6727334060a..caadc8ba4864 100644 --- a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.m +++ b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPlugin.h b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPlugin.h index b6d8687a32e3..3b3551d53461 100644 --- a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPlugin.h +++ b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPlugin.m b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPlugin.m index 8d260f31b055..9159ea4c990b 100644 --- a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPlugin.m +++ b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/ios/Tests/ImagePickerPluginTests.m b/packages/image_picker/image_picker/ios/Tests/ImagePickerPluginTests.m index f34fa7049616..04ba4b98e241 100644 --- a/packages/image_picker/image_picker/ios/Tests/ImagePickerPluginTests.m +++ b/packages/image_picker/image_picker/ios/Tests/ImagePickerPluginTests.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/ios/Tests/ImagePickerTestImages.h b/packages/image_picker/image_picker/ios/Tests/ImagePickerTestImages.h index 8ba64a4d03b6..1074a5c62455 100644 --- a/packages/image_picker/image_picker/ios/Tests/ImagePickerTestImages.h +++ b/packages/image_picker/image_picker/ios/Tests/ImagePickerTestImages.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/ios/Tests/ImagePickerTestImages.m b/packages/image_picker/image_picker/ios/Tests/ImagePickerTestImages.m index 536e3b3cba8e..a0bae7b8f91c 100644 --- a/packages/image_picker/image_picker/ios/Tests/ImagePickerTestImages.m +++ b/packages/image_picker/image_picker/ios/Tests/ImagePickerTestImages.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/ios/Tests/ImageUtilTests.m b/packages/image_picker/image_picker/ios/Tests/ImageUtilTests.m index 87c8249e78a4..958c99f9c651 100644 --- a/packages/image_picker/image_picker/ios/Tests/ImageUtilTests.m +++ b/packages/image_picker/image_picker/ios/Tests/ImageUtilTests.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/ios/Tests/MetaDataUtilTests.m b/packages/image_picker/image_picker/ios/Tests/MetaDataUtilTests.m index 505ccbfecab8..e1dbfad77b5d 100644 --- a/packages/image_picker/image_picker/ios/Tests/MetaDataUtilTests.m +++ b/packages/image_picker/image_picker/ios/Tests/MetaDataUtilTests.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/ios/Tests/PhotoAssetUtilTests.m b/packages/image_picker/image_picker/ios/Tests/PhotoAssetUtilTests.m index ac408b22c387..2a1ba75b0608 100644 --- a/packages/image_picker/image_picker/ios/Tests/PhotoAssetUtilTests.m +++ b/packages/image_picker/image_picker/ios/Tests/PhotoAssetUtilTests.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/lib/image_picker.dart b/packages/image_picker/image_picker/lib/image_picker.dart index 22315100c961..77c26d40346a 100755 --- a/packages/image_picker/image_picker/lib/image_picker.dart +++ b/packages/image_picker/image_picker/lib/image_picker.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker/test/image_picker_test.dart b/packages/image_picker/image_picker/test/image_picker_test.dart index 0508d257016d..f56d47ff262b 100644 --- a/packages/image_picker/image_picker/test/image_picker_test.dart +++ b/packages/image_picker/image_picker/test/image_picker_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker_for_web/LICENSE b/packages/image_picker/image_picker_for_web/LICENSE index b257ce7c224c..c6823b81eb84 100644 --- a/packages/image_picker/image_picker_for_web/LICENSE +++ b/packages/image_picker/image_picker_for_web/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index 75e185470d60..2fb66380e1d8 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker_for_web/test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/test/image_picker_for_web_test.dart index aa97170bf800..fbdd1d38bee6 100644 --- a/packages/image_picker/image_picker_for_web/test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/test/image_picker_for_web_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker_platform_interface/LICENSE b/packages/image_picker/image_picker_platform_interface/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/image_picker/image_picker_platform_interface/LICENSE +++ b/packages/image_picker/image_picker_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/image_picker/image_picker_platform_interface/lib/image_picker_platform_interface.dart b/packages/image_picker/image_picker_platform_interface/lib/image_picker_platform_interface.dart index e04027cbd744..b384e3845c4b 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/image_picker_platform_interface.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/image_picker_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/method_channel/method_channel_image_picker.dart b/packages/image_picker/image_picker_platform_interface/lib/src/method_channel/method_channel_image_picker.dart index 272a018a3e35..429c51bc8923 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/method_channel/method_channel_image_picker.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/method_channel/method_channel_image_picker.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/platform_interface/image_picker_platform.dart b/packages/image_picker/image_picker_platform_interface/lib/src/platform_interface/image_picker_platform.dart index 66986d35719f..3bbf4221ff50 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/platform_interface/image_picker_platform.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/platform_interface/image_picker_platform.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/camera_device.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/camera_device.dart index 658adc5f2c7f..45dfe3ac96aa 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/camera_device.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/camera_device.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/image_source.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/image_source.dart index 6676a9dab30b..ed907dc54c48 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/image_source.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/image_source.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart index a6cbeeed5c97..de259e0611dd 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/base.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart index 8e757774042b..24e1931008b6 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/html.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart index 08c172a98a05..7037b6b7121a 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/io.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/lost_data.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/lost_data.dart index 3bd9a696d035..64f6a1f27538 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/lost_data.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/lost_data.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/picked_file.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/picked_file.dart index 34fa2f624f0d..c8c9e5a0ac79 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/picked_file.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/picked_file.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/unsupported.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/unsupported.dart index 25a0a73d49a9..ad3ed6a4f86a 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/unsupported.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/picked_file/unsupported.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/retrieve_type.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/retrieve_type.dart index 3090513b5b8d..445445e5d7fb 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/retrieve_type.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/retrieve_type.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart b/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart index c07ac524335e..10e7745f2741 100644 --- a/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart +++ b/packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker_platform_interface/test/new_method_channel_image_picker_test.dart b/packages/image_picker/image_picker_platform_interface/test/new_method_channel_image_picker_test.dart index df35f8fd96b8..26217334aeb3 100644 --- a/packages/image_picker/image_picker_platform_interface/test/new_method_channel_image_picker_test.dart +++ b/packages/image_picker/image_picker_platform_interface/test/new_method_channel_image_picker_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker_platform_interface/test/picked_file_html_test.dart b/packages/image_picker/image_picker_platform_interface/test/picked_file_html_test.dart index 00d6e99ec0bf..7721f66148e0 100644 --- a/packages/image_picker/image_picker_platform_interface/test/picked_file_html_test.dart +++ b/packages/image_picker/image_picker_platform_interface/test/picked_file_html_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/image_picker/image_picker_platform_interface/test/picked_file_io_test.dart b/packages/image_picker/image_picker_platform_interface/test/picked_file_io_test.dart index c721326e17a4..d366204c36bf 100644 --- a/packages/image_picker/image_picker_platform_interface/test/picked_file_io_test.dart +++ b/packages/image_picker/image_picker_platform_interface/test/picked_file_io_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/LICENSE b/packages/in_app_purchase/LICENSE index 050e2c7cac4f..c6823b81eb84 100644 --- a/packages/in_app_purchase/LICENSE +++ b/packages/in_app_purchase/LICENSE @@ -1,4 +1,4 @@ -Copyright 2018 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactory.java b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactory.java index 915a18eee7ac..7b21cbf2e6f5 100644 --- a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactory.java +++ b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactory.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactoryImpl.java b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactoryImpl.java index 38e59321ce8a..c256d2c59551 100644 --- a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactoryImpl.java +++ b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactoryImpl.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/InAppPurchasePlugin.java b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/InAppPurchasePlugin.java index f412b517cf1c..e4719f030d53 100644 --- a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/InAppPurchasePlugin.java +++ b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/InAppPurchasePlugin.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java index 1663c39cfa0f..cfcb81ae05b5 100644 --- a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java +++ b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/PluginPurchaseListener.java b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/PluginPurchaseListener.java index 04f980429eaf..54c775d0ad0f 100644 --- a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/PluginPurchaseListener.java +++ b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/PluginPurchaseListener.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java index c7e7e9029ebd..37e30cbfed06 100644 --- a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java +++ b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1Activity.java b/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1Activity.java index dd4ad6db07a7..c74ad9447e81 100644 --- a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1Activity.java +++ b/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1ActivityTest.java b/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1ActivityTest.java index 165bc4b42c67..55d97a658ec0 100644 --- a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1ActivityTest.java +++ b/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/FlutterActivityTest.java b/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/FlutterActivityTest.java index eaacdf16282d..a60599573d57 100644 --- a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/FlutterActivityTest.java +++ b/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/FlutterActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java index 248e4105b200..bcee5428eac9 100644 --- a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java +++ b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java index 374dc3297e9e..4d7a02220cf5 100644 --- a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java +++ b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java index 63f670dc26e1..47147e772bce 100644 --- a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java +++ b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/example/ios/Runner/AppDelegate.h b/packages/in_app_purchase/example/ios/Runner/AppDelegate.h index 31fc381e7066..0681d288bb70 100644 --- a/packages/in_app_purchase/example/ios/Runner/AppDelegate.h +++ b/packages/in_app_purchase/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/example/ios/Runner/AppDelegate.m b/packages/in_app_purchase/example/ios/Runner/AppDelegate.m index 2147d3d605ac..30b87969f44a 100644 --- a/packages/in_app_purchase/example/ios/Runner/AppDelegate.m +++ b/packages/in_app_purchase/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/example/ios/Runner/main.m b/packages/in_app_purchase/example/ios/Runner/main.m index f451b14cb751..f97b9ef5c8a1 100644 --- a/packages/in_app_purchase/example/ios/Runner/main.m +++ b/packages/in_app_purchase/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/example/lib/consumable_store.dart b/packages/in_app_purchase/example/lib/consumable_store.dart index 271291ca6eee..4d10a50e1ee8 100644 --- a/packages/in_app_purchase/example/lib/consumable_store.dart +++ b/packages/in_app_purchase/example/lib/consumable_store.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/example/lib/main.dart b/packages/in_app_purchase/example/lib/main.dart index 2172ca3480f5..58cca9162b17 100644 --- a/packages/in_app_purchase/example/lib/main.dart +++ b/packages/in_app_purchase/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/example/test_driver/test/integration_test.dart b/packages/in_app_purchase/example/test_driver/test/integration_test.dart index b02d7d397106..4c4c006068b8 100644 --- a/packages/in_app_purchase/example/test_driver/test/integration_test.dart +++ b/packages/in_app_purchase/example/test_driver/test/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/integration_test/in_app_purchase_test.dart b/packages/in_app_purchase/integration_test/in_app_purchase_test.dart index f7edfb71412c..ca1eea640655 100644 --- a/packages/in_app_purchase/integration_test/in_app_purchase_test.dart +++ b/packages/in_app_purchase/integration_test/in_app_purchase_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/ios/Classes/FIAObjectTranslator.h b/packages/in_app_purchase/ios/Classes/FIAObjectTranslator.h index 383e5440509a..2d0187e88aed 100644 --- a/packages/in_app_purchase/ios/Classes/FIAObjectTranslator.h +++ b/packages/in_app_purchase/ios/Classes/FIAObjectTranslator.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/ios/Classes/FIAObjectTranslator.m b/packages/in_app_purchase/ios/Classes/FIAObjectTranslator.m index e54504a67218..5d6e0a244a96 100644 --- a/packages/in_app_purchase/ios/Classes/FIAObjectTranslator.m +++ b/packages/in_app_purchase/ios/Classes/FIAObjectTranslator.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.h b/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.h index 797e4a6f4216..94020ff2348b 100644 --- a/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.h +++ b/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.m b/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.m index deeed2873b30..526364020ad3 100644 --- a/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.m +++ b/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/ios/Classes/FIAPRequestHandler.h b/packages/in_app_purchase/ios/Classes/FIAPRequestHandler.h index 6c75a9fcdf44..cbf21d6e161f 100644 --- a/packages/in_app_purchase/ios/Classes/FIAPRequestHandler.h +++ b/packages/in_app_purchase/ios/Classes/FIAPRequestHandler.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/ios/Classes/FIAPRequestHandler.m b/packages/in_app_purchase/ios/Classes/FIAPRequestHandler.m index 7172687956bf..8767265d8544 100644 --- a/packages/in_app_purchase/ios/Classes/FIAPRequestHandler.m +++ b/packages/in_app_purchase/ios/Classes/FIAPRequestHandler.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.h b/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.h index 4776062aa04c..fddeb07e01a3 100644 --- a/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.h +++ b/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.m b/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.m index 8eed06ce022c..eb3348e4b3c9 100644 --- a/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.m +++ b/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.h b/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.h index 6974b33fd230..8cb42f3fe8c2 100644 --- a/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.h +++ b/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m b/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m index b254e622e69f..650cd812d470 100644 --- a/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m +++ b/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m b/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m index 7ef757b7c4c5..cb00cbc2a43e 100644 --- a/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m +++ b/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/ios/Tests/PaymentQueueTest.m b/packages/in_app_purchase/ios/Tests/PaymentQueueTest.m index f5248da74635..c335fa3ef307 100644 --- a/packages/in_app_purchase/ios/Tests/PaymentQueueTest.m +++ b/packages/in_app_purchase/ios/Tests/PaymentQueueTest.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/ios/Tests/ProductRequestHandlerTest.m b/packages/in_app_purchase/ios/Tests/ProductRequestHandlerTest.m index 25d11de5f6ad..19f5848b7168 100644 --- a/packages/in_app_purchase/ios/Tests/ProductRequestHandlerTest.m +++ b/packages/in_app_purchase/ios/Tests/ProductRequestHandlerTest.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/ios/Tests/Stubs.h b/packages/in_app_purchase/ios/Tests/Stubs.h index f93d41325199..e07cc3f5a147 100644 --- a/packages/in_app_purchase/ios/Tests/Stubs.h +++ b/packages/in_app_purchase/ios/Tests/Stubs.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/ios/Tests/Stubs.m b/packages/in_app_purchase/ios/Tests/Stubs.m index 640352a82146..66610a88a77d 100644 --- a/packages/in_app_purchase/ios/Tests/Stubs.m +++ b/packages/in_app_purchase/ios/Tests/Stubs.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/ios/Tests/TranslatorTest.m b/packages/in_app_purchase/ios/Tests/TranslatorTest.m index e1db3d154310..550d1fc341c6 100644 --- a/packages/in_app_purchase/ios/Tests/TranslatorTest.m +++ b/packages/in_app_purchase/ios/Tests/TranslatorTest.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/billing_client_wrappers.dart b/packages/in_app_purchase/lib/billing_client_wrappers.dart index e8d13e7d2315..1dac19f825b8 100644 --- a/packages/in_app_purchase/lib/billing_client_wrappers.dart +++ b/packages/in_app_purchase/lib/billing_client_wrappers.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/in_app_purchase.dart b/packages/in_app_purchase/lib/in_app_purchase.dart index b197583614a6..928f860daa4b 100644 --- a/packages/in_app_purchase/lib/in_app_purchase.dart +++ b/packages/in_app_purchase/lib/in_app_purchase.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart index 909c4d70b101..1f43b3a8fbdd 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart index 0b1e96a19d53..1f5e2a286d6a 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart index 2353175b15b4..7ef089f4af8d 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart b/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart index bfaafb7faf08..e3d13df2262a 100644 --- a/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart +++ b/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/src/channel.dart b/packages/in_app_purchase/lib/src/channel.dart index 9976ea6e23d1..f8ab4d48be7e 100644 --- a/packages/in_app_purchase/lib/src/channel.dart +++ b/packages/in_app_purchase/lib/src/channel.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart b/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart index cf0b4df2fbbe..069cf7800599 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart b/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart index 044144e04f24..069dad5f40f3 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart b/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart index c53d40914874..a5db8e5d4206 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/product_details.dart b/packages/in_app_purchase/lib/src/in_app_purchase/product_details.dart index 0f23c3a8e557..151086d90f92 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/product_details.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/product_details.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart b/packages/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart index e346c7f42e42..fc286d404de1 100644 --- a/packages/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart +++ b/packages/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.dart index 2a20b21eabb7..5a4438913338 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart index f4a766a9f4c6..2ba61b0a5d44 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.dart index edf0708b8041..01cd6db0dda1 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.dart index 045c2fcd5b07..ef0e6671d177 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_receipt_manager.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_receipt_manager.dart index 5cab368558a5..429cbf032812 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_receipt_manager.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_receipt_manager.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_request_maker.dart b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_request_maker.dart index 6f143edd50da..88f3ac5835b5 100644 --- a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_request_maker.dart +++ b/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_request_maker.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/lib/store_kit_wrappers.dart b/packages/in_app_purchase/lib/store_kit_wrappers.dart index 3b94a17f9ad9..b687d238083c 100644 --- a/packages/in_app_purchase/lib/store_kit_wrappers.dart +++ b/packages/in_app_purchase/lib/store_kit_wrappers.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart b/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart index b1bfa7f3b6dd..9a5d262923f1 100644 --- a/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart +++ b/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart b/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart index 8aeef23cda3b..b6755262cf1c 100644 --- a/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart +++ b/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart b/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart index 46ec9c602e23..74af47266447 100644 --- a/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart +++ b/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart b/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart index 9b979e6ef021..dfab31906231 100644 --- a/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart +++ b/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart b/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart index d29c0e43d9bc..25feb89fed45 100644 --- a/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart +++ b/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart b/packages/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart index 57932cd44af6..5bc3d92d735e 100644 --- a/packages/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart +++ b/packages/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/test/store_kit_wrappers/sk_product_test.dart b/packages/in_app_purchase/test/store_kit_wrappers/sk_product_test.dart index 6508c83bceb1..e2db6ba7dde8 100644 --- a/packages/in_app_purchase/test/store_kit_wrappers/sk_product_test.dart +++ b/packages/in_app_purchase/test/store_kit_wrappers/sk_product_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/test/store_kit_wrappers/sk_test_stub_objects.dart b/packages/in_app_purchase/test/store_kit_wrappers/sk_test_stub_objects.dart index 7c92a11962fb..09c730ec75b4 100644 --- a/packages/in_app_purchase/test/store_kit_wrappers/sk_test_stub_objects.dart +++ b/packages/in_app_purchase/test/store_kit_wrappers/sk_test_stub_objects.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/in_app_purchase/test/stub_in_app_purchase_platform.dart b/packages/in_app_purchase/test/stub_in_app_purchase_platform.dart index 325b48931896..11a3426335d5 100644 --- a/packages/in_app_purchase/test/stub_in_app_purchase_platform.dart +++ b/packages/in_app_purchase/test/stub_in_app_purchase_platform.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/LICENSE b/packages/integration_test/LICENSE index b257ce7c224c..c6823b81eb84 100644 --- a/packages/integration_test/LICENSE +++ b/packages/integration_test/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/FlutterTestRunner.java b/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/FlutterTestRunner.java index 3cada2f44a58..25cd2a1f5521 100644 --- a/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/FlutterTestRunner.java +++ b/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/FlutterTestRunner.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/IntegrationTestPlugin.java b/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/IntegrationTestPlugin.java index 01adf98ad90d..7793b10f2db5 100644 --- a/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/IntegrationTestPlugin.java +++ b/packages/integration_test/android/src/main/java/dev/flutter/plugins/integration_test/IntegrationTestPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/EmbedderV1ActivityTest.java b/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/EmbedderV1ActivityTest.java index 2ae8cbb37db2..18ac43ee9b39 100644 --- a/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/EmbedderV1ActivityTest.java +++ b/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/EmbedderV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityTest.java b/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityTest.java index b84b290f175b..a607c06f9ce5 100644 --- a/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityTest.java +++ b/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityWithPermissionTest.java b/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityWithPermissionTest.java index a8e868a76838..4752d2fcbcc3 100644 --- a/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityWithPermissionTest.java +++ b/packages/integration_test/example/android/app/src/androidTest/java/com/example/e2e_example/FlutterActivityWithPermissionTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/android/app/src/main/java/com/example/e2e_example/EmbedderV1Activity.java b/packages/integration_test/example/android/app/src/main/java/com/example/e2e_example/EmbedderV1Activity.java index fedd3626fa80..9dbed6e01e8b 100644 --- a/packages/integration_test/example/android/app/src/main/java/com/example/e2e_example/EmbedderV1Activity.java +++ b/packages/integration_test/example/android/app/src/main/java/com/example/e2e_example/EmbedderV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/integration_test/_example_test_io.dart b/packages/integration_test/example/integration_test/_example_test_io.dart index 01bcfe2928b1..eed73218bc3e 100644 --- a/packages/integration_test/example/integration_test/_example_test_io.dart +++ b/packages/integration_test/example/integration_test/_example_test_io.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/integration_test/_example_test_web.dart b/packages/integration_test/example/integration_test/_example_test_web.dart index f0fd6212615a..cfc5b90e180d 100644 --- a/packages/integration_test/example/integration_test/_example_test_web.dart +++ b/packages/integration_test/example/integration_test/_example_test_web.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/integration_test/_extended_test_io.dart b/packages/integration_test/example/integration_test/_extended_test_io.dart index ee0618a5adbc..1a727ee0552d 100644 --- a/packages/integration_test/example/integration_test/_extended_test_io.dart +++ b/packages/integration_test/example/integration_test/_extended_test_io.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/integration_test/_extended_test_web.dart b/packages/integration_test/example/integration_test/_extended_test_web.dart index 878d9949af20..cb0819fd5071 100644 --- a/packages/integration_test/example/integration_test/_extended_test_web.dart +++ b/packages/integration_test/example/integration_test/_extended_test_web.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/integration_test/example_test.dart b/packages/integration_test/example/integration_test/example_test.dart index 382094b9232f..9db52436de88 100644 --- a/packages/integration_test/example/integration_test/example_test.dart +++ b/packages/integration_test/example/integration_test/example_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/integration_test/extended_test.dart b/packages/integration_test/example/integration_test/extended_test.dart index b2a42ffafc00..6e3a40af0032 100644 --- a/packages/integration_test/example/integration_test/extended_test.dart +++ b/packages/integration_test/example/integration_test/extended_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/ios/Runner/AppDelegate.h b/packages/integration_test/example/ios/Runner/AppDelegate.h index d53a2aeb21ac..0681d288bb70 100644 --- a/packages/integration_test/example/ios/Runner/AppDelegate.h +++ b/packages/integration_test/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/ios/Runner/AppDelegate.m b/packages/integration_test/example/ios/Runner/AppDelegate.m index a1fd21cf937c..30b87969f44a 100644 --- a/packages/integration_test/example/ios/Runner/AppDelegate.m +++ b/packages/integration_test/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/ios/Runner/main.m b/packages/integration_test/example/ios/Runner/main.m index 4817030ede8d..f97b9ef5c8a1 100644 --- a/packages/integration_test/example/ios/Runner/main.m +++ b/packages/integration_test/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/ios/RunnerTests/RunnerTests.m b/packages/integration_test/example/ios/RunnerTests/RunnerTests.m index 15cc596a22cb..6b9c5a3cf5a8 100644 --- a/packages/integration_test/example/ios/RunnerTests/RunnerTests.m +++ b/packages/integration_test/example/ios/RunnerTests/RunnerTests.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/lib/main.dart b/packages/integration_test/example/lib/main.dart index 76d2378b32e1..796384bead77 100644 --- a/packages/integration_test/example/lib/main.dart +++ b/packages/integration_test/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/lib/my_app.dart b/packages/integration_test/example/lib/my_app.dart index bfcee0911064..8d497866bbb8 100644 --- a/packages/integration_test/example/lib/my_app.dart +++ b/packages/integration_test/example/lib/my_app.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/lib/my_web_app.dart b/packages/integration_test/example/lib/my_web_app.dart index b3efb24a54a8..c0ea09da24e4 100644 --- a/packages/integration_test/example/lib/my_web_app.dart +++ b/packages/integration_test/example/lib/my_web_app.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/macos/Runner/AppDelegate.swift b/packages/integration_test/example/macos/Runner/AppDelegate.swift index ca19fe95f8cf..5cec4c48f620 100644 --- a/packages/integration_test/example/macos/Runner/AppDelegate.swift +++ b/packages/integration_test/example/macos/Runner/AppDelegate.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/macos/Runner/MainFlutterWindow.swift b/packages/integration_test/example/macos/Runner/MainFlutterWindow.swift index 2ce11b78604b..32aaeedceb1f 100644 --- a/packages/integration_test/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/integration_test/example/macos/Runner/MainFlutterWindow.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/test_driver/extended_integration_test.dart b/packages/integration_test/example/test_driver/extended_integration_test.dart index 059a3d13a2eb..22d93aa7b157 100644 --- a/packages/integration_test/example/test_driver/extended_integration_test.dart +++ b/packages/integration_test/example/test_driver/extended_integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/test_driver/failure.dart b/packages/integration_test/example/test_driver/failure.dart index a37306392321..72b7bab57ca7 100644 --- a/packages/integration_test/example/test_driver/failure.dart +++ b/packages/integration_test/example/test_driver/failure.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/test_driver/failure_test.dart b/packages/integration_test/example/test_driver/failure_test.dart index c90eaafa7090..21dfb08241fc 100644 --- a/packages/integration_test/example/test_driver/failure_test.dart +++ b/packages/integration_test/example/test_driver/failure_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/test_driver/integration_test.dart b/packages/integration_test/example/test_driver/integration_test.dart index 8c650ee9f293..4f10f2a522f3 100644 --- a/packages/integration_test/example/test_driver/integration_test.dart +++ b/packages/integration_test/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/example/web/index.html b/packages/integration_test/example/web/index.html index 492b9fd4cefc..3d58580ac205 100644 --- a/packages/integration_test/example/web/index.html +++ b/packages/integration_test/example/web/index.html @@ -1,5 +1,5 @@ - diff --git a/packages/integration_test/ios/Classes/IntegrationTestIosTest.h b/packages/integration_test/ios/Classes/IntegrationTestIosTest.h index 19503385b70e..553cdbe2cd87 100644 --- a/packages/integration_test/ios/Classes/IntegrationTestIosTest.h +++ b/packages/integration_test/ios/Classes/IntegrationTestIosTest.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/ios/Classes/IntegrationTestIosTest.m b/packages/integration_test/ios/Classes/IntegrationTestIosTest.m index 78cd0c28bbfb..55aebe9f3ff4 100644 --- a/packages/integration_test/ios/Classes/IntegrationTestIosTest.m +++ b/packages/integration_test/ios/Classes/IntegrationTestIosTest.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/ios/Classes/IntegrationTestPlugin.h b/packages/integration_test/ios/Classes/IntegrationTestPlugin.h index 4593e31e1766..918aa8c51f4f 100644 --- a/packages/integration_test/ios/Classes/IntegrationTestPlugin.h +++ b/packages/integration_test/ios/Classes/IntegrationTestPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/ios/Classes/IntegrationTestPlugin.m b/packages/integration_test/ios/Classes/IntegrationTestPlugin.m index 51ac0e34562f..081135e5f4e4 100644 --- a/packages/integration_test/ios/Classes/IntegrationTestPlugin.m +++ b/packages/integration_test/ios/Classes/IntegrationTestPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/lib/_callback_io.dart b/packages/integration_test/lib/_callback_io.dart index fe4e400be997..e6b5fd37004e 100644 --- a/packages/integration_test/lib/_callback_io.dart +++ b/packages/integration_test/lib/_callback_io.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/lib/_callback_web.dart b/packages/integration_test/lib/_callback_web.dart index bff8e8a9d31e..80bb4ad4ab5a 100644 --- a/packages/integration_test/lib/_callback_web.dart +++ b/packages/integration_test/lib/_callback_web.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/lib/_extension_io.dart b/packages/integration_test/lib/_extension_io.dart index 8f6f8ac8cad1..c3b95ff06618 100644 --- a/packages/integration_test/lib/_extension_io.dart +++ b/packages/integration_test/lib/_extension_io.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/lib/_extension_web.dart b/packages/integration_test/lib/_extension_web.dart index b83fc1eb292e..2f4be0cf0034 100644 --- a/packages/integration_test/lib/_extension_web.dart +++ b/packages/integration_test/lib/_extension_web.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/lib/common.dart b/packages/integration_test/lib/common.dart index 15b0c5c0d0cd..b523224e32b3 100644 --- a/packages/integration_test/lib/common.dart +++ b/packages/integration_test/lib/common.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/lib/integration_test.dart b/packages/integration_test/lib/integration_test.dart index 5a070a4fa9ef..d807b603c085 100644 --- a/packages/integration_test/lib/integration_test.dart +++ b/packages/integration_test/lib/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/lib/integration_test_driver.dart b/packages/integration_test/lib/integration_test_driver.dart index 3b0e756000d0..e06340d67f52 100644 --- a/packages/integration_test/lib/integration_test_driver.dart +++ b/packages/integration_test/lib/integration_test_driver.dart @@ -1,4 +1,4 @@ -// Copyright 2014 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/lib/integration_test_driver_extended.dart b/packages/integration_test/lib/integration_test_driver_extended.dart index 613571e26abe..18514f12a102 100644 --- a/packages/integration_test/lib/integration_test_driver_extended.dart +++ b/packages/integration_test/lib/integration_test_driver_extended.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/test/binding_fail_test.dart b/packages/integration_test/test/binding_fail_test.dart index 34c4e6c647df..f5ff21f0cb86 100644 --- a/packages/integration_test/test/binding_fail_test.dart +++ b/packages/integration_test/test/binding_fail_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/test/binding_test.dart b/packages/integration_test/test/binding_test.dart index 449eab5525fc..500d65766da1 100644 --- a/packages/integration_test/test/binding_test.dart +++ b/packages/integration_test/test/binding_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/test/data/fail_test_script.dart b/packages/integration_test/test/data/fail_test_script.dart index 3e2ac31dbd7c..a3055d865049 100644 --- a/packages/integration_test/test/data/fail_test_script.dart +++ b/packages/integration_test/test/data/fail_test_script.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/test/data/pass_test_script.dart b/packages/integration_test/test/data/pass_test_script.dart index cb5eed12ab07..289af70e0005 100644 --- a/packages/integration_test/test/data/pass_test_script.dart +++ b/packages/integration_test/test/data/pass_test_script.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/test/data/pass_then_fail_test_script.dart b/packages/integration_test/test/data/pass_then_fail_test_script.dart index 0b0b67821284..d7de6e6c59f6 100644 --- a/packages/integration_test/test/data/pass_then_fail_test_script.dart +++ b/packages/integration_test/test/data/pass_then_fail_test_script.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/integration_test/test/response_serialization_test.dart b/packages/integration_test/test/response_serialization_test.dart index 54bd49780a5d..3ce6c05a53d6 100644 --- a/packages/integration_test/test/response_serialization_test.dart +++ b/packages/integration_test/test/response_serialization_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/ios_platform_images/LICENSE b/packages/ios_platform_images/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/ios_platform_images/LICENSE +++ b/packages/ios_platform_images/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/ios_platform_images/example/ios/Runner/AppDelegate.swift b/packages/ios_platform_images/example/ios/Runner/AppDelegate.swift index f26669f6bd4f..caf998393333 100644 --- a/packages/ios_platform_images/example/ios/Runner/AppDelegate.swift +++ b/packages/ios_platform_images/example/ios/Runner/AppDelegate.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/ios_platform_images/example/ios/Runner/Runner-Bridging-Header.h b/packages/ios_platform_images/example/ios/Runner/Runner-Bridging-Header.h index 3a69a7befa44..eb7e8ba8052f 100644 --- a/packages/ios_platform_images/example/ios/Runner/Runner-Bridging-Header.h +++ b/packages/ios_platform_images/example/ios/Runner/Runner-Bridging-Header.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/ios_platform_images/example/lib/main.dart b/packages/ios_platform_images/example/lib/main.dart index aa4392243785..d1b07b0a5fee 100644 --- a/packages/ios_platform_images/example/lib/main.dart +++ b/packages/ios_platform_images/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/ios_platform_images/example/test/widget_test.dart b/packages/ios_platform_images/example/test/widget_test.dart index 66d964302180..09fa35c27a6b 100644 --- a/packages/ios_platform_images/example/test/widget_test.dart +++ b/packages/ios_platform_images/example/test/widget_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.h b/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.h index 8125fb2282ba..f3c8efe9bd6a 100644 --- a/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.h +++ b/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.m b/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.m index 76c54d5c2576..abd331e5d0cb 100644 --- a/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.m +++ b/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/ios_platform_images/lib/ios_platform_images.dart b/packages/ios_platform_images/lib/ios_platform_images.dart index 3c30c4b8fc0c..e9bc0b342239 100644 --- a/packages/ios_platform_images/lib/ios_platform_images.dart +++ b/packages/ios_platform_images/lib/ios_platform_images.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/ios_platform_images/test/ios_platform_images_test.dart b/packages/ios_platform_images/test/ios_platform_images_test.dart index bbdf8de57ed5..a896e3d835af 100644 --- a/packages/ios_platform_images/test/ios_platform_images_test.dart +++ b/packages/ios_platform_images/test/ios_platform_images_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/local_auth/LICENSE b/packages/local_auth/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/local_auth/LICENSE +++ b/packages/local_auth/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java b/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java index cf4226d4ed26..2b825c6d1f31 100644 --- a/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java +++ b/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. package io.flutter.plugins.localauth; diff --git a/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java b/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java index 5df034650f34..7ed9a7ea324d 100644 --- a/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java +++ b/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/EmbeddingV1ActivityTest.java b/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/EmbeddingV1ActivityTest.java index dc28926caa08..696fc493c6b8 100644 --- a/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/EmbeddingV1ActivityTest.java +++ b/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java b/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java index ebaf3ccf92ba..e5ece3edd50d 100644 --- a/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java +++ b/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/local_auth/example/android/app/src/main/java/io/flutter/plugins/localauthexample/EmbeddingV1Activity.java b/packages/local_auth/example/android/app/src/main/java/io/flutter/plugins/localauthexample/EmbeddingV1Activity.java index 83af839a9fbb..c3fc8d47b3a4 100644 --- a/packages/local_auth/example/android/app/src/main/java/io/flutter/plugins/localauthexample/EmbeddingV1Activity.java +++ b/packages/local_auth/example/android/app/src/main/java/io/flutter/plugins/localauthexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/local_auth/example/ios/Runner/AppDelegate.h b/packages/local_auth/example/ios/Runner/AppDelegate.h index 31fc381e7066..0681d288bb70 100644 --- a/packages/local_auth/example/ios/Runner/AppDelegate.h +++ b/packages/local_auth/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/local_auth/example/ios/Runner/AppDelegate.m b/packages/local_auth/example/ios/Runner/AppDelegate.m index 2147d3d605ac..30b87969f44a 100644 --- a/packages/local_auth/example/ios/Runner/AppDelegate.m +++ b/packages/local_auth/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/local_auth/example/ios/Runner/main.m b/packages/local_auth/example/ios/Runner/main.m index f451b14cb751..f97b9ef5c8a1 100644 --- a/packages/local_auth/example/ios/Runner/main.m +++ b/packages/local_auth/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/local_auth/example/lib/main.dart b/packages/local_auth/example/lib/main.dart index 7d611a4ea10f..d00a5b1e9ac2 100644 --- a/packages/local_auth/example/lib/main.dart +++ b/packages/local_auth/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/local_auth/integration_test/local_auth_test.dart b/packages/local_auth/integration_test/local_auth_test.dart index 5ebaf39cfe58..436d6b9effcf 100644 --- a/packages/local_auth/integration_test/local_auth_test.dart +++ b/packages/local_auth/integration_test/local_auth_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.h b/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.h index 7fc6e568a470..1a1446fb27bd 100644 --- a/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.h +++ b/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m b/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m index f11517ceb691..40a14b9f4b47 100644 --- a/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m +++ b/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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 diff --git a/packages/local_auth/lib/auth_strings.dart b/packages/local_auth/lib/auth_strings.dart index c7dc6bdf09f0..537340b79d4e 100644 --- a/packages/local_auth/lib/auth_strings.dart +++ b/packages/local_auth/lib/auth_strings.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/local_auth/lib/error_codes.dart b/packages/local_auth/lib/error_codes.dart index 4ead02005250..bcf15b7b2154 100644 --- a/packages/local_auth/lib/error_codes.dart +++ b/packages/local_auth/lib/error_codes.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/local_auth/lib/local_auth.dart b/packages/local_auth/lib/local_auth.dart index cd32b667e140..3f332592a4dd 100644 --- a/packages/local_auth/lib/local_auth.dart +++ b/packages/local_auth/lib/local_auth.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/local_auth/test/local_auth_test.dart b/packages/local_auth/test/local_auth_test.dart index f4bf9fe0314d..d0a4dc8fc594 100644 --- a/packages/local_auth/test/local_auth_test.dart +++ b/packages/local_auth/test/local_auth_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/package_info/LICENSE b/packages/package_info/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/package_info/LICENSE +++ b/packages/package_info/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/package_info/android/src/main/java/io/flutter/plugins/packageinfo/PackageInfoPlugin.java b/packages/package_info/android/src/main/java/io/flutter/plugins/packageinfo/PackageInfoPlugin.java index 1444b1c71148..4611f70951f9 100644 --- a/packages/package_info/android/src/main/java/io/flutter/plugins/packageinfo/PackageInfoPlugin.java +++ b/packages/package_info/android/src/main/java/io/flutter/plugins/packageinfo/PackageInfoPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/package_info/darwin/Classes/FLTPackageInfoPlugin.m b/packages/package_info/darwin/Classes/FLTPackageInfoPlugin.m index 8207438f794b..ab686fa08676 100644 --- a/packages/package_info/darwin/Classes/FLTPackageInfoPlugin.m +++ b/packages/package_info/darwin/Classes/FLTPackageInfoPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/EmbedderV1ActivityTest.java b/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/EmbedderV1ActivityTest.java index aef7d0dbd264..8d3b0b6c6cad 100644 --- a/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/EmbedderV1ActivityTest.java +++ b/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/EmbedderV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/MainActivityTest.java b/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/MainActivityTest.java index f5f95cec3ed1..cf7252ce19de 100644 --- a/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/MainActivityTest.java +++ b/packages/package_info/example/android/app/src/androidTest/java/io/flutter/plugins/packageinfoexample/MainActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/package_info/example/android/app/src/main/java/io/flutter/plugins/packageinfoexample/EmbedderV1Activity.java b/packages/package_info/example/android/app/src/main/java/io/flutter/plugins/packageinfoexample/EmbedderV1Activity.java index d049ed7b4efc..ded5f348c506 100644 --- a/packages/package_info/example/android/app/src/main/java/io/flutter/plugins/packageinfoexample/EmbedderV1Activity.java +++ b/packages/package_info/example/android/app/src/main/java/io/flutter/plugins/packageinfoexample/EmbedderV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/package_info/example/integration_test/package_info_test.dart b/packages/package_info/example/integration_test/package_info_test.dart index ecd75e2687f2..10db8d0caf57 100644 --- a/packages/package_info/example/integration_test/package_info_test.dart +++ b/packages/package_info/example/integration_test/package_info_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/package_info/example/ios/Runner/AppDelegate.h b/packages/package_info/example/ios/Runner/AppDelegate.h index 31fc381e7066..0681d288bb70 100644 --- a/packages/package_info/example/ios/Runner/AppDelegate.h +++ b/packages/package_info/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/package_info/example/ios/Runner/AppDelegate.m b/packages/package_info/example/ios/Runner/AppDelegate.m index 2147d3d605ac..30b87969f44a 100644 --- a/packages/package_info/example/ios/Runner/AppDelegate.m +++ b/packages/package_info/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/package_info/example/ios/Runner/main.m b/packages/package_info/example/ios/Runner/main.m index f451b14cb751..f97b9ef5c8a1 100644 --- a/packages/package_info/example/ios/Runner/main.m +++ b/packages/package_info/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/package_info/example/lib/main.dart b/packages/package_info/example/lib/main.dart index 3fa7780fe9bb..60e4a16f7817 100644 --- a/packages/package_info/example/lib/main.dart +++ b/packages/package_info/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/package_info/example/macos/Runner/AppDelegate.swift b/packages/package_info/example/macos/Runner/AppDelegate.swift index ca19fe95f8cf..5cec4c48f620 100644 --- a/packages/package_info/example/macos/Runner/AppDelegate.swift +++ b/packages/package_info/example/macos/Runner/AppDelegate.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/package_info/example/macos/Runner/MainFlutterWindow.swift b/packages/package_info/example/macos/Runner/MainFlutterWindow.swift index 2ce11b78604b..32aaeedceb1f 100644 --- a/packages/package_info/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/package_info/example/macos/Runner/MainFlutterWindow.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/package_info/example/test_driver/integration_test.dart b/packages/package_info/example/test_driver/integration_test.dart index 9e813df086c1..1bcccae039d6 100644 --- a/packages/package_info/example/test_driver/integration_test.dart +++ b/packages/package_info/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/package_info/ios/Classes/FLTPackageInfoPlugin.h b/packages/package_info/ios/Classes/FLTPackageInfoPlugin.h index e6a73bf164c5..65be5f99d569 100644 --- a/packages/package_info/ios/Classes/FLTPackageInfoPlugin.h +++ b/packages/package_info/ios/Classes/FLTPackageInfoPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/package_info/lib/package_info.dart b/packages/package_info/lib/package_info.dart index 7bcd80619037..69246813873a 100644 --- a/packages/package_info/lib/package_info.dart +++ b/packages/package_info/lib/package_info.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/package_info/macos/Classes/FLTPackageInfoPlugin.h b/packages/package_info/macos/Classes/FLTPackageInfoPlugin.h index b8705ddfc199..590e8263d951 100644 --- a/packages/package_info/macos/Classes/FLTPackageInfoPlugin.h +++ b/packages/package_info/macos/Classes/FLTPackageInfoPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/package_info/test/package_info_test.dart b/packages/package_info/test/package_info_test.dart index cb6967155ca0..91661de72103 100644 --- a/packages/package_info/test/package_info_test.dart +++ b/packages/package_info/test/package_info_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/LICENSE b/packages/path_provider/path_provider/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/path_provider/path_provider/LICENSE +++ b/packages/path_provider/path_provider/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/path_provider/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java b/packages/path_provider/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java index 9a0c76232fb3..49360809e892 100644 --- a/packages/path_provider/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java +++ b/packages/path_provider/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java b/packages/path_provider/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java index c41b81deaff6..1a77560623a2 100644 --- a/packages/path_provider/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java +++ b/packages/path_provider/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java b/packages/path_provider/path_provider/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java index 2df4497332b3..7469c545b817 100644 --- a/packages/path_provider/path_provider/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java +++ b/packages/path_provider/path_provider/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java b/packages/path_provider/path_provider/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java index 9292edb43dd7..b6a39a8260ce 100644 --- a/packages/path_provider/path_provider/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java +++ b/packages/path_provider/path_provider/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/android/app/src/androidTest/java/MainActivityTest.java b/packages/path_provider/path_provider/example/android/app/src/androidTest/java/MainActivityTest.java index 986e3a439b0f..0380a4397ae6 100644 --- a/packages/path_provider/path_provider/example/android/app/src/androidTest/java/MainActivityTest.java +++ b/packages/path_provider/path_provider/example/android/app/src/androidTest/java/MainActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java b/packages/path_provider/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java index 2853fb394179..997cd1081a0a 100644 --- a/packages/path_provider/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java +++ b/packages/path_provider/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart b/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart index 71c138b2dd3e..2613b45a8574 100644 --- a/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/ios/Runner/AppDelegate.h b/packages/path_provider/path_provider/example/ios/Runner/AppDelegate.h index 31fc381e7066..0681d288bb70 100644 --- a/packages/path_provider/path_provider/example/ios/Runner/AppDelegate.h +++ b/packages/path_provider/path_provider/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/ios/Runner/AppDelegate.m b/packages/path_provider/path_provider/example/ios/Runner/AppDelegate.m index abfe2106b092..b790a0a52635 100644 --- a/packages/path_provider/path_provider/example/ios/Runner/AppDelegate.m +++ b/packages/path_provider/path_provider/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/ios/Runner/main.m b/packages/path_provider/path_provider/example/ios/Runner/main.m index f451b14cb751..f97b9ef5c8a1 100644 --- a/packages/path_provider/path_provider/example/ios/Runner/main.m +++ b/packages/path_provider/path_provider/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/lib/main.dart b/packages/path_provider/path_provider/example/lib/main.dart index ddc1f8a6e2d5..7b1d6a73a2f5 100644 --- a/packages/path_provider/path_provider/example/lib/main.dart +++ b/packages/path_provider/path_provider/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/linux/main.cc b/packages/path_provider/path_provider/example/linux/main.cc index a15afa068a7b..88a5fd45ce1b 100644 --- a/packages/path_provider/path_provider/example/linux/main.cc +++ b/packages/path_provider/path_provider/example/linux/main.cc @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/linux/my_application.cc b/packages/path_provider/path_provider/example/linux/my_application.cc index 3843c07aaf04..9cb411ba475b 100644 --- a/packages/path_provider/path_provider/example/linux/my_application.cc +++ b/packages/path_provider/path_provider/example/linux/my_application.cc @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/linux/my_application.h b/packages/path_provider/path_provider/example/linux/my_application.h index b3d62442a005..6e9f0c3ff665 100644 --- a/packages/path_provider/path_provider/example/linux/my_application.h +++ b/packages/path_provider/path_provider/example/linux/my_application.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/macos/Runner/AppDelegate.swift b/packages/path_provider/path_provider/example/macos/Runner/AppDelegate.swift index ca19fe95f8cf..5cec4c48f620 100644 --- a/packages/path_provider/path_provider/example/macos/Runner/AppDelegate.swift +++ b/packages/path_provider/path_provider/example/macos/Runner/AppDelegate.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/macos/Runner/MainFlutterWindow.swift b/packages/path_provider/path_provider/example/macos/Runner/MainFlutterWindow.swift index 2ce11b78604b..32aaeedceb1f 100644 --- a/packages/path_provider/path_provider/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/path_provider/path_provider/example/macos/Runner/MainFlutterWindow.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/test_driver/integration_test.dart b/packages/path_provider/path_provider/example/test_driver/integration_test.dart index dec1aa55d40e..18ed3cff3ee8 100644 --- a/packages/path_provider/path_provider/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/windows/runner/flutter_window.cpp b/packages/path_provider/path_provider/example/windows/runner/flutter_window.cpp index b7d078e4d4a5..8e415602cf3b 100644 --- a/packages/path_provider/path_provider/example/windows/runner/flutter_window.cpp +++ b/packages/path_provider/path_provider/example/windows/runner/flutter_window.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/windows/runner/flutter_window.h b/packages/path_provider/path_provider/example/windows/runner/flutter_window.h index 9b4ef089621b..8e9c12bbe022 100644 --- a/packages/path_provider/path_provider/example/windows/runner/flutter_window.h +++ b/packages/path_provider/path_provider/example/windows/runner/flutter_window.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/windows/runner/main.cpp b/packages/path_provider/path_provider/example/windows/runner/main.cpp index e74157ed999a..126302b0be18 100644 --- a/packages/path_provider/path_provider/example/windows/runner/main.cpp +++ b/packages/path_provider/path_provider/example/windows/runner/main.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/windows/runner/run_loop.cpp b/packages/path_provider/path_provider/example/windows/runner/run_loop.cpp index ee2e2fd5eae9..1916500e6440 100644 --- a/packages/path_provider/path_provider/example/windows/runner/run_loop.cpp +++ b/packages/path_provider/path_provider/example/windows/runner/run_loop.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/windows/runner/run_loop.h b/packages/path_provider/path_provider/example/windows/runner/run_loop.h index a24c47f2e55f..819ed3ed4995 100644 --- a/packages/path_provider/path_provider/example/windows/runner/run_loop.h +++ b/packages/path_provider/path_provider/example/windows/runner/run_loop.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/windows/runner/utils.cpp b/packages/path_provider/path_provider/example/windows/runner/utils.cpp index 9eba364025d0..537728149601 100644 --- a/packages/path_provider/path_provider/example/windows/runner/utils.cpp +++ b/packages/path_provider/path_provider/example/windows/runner/utils.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/windows/runner/utils.h b/packages/path_provider/path_provider/example/windows/runner/utils.h index 640587eb23ab..16b3f0794597 100644 --- a/packages/path_provider/path_provider/example/windows/runner/utils.h +++ b/packages/path_provider/path_provider/example/windows/runner/utils.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/windows/runner/win32_window.cpp b/packages/path_provider/path_provider/example/windows/runner/win32_window.cpp index 97628170c2c2..a609a2002bb3 100644 --- a/packages/path_provider/path_provider/example/windows/runner/win32_window.cpp +++ b/packages/path_provider/path_provider/example/windows/runner/win32_window.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/example/windows/runner/win32_window.h b/packages/path_provider/path_provider/example/windows/runner/win32_window.h index 59b78382b27d..d2a730052223 100644 --- a/packages/path_provider/path_provider/example/windows/runner/win32_window.h +++ b/packages/path_provider/path_provider/example/windows/runner/win32_window.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/integration_test/path_provider_test.dart b/packages/path_provider/path_provider/integration_test/path_provider_test.dart index da368d52b832..1383099a0f16 100644 --- a/packages/path_provider/path_provider/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider/integration_test/path_provider_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/ios/Classes/FLTPathProviderPlugin.h b/packages/path_provider/path_provider/ios/Classes/FLTPathProviderPlugin.h index 394f8c070632..8f9fd4597f9d 100644 --- a/packages/path_provider/path_provider/ios/Classes/FLTPathProviderPlugin.h +++ b/packages/path_provider/path_provider/ios/Classes/FLTPathProviderPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/ios/Classes/FLTPathProviderPlugin.m b/packages/path_provider/path_provider/ios/Classes/FLTPathProviderPlugin.m index 705b371b4586..4d3dfeb6e6e6 100644 --- a/packages/path_provider/path_provider/ios/Classes/FLTPathProviderPlugin.m +++ b/packages/path_provider/path_provider/ios/Classes/FLTPathProviderPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/lib/path_provider.dart b/packages/path_provider/path_provider/lib/path_provider.dart index da9c0b3d48a3..d63887a60267 100644 --- a/packages/path_provider/path_provider/lib/path_provider.dart +++ b/packages/path_provider/path_provider/lib/path_provider.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider/test/path_provider_test.dart b/packages/path_provider/path_provider/test/path_provider_test.dart index 759e9c09ffc2..7232a74a1253 100644 --- a/packages/path_provider/path_provider/test/path_provider_test.dart +++ b/packages/path_provider/path_provider/test/path_provider_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_linux/LICENSE b/packages/path_provider/path_provider_linux/LICENSE index 67c7e2c52e46..c6823b81eb84 100644 --- a/packages/path_provider/path_provider_linux/LICENSE +++ b/packages/path_provider/path_provider_linux/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart b/packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart index a4b254145344..8776e84e8b3b 100644 --- a/packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider_linux/example/integration_test/path_provider_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_linux/example/lib/main.dart b/packages/path_provider/path_provider_linux/example/lib/main.dart index bd1c80a12fb7..104c998bc61a 100644 --- a/packages/path_provider/path_provider_linux/example/lib/main.dart +++ b/packages/path_provider/path_provider_linux/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_linux/example/linux/main.cc b/packages/path_provider/path_provider_linux/example/linux/main.cc index a15afa068a7b..88a5fd45ce1b 100644 --- a/packages/path_provider/path_provider_linux/example/linux/main.cc +++ b/packages/path_provider/path_provider_linux/example/linux/main.cc @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_linux/example/linux/my_application.cc b/packages/path_provider/path_provider_linux/example/linux/my_application.cc index 3843c07aaf04..9cb411ba475b 100644 --- a/packages/path_provider/path_provider_linux/example/linux/my_application.cc +++ b/packages/path_provider/path_provider_linux/example/linux/my_application.cc @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_linux/example/linux/my_application.h b/packages/path_provider/path_provider_linux/example/linux/my_application.h index b3d62442a005..6e9f0c3ff665 100644 --- a/packages/path_provider/path_provider_linux/example/linux/my_application.h +++ b/packages/path_provider/path_provider_linux/example/linux/my_application.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_linux/example/test/widget_test.dart b/packages/path_provider/path_provider_linux/example/test/widget_test.dart index e25ebe36fb08..4d5da3e4e330 100644 --- a/packages/path_provider/path_provider_linux/example/test/widget_test.dart +++ b/packages/path_provider/path_provider_linux/example/test/widget_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart b/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart index dec1aa55d40e..18ed3cff3ee8 100644 --- a/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart b/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart index 0295ffa2d15a..cf8d12436429 100644 --- a/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart +++ b/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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:io'; diff --git a/packages/path_provider/path_provider_linux/test/path_provider_linux_test.dart b/packages/path_provider/path_provider_linux/test/path_provider_linux_test.dart index 5ec530313462..81329fb7c3cb 100644 --- a/packages/path_provider/path_provider_linux/test/path_provider_linux_test.dart +++ b/packages/path_provider/path_provider_linux/test/path_provider_linux_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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_test/flutter_test.dart'; diff --git a/packages/path_provider/path_provider_macos/LICENSE b/packages/path_provider/path_provider_macos/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/path_provider/path_provider_macos/LICENSE +++ b/packages/path_provider/path_provider_macos/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/path_provider/path_provider_macos/example/integration_test/path_provider_test.dart b/packages/path_provider/path_provider_macos/example/integration_test/path_provider_test.dart index 21f757c86e71..734caa9ac7a2 100644 --- a/packages/path_provider/path_provider_macos/example/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider_macos/example/integration_test/path_provider_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_macos/example/lib/main.dart b/packages/path_provider/path_provider_macos/example/lib/main.dart index f19807f1c273..19ba86e31cf5 100644 --- a/packages/path_provider/path_provider_macos/example/lib/main.dart +++ b/packages/path_provider/path_provider_macos/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/AppDelegate.swift b/packages/path_provider/path_provider_macos/example/macos/Runner/AppDelegate.swift index ca19fe95f8cf..5cec4c48f620 100644 --- a/packages/path_provider/path_provider_macos/example/macos/Runner/AppDelegate.swift +++ b/packages/path_provider/path_provider_macos/example/macos/Runner/AppDelegate.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/MainFlutterWindow.swift b/packages/path_provider/path_provider_macos/example/macos/Runner/MainFlutterWindow.swift index 2ce11b78604b..32aaeedceb1f 100644 --- a/packages/path_provider/path_provider_macos/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/path_provider/path_provider_macos/example/macos/Runner/MainFlutterWindow.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart b/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart index dec1aa55d40e..18ed3cff3ee8 100644 --- a/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_macos/macos/Classes/PathProviderPlugin.swift b/packages/path_provider/path_provider_macos/macos/Classes/PathProviderPlugin.swift index 8081b89b2ccf..b308793be355 100644 --- a/packages/path_provider/path_provider_macos/macos/Classes/PathProviderPlugin.swift +++ b/packages/path_provider/path_provider_macos/macos/Classes/PathProviderPlugin.swift @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_platform_interface/LICENSE b/packages/path_provider/path_provider_platform_interface/LICENSE index 67c7e2c52e46..c6823b81eb84 100644 --- a/packages/path_provider/path_provider_platform_interface/LICENSE +++ b/packages/path_provider/path_provider_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart b/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart index 5b7046bda3d8..3eb1580711ef 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart b/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart index fe46401501d4..e355d7d1a5be 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart index 418d983273ea..7889e004126f 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart index 3f44387f1b7d..71d55861c7b1 100644 --- a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart +++ b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_windows/LICENSE b/packages/path_provider/path_provider_windows/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/path_provider/path_provider_windows/LICENSE +++ b/packages/path_provider/path_provider_windows/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/path_provider/path_provider_windows/example/integration_test/path_provider_test.dart b/packages/path_provider/path_provider_windows/example/integration_test/path_provider_test.dart index 733865b577f0..f99b830b163d 100644 --- a/packages/path_provider/path_provider_windows/example/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider_windows/example/integration_test/path_provider_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_windows/example/lib/main.dart b/packages/path_provider/path_provider_windows/example/lib/main.dart index 7d4db2304259..b4b0f999d937 100644 --- a/packages/path_provider/path_provider_windows/example/lib/main.dart +++ b/packages/path_provider/path_provider_windows/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart b/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart index dec1aa55d40e..18ed3cff3ee8 100644 --- a/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_windows/example/windows/runner/flutter_window.cpp b/packages/path_provider/path_provider_windows/example/windows/runner/flutter_window.cpp index b7d078e4d4a5..8e415602cf3b 100644 --- a/packages/path_provider/path_provider_windows/example/windows/runner/flutter_window.cpp +++ b/packages/path_provider/path_provider_windows/example/windows/runner/flutter_window.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_windows/example/windows/runner/flutter_window.h b/packages/path_provider/path_provider_windows/example/windows/runner/flutter_window.h index 9b4ef089621b..8e9c12bbe022 100644 --- a/packages/path_provider/path_provider_windows/example/windows/runner/flutter_window.h +++ b/packages/path_provider/path_provider_windows/example/windows/runner/flutter_window.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_windows/example/windows/runner/main.cpp b/packages/path_provider/path_provider_windows/example/windows/runner/main.cpp index e74157ed999a..126302b0be18 100644 --- a/packages/path_provider/path_provider_windows/example/windows/runner/main.cpp +++ b/packages/path_provider/path_provider_windows/example/windows/runner/main.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_windows/example/windows/runner/run_loop.cpp b/packages/path_provider/path_provider_windows/example/windows/runner/run_loop.cpp index ee2e2fd5eae9..1916500e6440 100644 --- a/packages/path_provider/path_provider_windows/example/windows/runner/run_loop.cpp +++ b/packages/path_provider/path_provider_windows/example/windows/runner/run_loop.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_windows/example/windows/runner/run_loop.h b/packages/path_provider/path_provider_windows/example/windows/runner/run_loop.h index a24c47f2e55f..819ed3ed4995 100644 --- a/packages/path_provider/path_provider_windows/example/windows/runner/run_loop.h +++ b/packages/path_provider/path_provider_windows/example/windows/runner/run_loop.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_windows/example/windows/runner/utils.cpp b/packages/path_provider/path_provider_windows/example/windows/runner/utils.cpp index 9eba364025d0..537728149601 100644 --- a/packages/path_provider/path_provider_windows/example/windows/runner/utils.cpp +++ b/packages/path_provider/path_provider_windows/example/windows/runner/utils.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_windows/example/windows/runner/utils.h b/packages/path_provider/path_provider_windows/example/windows/runner/utils.h index 640587eb23ab..16b3f0794597 100644 --- a/packages/path_provider/path_provider_windows/example/windows/runner/utils.h +++ b/packages/path_provider/path_provider_windows/example/windows/runner/utils.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_windows/example/windows/runner/win32_window.cpp b/packages/path_provider/path_provider_windows/example/windows/runner/win32_window.cpp index 97628170c2c2..a609a2002bb3 100644 --- a/packages/path_provider/path_provider_windows/example/windows/runner/win32_window.cpp +++ b/packages/path_provider/path_provider_windows/example/windows/runner/win32_window.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_windows/example/windows/runner/win32_window.h b/packages/path_provider/path_provider_windows/example/windows/runner/win32_window.h index 59b78382b27d..d2a730052223 100644 --- a/packages/path_provider/path_provider_windows/example/windows/runner/win32_window.h +++ b/packages/path_provider/path_provider_windows/example/windows/runner/win32_window.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_windows/lib/path_provider_windows.dart b/packages/path_provider/path_provider_windows/lib/path_provider_windows.dart index dbb178242970..9af55ac2616c 100644 --- a/packages/path_provider/path_provider_windows/lib/path_provider_windows.dart +++ b/packages/path_provider/path_provider_windows/lib/path_provider_windows.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_windows/lib/src/folders.dart b/packages/path_provider/path_provider_windows/lib/src/folders.dart index d1e7ecc767f0..e8112c1a953a 100644 --- a/packages/path_provider/path_provider_windows/lib/src/folders.dart +++ b/packages/path_provider/path_provider_windows/lib/src/folders.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_windows/lib/src/folders_stub.dart b/packages/path_provider/path_provider_windows/lib/src/folders_stub.dart index 6dae052246ad..34e9e6118f7d 100644 --- a/packages/path_provider/path_provider_windows/lib/src/folders_stub.dart +++ b/packages/path_provider/path_provider_windows/lib/src/folders_stub.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart index 23eee59f32fb..5fef0dba32ed 100644 --- a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart +++ b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_stub.dart b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_stub.dart index 9d71d2258e04..69094af9eafa 100644 --- a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_stub.dart +++ b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_stub.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/path_provider/path_provider_windows/test/path_provider_windows_test.dart b/packages/path_provider/path_provider_windows/test/path_provider_windows_test.dart index 0ca4595fa14e..22683d721e7c 100644 --- a/packages/path_provider/path_provider_windows/test/path_provider_windows_test.dart +++ b/packages/path_provider/path_provider_windows/test/path_provider_windows_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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:ffi'; diff --git a/packages/plugin_platform_interface/LICENSE b/packages/plugin_platform_interface/LICENSE index b257ce7c224c..c6823b81eb84 100644 --- a/packages/plugin_platform_interface/LICENSE +++ b/packages/plugin_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/plugin_platform_interface/lib/plugin_platform_interface.dart b/packages/plugin_platform_interface/lib/plugin_platform_interface.dart index 187d1fa47b44..d9bd88168422 100644 --- a/packages/plugin_platform_interface/lib/plugin_platform_interface.dart +++ b/packages/plugin_platform_interface/lib/plugin_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/plugin_platform_interface/test/plugin_platform_interface_test.dart b/packages/plugin_platform_interface/test/plugin_platform_interface_test.dart index 8b5d68f00684..0079765f0b09 100644 --- a/packages/plugin_platform_interface/test/plugin_platform_interface_test.dart +++ b/packages/plugin_platform_interface/test/plugin_platform_interface_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/quick_actions/quick_actions/LICENSE b/packages/quick_actions/quick_actions/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/quick_actions/quick_actions/LICENSE +++ b/packages/quick_actions/quick_actions/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/quick_actions/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/MethodCallHandlerImpl.java b/packages/quick_actions/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/MethodCallHandlerImpl.java index 6d7f79fb7c2d..465283053442 100644 --- a/packages/quick_actions/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/MethodCallHandlerImpl.java +++ b/packages/quick_actions/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/MethodCallHandlerImpl.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/quick_actions/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/QuickActionsPlugin.java b/packages/quick_actions/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/QuickActionsPlugin.java index 695ff00a1a67..ab3431325503 100644 --- a/packages/quick_actions/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/QuickActionsPlugin.java +++ b/packages/quick_actions/quick_actions/android/src/main/java/io/flutter/plugins/quickactions/QuickActionsPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/quick_actions/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1Activity.java b/packages/quick_actions/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1Activity.java index db2b2f69609c..d85ead3b4e36 100644 --- a/packages/quick_actions/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1Activity.java +++ b/packages/quick_actions/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/quick_actions/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1ActivityTest.java b/packages/quick_actions/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1ActivityTest.java index 16820dfa0f39..a7fab3f052a4 100644 --- a/packages/quick_actions/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1ActivityTest.java +++ b/packages/quick_actions/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/quick_actions/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/FlutterActivityTest.java b/packages/quick_actions/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/FlutterActivityTest.java index 4eb4033a4f94..0b60dfa53e1f 100644 --- a/packages/quick_actions/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/FlutterActivityTest.java +++ b/packages/quick_actions/quick_actions/example/android/app/src/main/java/io/flutter/plugins/quickactionsexample/FlutterActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/quick_actions/quick_actions/example/integration_test/quick_actions_test.dart b/packages/quick_actions/quick_actions/example/integration_test/quick_actions_test.dart index f8841843b016..4b0ec7584243 100644 --- a/packages/quick_actions/quick_actions/example/integration_test/quick_actions_test.dart +++ b/packages/quick_actions/quick_actions/example/integration_test/quick_actions_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/quick_actions/quick_actions/example/ios/Runner/AppDelegate.h b/packages/quick_actions/quick_actions/example/ios/Runner/AppDelegate.h index 31fc381e7066..0681d288bb70 100644 --- a/packages/quick_actions/quick_actions/example/ios/Runner/AppDelegate.h +++ b/packages/quick_actions/quick_actions/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/quick_actions/quick_actions/example/ios/Runner/AppDelegate.m b/packages/quick_actions/quick_actions/example/ios/Runner/AppDelegate.m index 2147d3d605ac..30b87969f44a 100644 --- a/packages/quick_actions/quick_actions/example/ios/Runner/AppDelegate.m +++ b/packages/quick_actions/quick_actions/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/quick_actions/quick_actions/example/ios/Runner/main.m b/packages/quick_actions/quick_actions/example/ios/Runner/main.m index f451b14cb751..f97b9ef5c8a1 100644 --- a/packages/quick_actions/quick_actions/example/ios/Runner/main.m +++ b/packages/quick_actions/quick_actions/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/quick_actions/quick_actions/example/ios/RunnerUITests/RunnerUITests.m b/packages/quick_actions/quick_actions/example/ios/RunnerUITests/RunnerUITests.m index dfb8022529d2..45791864d239 100644 --- a/packages/quick_actions/quick_actions/example/ios/RunnerUITests/RunnerUITests.m +++ b/packages/quick_actions/quick_actions/example/ios/RunnerUITests/RunnerUITests.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/quick_actions/quick_actions/example/lib/main.dart b/packages/quick_actions/quick_actions/example/lib/main.dart index 4422a520c9ed..3ff6528f3565 100644 --- a/packages/quick_actions/quick_actions/example/lib/main.dart +++ b/packages/quick_actions/quick_actions/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/quick_actions/quick_actions/example/test_driver/integration_test.dart b/packages/quick_actions/quick_actions/example/test_driver/integration_test.dart index b02d7d397106..4c4c006068b8 100644 --- a/packages/quick_actions/quick_actions/example/test_driver/integration_test.dart +++ b/packages/quick_actions/quick_actions/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/quick_actions/quick_actions/ios/Classes/FLTQuickActionsPlugin.h b/packages/quick_actions/quick_actions/ios/Classes/FLTQuickActionsPlugin.h index d170a81a2e58..8f98cc35e8ba 100644 --- a/packages/quick_actions/quick_actions/ios/Classes/FLTQuickActionsPlugin.h +++ b/packages/quick_actions/quick_actions/ios/Classes/FLTQuickActionsPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/quick_actions/quick_actions/ios/Classes/FLTQuickActionsPlugin.m b/packages/quick_actions/quick_actions/ios/Classes/FLTQuickActionsPlugin.m index 808d4d112b12..0025795744f9 100644 --- a/packages/quick_actions/quick_actions/ios/Classes/FLTQuickActionsPlugin.m +++ b/packages/quick_actions/quick_actions/ios/Classes/FLTQuickActionsPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/quick_actions/quick_actions/lib/quick_actions.dart b/packages/quick_actions/quick_actions/lib/quick_actions.dart index fe95b1d07765..23dd15302d57 100644 --- a/packages/quick_actions/quick_actions/lib/quick_actions.dart +++ b/packages/quick_actions/quick_actions/lib/quick_actions.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/quick_actions/quick_actions/test/quick_actions_test.dart b/packages/quick_actions/quick_actions/test/quick_actions_test.dart index 9adcf5628a47..f2b9a9aefc8d 100644 --- a/packages/quick_actions/quick_actions/test/quick_actions_test.dart +++ b/packages/quick_actions/quick_actions/test/quick_actions_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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'; diff --git a/packages/sensors/LICENSE b/packages/sensors/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/sensors/LICENSE +++ b/packages/sensors/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/SensorsPlugin.java b/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/SensorsPlugin.java index 4aac1a58d6bf..c643edce3401 100644 --- a/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/SensorsPlugin.java +++ b/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/SensorsPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/StreamHandlerImpl.java b/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/StreamHandlerImpl.java index 93fd2e0fbf2b..7e6da156386d 100644 --- a/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/StreamHandlerImpl.java +++ b/packages/sensors/android/src/main/java/io/flutter/plugins/sensors/StreamHandlerImpl.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1Activity.java b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1Activity.java index 23390293aeb5..128768a097aa 100644 --- a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1Activity.java +++ b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1ActivityTest.java b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1ActivityTest.java index 9760ef098572..c96ab243a778 100644 --- a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1ActivityTest.java +++ b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/FlutterActivityTest.java b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/FlutterActivityTest.java index 7f2d79bab028..c1584aab107c 100644 --- a/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/FlutterActivityTest.java +++ b/packages/sensors/example/android/app/src/main/java/io/flutter/plugins/sensorsexample/FlutterActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/sensors/example/ios/Runner/AppDelegate.h b/packages/sensors/example/ios/Runner/AppDelegate.h index 31fc381e7066..0681d288bb70 100644 --- a/packages/sensors/example/ios/Runner/AppDelegate.h +++ b/packages/sensors/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/sensors/example/ios/Runner/AppDelegate.m b/packages/sensors/example/ios/Runner/AppDelegate.m index 2147d3d605ac..30b87969f44a 100644 --- a/packages/sensors/example/ios/Runner/AppDelegate.m +++ b/packages/sensors/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/sensors/example/ios/Runner/main.m b/packages/sensors/example/ios/Runner/main.m index f451b14cb751..f97b9ef5c8a1 100644 --- a/packages/sensors/example/ios/Runner/main.m +++ b/packages/sensors/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/sensors/example/lib/main.dart b/packages/sensors/example/lib/main.dart index 88cc2d7a2750..0946a8e8421b 100644 --- a/packages/sensors/example/lib/main.dart +++ b/packages/sensors/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/sensors/example/lib/snake.dart b/packages/sensors/example/lib/snake.dart index 28610758ca5f..47177681020f 100644 --- a/packages/sensors/example/lib/snake.dart +++ b/packages/sensors/example/lib/snake.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/sensors/example/test_driver/test/integration_test.dart b/packages/sensors/example/test_driver/test/integration_test.dart index ac2a0cf5f19b..257b0d3c0930 100644 --- a/packages/sensors/example/test_driver/test/integration_test.dart +++ b/packages/sensors/example/test_driver/test/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/sensors/integration_test/sensors_test.dart b/packages/sensors/integration_test/sensors_test.dart index ecee934b799a..3b8f614d2dcb 100644 --- a/packages/sensors/integration_test/sensors_test.dart +++ b/packages/sensors/integration_test/sensors_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/sensors/ios/Classes/FLTSensorsPlugin.h b/packages/sensors/ios/Classes/FLTSensorsPlugin.h index c3eaa137d065..8c3176b42a44 100644 --- a/packages/sensors/ios/Classes/FLTSensorsPlugin.h +++ b/packages/sensors/ios/Classes/FLTSensorsPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/sensors/ios/Classes/FLTSensorsPlugin.m b/packages/sensors/ios/Classes/FLTSensorsPlugin.m index d3541337280a..110fd305f14b 100644 --- a/packages/sensors/ios/Classes/FLTSensorsPlugin.m +++ b/packages/sensors/ios/Classes/FLTSensorsPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/sensors/lib/sensors.dart b/packages/sensors/lib/sensors.dart index 3309f1b20453..8db29e017ad0 100644 --- a/packages/sensors/lib/sensors.dart +++ b/packages/sensors/lib/sensors.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/sensors/test/sensors_test.dart b/packages/sensors/test/sensors_test.dart index 89856279ff16..659c658c3604 100644 --- a/packages/sensors/test/sensors_test.dart +++ b/packages/sensors/test/sensors_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/LICENSE b/packages/share/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/share/LICENSE +++ b/packages/share/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/share/android/src/main/java/io/flutter/plugins/share/MethodCallHandler.java b/packages/share/android/src/main/java/io/flutter/plugins/share/MethodCallHandler.java index 99baabeab6b7..7f162e883c32 100644 --- a/packages/share/android/src/main/java/io/flutter/plugins/share/MethodCallHandler.java +++ b/packages/share/android/src/main/java/io/flutter/plugins/share/MethodCallHandler.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/android/src/main/java/io/flutter/plugins/share/Share.java b/packages/share/android/src/main/java/io/flutter/plugins/share/Share.java index be7280eea673..fced7bb7f87c 100644 --- a/packages/share/android/src/main/java/io/flutter/plugins/share/Share.java +++ b/packages/share/android/src/main/java/io/flutter/plugins/share/Share.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/android/src/main/java/io/flutter/plugins/share/ShareFileProvider.java b/packages/share/android/src/main/java/io/flutter/plugins/share/ShareFileProvider.java index 87e4e42a03d4..fff48a6bad14 100644 --- a/packages/share/android/src/main/java/io/flutter/plugins/share/ShareFileProvider.java +++ b/packages/share/android/src/main/java/io/flutter/plugins/share/ShareFileProvider.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/android/src/main/java/io/flutter/plugins/share/SharePlugin.java b/packages/share/android/src/main/java/io/flutter/plugins/share/SharePlugin.java index af4a02eaba47..6807851caf6b 100644 --- a/packages/share/android/src/main/java/io/flutter/plugins/share/SharePlugin.java +++ b/packages/share/android/src/main/java/io/flutter/plugins/share/SharePlugin.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1Activity.java b/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1Activity.java index 32c382f656f8..85f4efb208af 100644 --- a/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1Activity.java +++ b/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1ActivityTest.java b/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1ActivityTest.java index 77bc7cedcfa5..cbe6c064371d 100644 --- a/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1ActivityTest.java +++ b/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/FlutterActivityTest.java b/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/FlutterActivityTest.java index 9767b63e7799..070749dcff20 100644 --- a/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/FlutterActivityTest.java +++ b/packages/share/example/android/app/src/main/java/io/flutter/plugins/shareexample/FlutterActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/example/ios/Runner/AppDelegate.h b/packages/share/example/ios/Runner/AppDelegate.h index 31fc381e7066..0681d288bb70 100644 --- a/packages/share/example/ios/Runner/AppDelegate.h +++ b/packages/share/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/example/ios/Runner/AppDelegate.m b/packages/share/example/ios/Runner/AppDelegate.m index abfe2106b092..b790a0a52635 100644 --- a/packages/share/example/ios/Runner/AppDelegate.m +++ b/packages/share/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/example/ios/Runner/main.m b/packages/share/example/ios/Runner/main.m index f451b14cb751..f97b9ef5c8a1 100644 --- a/packages/share/example/ios/Runner/main.m +++ b/packages/share/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/example/ios/RunnerUITests/FLTShareExampleUITests.m b/packages/share/example/ios/RunnerUITests/FLTShareExampleUITests.m index 05966fb439f1..c099cb946b92 100644 --- a/packages/share/example/ios/RunnerUITests/FLTShareExampleUITests.m +++ b/packages/share/example/ios/RunnerUITests/FLTShareExampleUITests.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/example/lib/image_previews.dart b/packages/share/example/lib/image_previews.dart index 7298ed4348b1..9b5b807c77c6 100644 --- a/packages/share/example/lib/image_previews.dart +++ b/packages/share/example/lib/image_previews.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/example/lib/main.dart b/packages/share/example/lib/main.dart index 8d6a78305db9..f802b492df6d 100644 --- a/packages/share/example/lib/main.dart +++ b/packages/share/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/example/test_driver/test/integration_test.dart b/packages/share/example/test_driver/test/integration_test.dart index ac2a0cf5f19b..257b0d3c0930 100644 --- a/packages/share/example/test_driver/test/integration_test.dart +++ b/packages/share/example/test_driver/test/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/integration_test/share_test.dart b/packages/share/integration_test/share_test.dart index 4fdfc220c9cc..54d553bbb5a0 100644 --- a/packages/share/integration_test/share_test.dart +++ b/packages/share/integration_test/share_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/ios/Classes/FLTSharePlugin.h b/packages/share/ios/Classes/FLTSharePlugin.h index b06f1d0be606..8f6a6a538e2a 100644 --- a/packages/share/ios/Classes/FLTSharePlugin.h +++ b/packages/share/ios/Classes/FLTSharePlugin.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/ios/Classes/FLTSharePlugin.m b/packages/share/ios/Classes/FLTSharePlugin.m index 024ede9cb2f3..b8a3a7ffa316 100644 --- a/packages/share/ios/Classes/FLTSharePlugin.m +++ b/packages/share/ios/Classes/FLTSharePlugin.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/lib/share.dart b/packages/share/lib/share.dart index f15566714857..6a3f5a317e31 100644 --- a/packages/share/lib/share.dart +++ b/packages/share/lib/share.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/share/test/share_test.dart b/packages/share/test/share_test.dart index 7e72fc4dc012..d0049cef94ab 100644 --- a/packages/share/test/share_test.dart +++ b/packages/share/test/share_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/LICENSE b/packages/shared_preferences/shared_preferences/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/shared_preferences/shared_preferences/LICENSE +++ b/packages/shared_preferences/shared_preferences/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java index 7955f2f89afb..71ec14e7d06b 100644 --- a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java +++ b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java index 3583f3b73cb7..d41328ee6202 100644 --- a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java +++ b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart index daa2cbba1670..f844d453b743 100644 --- a/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.h b/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.h index 31fc381e7066..0681d288bb70 100644 --- a/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.h +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.m b/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.m index abfe2106b092..b790a0a52635 100644 --- a/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.m +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.swift b/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.swift index f26669f6bd4f..caf998393333 100644 --- a/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.swift +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner/AppDelegate.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner/Runner-Bridging-Header.h b/packages/shared_preferences/shared_preferences/example/ios/Runner/Runner-Bridging-Header.h index 3a69a7befa44..eb7e8ba8052f 100644 --- a/packages/shared_preferences/shared_preferences/example/ios/Runner/Runner-Bridging-Header.h +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner/Runner-Bridging-Header.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/ios/Runner/main.m b/packages/shared_preferences/shared_preferences/example/ios/Runner/main.m index f451b14cb751..f97b9ef5c8a1 100644 --- a/packages/shared_preferences/shared_preferences/example/ios/Runner/main.m +++ b/packages/shared_preferences/shared_preferences/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/lib/main.dart b/packages/shared_preferences/shared_preferences/example/lib/main.dart index a56deb276037..103481a2d295 100644 --- a/packages/shared_preferences/shared_preferences/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/linux/main.cc b/packages/shared_preferences/shared_preferences/example/linux/main.cc index a15afa068a7b..88a5fd45ce1b 100644 --- a/packages/shared_preferences/shared_preferences/example/linux/main.cc +++ b/packages/shared_preferences/shared_preferences/example/linux/main.cc @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/linux/my_application.cc b/packages/shared_preferences/shared_preferences/example/linux/my_application.cc index 3843c07aaf04..9cb411ba475b 100644 --- a/packages/shared_preferences/shared_preferences/example/linux/my_application.cc +++ b/packages/shared_preferences/shared_preferences/example/linux/my_application.cc @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/linux/my_application.h b/packages/shared_preferences/shared_preferences/example/linux/my_application.h index b3d62442a005..6e9f0c3ff665 100644 --- a/packages/shared_preferences/shared_preferences/example/linux/my_application.h +++ b/packages/shared_preferences/shared_preferences/example/linux/my_application.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/macos/Runner/AppDelegate.swift b/packages/shared_preferences/shared_preferences/example/macos/Runner/AppDelegate.swift index ca19fe95f8cf..5cec4c48f620 100644 --- a/packages/shared_preferences/shared_preferences/example/macos/Runner/AppDelegate.swift +++ b/packages/shared_preferences/shared_preferences/example/macos/Runner/AppDelegate.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/macos/Runner/MainFlutterWindow.swift b/packages/shared_preferences/shared_preferences/example/macos/Runner/MainFlutterWindow.swift index 2ce11b78604b..32aaeedceb1f 100644 --- a/packages/shared_preferences/shared_preferences/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/shared_preferences/shared_preferences/example/macos/Runner/MainFlutterWindow.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/test_driver/integration_test.dart b/packages/shared_preferences/shared_preferences/example/test_driver/integration_test.dart index dec1aa55d40e..18ed3cff3ee8 100644 --- a/packages/shared_preferences/shared_preferences/example/test_driver/integration_test.dart +++ b/packages/shared_preferences/shared_preferences/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/web/index.html b/packages/shared_preferences/shared_preferences/example/web/index.html index 27464c33811a..7fb138cc90fa 100644 --- a/packages/shared_preferences/shared_preferences/example/web/index.html +++ b/packages/shared_preferences/shared_preferences/example/web/index.html @@ -1,5 +1,5 @@ - diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.cpp b/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.cpp index b7d078e4d4a5..8e415602cf3b 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.cpp +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.h b/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.h index 9b4ef089621b..8e9c12bbe022 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.h +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/flutter_window.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/main.cpp b/packages/shared_preferences/shared_preferences/example/windows/runner/main.cpp index e74157ed999a..126302b0be18 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/main.cpp +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/main.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.cpp b/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.cpp index ee2e2fd5eae9..1916500e6440 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.cpp +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.h b/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.h index a24c47f2e55f..819ed3ed4995 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.h +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/run_loop.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/utils.cpp b/packages/shared_preferences/shared_preferences/example/windows/runner/utils.cpp index 9eba364025d0..537728149601 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/utils.cpp +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/utils.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/utils.h b/packages/shared_preferences/shared_preferences/example/windows/runner/utils.h index 640587eb23ab..16b3f0794597 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/utils.h +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/utils.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.cpp b/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.cpp index 97628170c2c2..a609a2002bb3 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.cpp +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.h b/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.h index 59b78382b27d..d2a730052223 100644 --- a/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.h +++ b/packages/shared_preferences/shared_preferences/example/windows/runner/win32_window.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/ios/Classes/FLTSharedPreferencesPlugin.h b/packages/shared_preferences/shared_preferences/ios/Classes/FLTSharedPreferencesPlugin.h index d77611fde7b4..d2d04aee3b64 100644 --- a/packages/shared_preferences/shared_preferences/ios/Classes/FLTSharedPreferencesPlugin.h +++ b/packages/shared_preferences/shared_preferences/ios/Classes/FLTSharedPreferencesPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/ios/Classes/FLTSharedPreferencesPlugin.m b/packages/shared_preferences/shared_preferences/ios/Classes/FLTSharedPreferencesPlugin.m index 77d53504b4d3..09308d42d762 100644 --- a/packages/shared_preferences/shared_preferences/ios/Classes/FLTSharedPreferencesPlugin.m +++ b/packages/shared_preferences/shared_preferences/ios/Classes/FLTSharedPreferencesPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart b/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart index 6ed771e87c53..493e38901ddf 100644 --- a/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart +++ b/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart index 412285ed4fd3..878021a03361 100755 --- a/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences/test/shared_preferences_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_linux/LICENSE b/packages/shared_preferences/shared_preferences_linux/LICENSE index 67c7e2c52e46..c6823b81eb84 100644 --- a/packages/shared_preferences/shared_preferences_linux/LICENSE +++ b/packages/shared_preferences/shared_preferences_linux/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart index a8e52ccc3063..ab32552b4918 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_linux/example/lib/main.dart b/packages/shared_preferences/shared_preferences_linux/example/lib/main.dart index 0f6d7fc49f7e..aee71d00d44d 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences_linux/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_linux/example/linux/main.cc b/packages/shared_preferences/shared_preferences_linux/example/linux/main.cc index 612325f29cd7..1507d02825e7 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/linux/main.cc +++ b/packages/shared_preferences/shared_preferences_linux/example/linux/main.cc @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.cc b/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.cc index a8f67ccc9a86..878cd973d997 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.cc +++ b/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.cc @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.h b/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.h index 5d666ca73bec..6e9f0c3ff665 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.h +++ b/packages/shared_preferences/shared_preferences_linux/example/linux/my_application.h @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_linux/example/test_driver/integration_test.dart b/packages/shared_preferences/shared_preferences_linux/example/test_driver/integration_test.dart index dec1aa55d40e..18ed3cff3ee8 100644 --- a/packages/shared_preferences/shared_preferences_linux/example/test_driver/integration_test.dart +++ b/packages/shared_preferences/shared_preferences_linux/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart b/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart index 6252da4668c9..e4fc24e78cff 100644 --- a/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart +++ b/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart b/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart index 98260302b778..11e52dd6037f 100644 --- a/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart +++ b/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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:file/memory.dart'; diff --git a/packages/shared_preferences/shared_preferences_macos/LICENSE b/packages/shared_preferences/shared_preferences_macos/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/shared_preferences/shared_preferences_macos/LICENSE +++ b/packages/shared_preferences/shared_preferences_macos/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/shared_preferences/shared_preferences_macos/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_macos/example/integration_test/shared_preferences_test.dart index 53d3cfdf3bc5..722aee3da50a 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_macos/example/integration_test/shared_preferences_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_macos/example/lib/main.dart b/packages/shared_preferences/shared_preferences_macos/example/lib/main.dart index 388f2389bf5b..fb85c301f623 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences_macos/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_macos/example/macos/Runner/AppDelegate.swift b/packages/shared_preferences/shared_preferences_macos/example/macos/Runner/AppDelegate.swift index ca19fe95f8cf..5cec4c48f620 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/macos/Runner/AppDelegate.swift +++ b/packages/shared_preferences/shared_preferences_macos/example/macos/Runner/AppDelegate.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_macos/example/macos/Runner/MainFlutterWindow.swift b/packages/shared_preferences/shared_preferences_macos/example/macos/Runner/MainFlutterWindow.swift index 2ce11b78604b..32aaeedceb1f 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/shared_preferences/shared_preferences_macos/example/macos/Runner/MainFlutterWindow.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_macos/example/test_driver/integration_test.dart b/packages/shared_preferences/shared_preferences_macos/example/test_driver/integration_test.dart index dec1aa55d40e..18ed3cff3ee8 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/test_driver/integration_test.dart +++ b/packages/shared_preferences/shared_preferences_macos/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_macos/macos/Classes/SharedPreferencesPlugin.swift b/packages/shared_preferences/shared_preferences_macos/macos/Classes/SharedPreferencesPlugin.swift index 19a420d002a4..2cf345cf0b04 100644 --- a/packages/shared_preferences/shared_preferences_macos/macos/Classes/SharedPreferencesPlugin.swift +++ b/packages/shared_preferences/shared_preferences_macos/macos/Classes/SharedPreferencesPlugin.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_platform_interface/LICENSE b/packages/shared_preferences/shared_preferences_platform_interface/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/LICENSE +++ b/packages/shared_preferences/shared_preferences_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/shared_preferences/shared_preferences_platform_interface/lib/method_channel_shared_preferences.dart b/packages/shared_preferences/shared_preferences_platform_interface/lib/method_channel_shared_preferences.dart index 47004b198175..fa1bdc097b8d 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/lib/method_channel_shared_preferences.dart +++ b/packages/shared_preferences/shared_preferences_platform_interface/lib/method_channel_shared_preferences.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_platform_interface.dart b/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_platform_interface.dart index f330b04cd30c..8023c864a399 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_platform_interface.dart +++ b/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_platform_interface/test/method_channel_shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_platform_interface/test/method_channel_shared_preferences_test.dart index 3225090e5b51..3b43062c2be3 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/test/method_channel_shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_platform_interface/test/method_channel_shared_preferences_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_platform_interface/test/shared_preferences_platform_interface_test.dart b/packages/shared_preferences/shared_preferences_platform_interface/test/shared_preferences_platform_interface_test.dart index a1c4ca9219aa..8efe885c122c 100644 --- a/packages/shared_preferences/shared_preferences_platform_interface/test/shared_preferences_platform_interface_test.dart +++ b/packages/shared_preferences/shared_preferences_platform_interface/test/shared_preferences_platform_interface_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_web/LICENSE b/packages/shared_preferences/shared_preferences_web/LICENSE index b257ce7c224c..c6823b81eb84 100644 --- a/packages/shared_preferences/shared_preferences_web/LICENSE +++ b/packages/shared_preferences/shared_preferences_web/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart b/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart index 7d5292a54db1..9cff1d448896 100644 --- a/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart +++ b/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_web/test/shared_preferences_web_test.dart b/packages/shared_preferences/shared_preferences_web/test/shared_preferences_web_test.dart index b1275330e3a7..6e49fb47f755 100644 --- a/packages/shared_preferences/shared_preferences_web/test/shared_preferences_web_test.dart +++ b/packages/shared_preferences/shared_preferences_web/test/shared_preferences_web_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_windows/LICENSE b/packages/shared_preferences/shared_preferences_windows/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/shared_preferences/shared_preferences_windows/LICENSE +++ b/packages/shared_preferences/shared_preferences_windows/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/shared_preferences/shared_preferences_windows/example/LICENSE b/packages/shared_preferences/shared_preferences_windows/example/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/LICENSE +++ b/packages/shared_preferences/shared_preferences_windows/example/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart index 16f17cf71094..6b3e9e76fffd 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart b/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart index 96c2490a60ee..0cdd37394706 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/test_driver/integration_test.dart b/packages/shared_preferences/shared_preferences_windows/example/test_driver/integration_test.dart index f41cb47e07a2..18ed3cff3ee8 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/test_driver/integration_test.dart +++ b/packages/shared_preferences/shared_preferences_windows/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.cpp b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.cpp index b7d078e4d4a5..8e415602cf3b 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.cpp +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.h b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.h index 9b4ef089621b..8e9c12bbe022 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.h +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/flutter_window.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/main.cpp b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/main.cpp index e74157ed999a..126302b0be18 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/main.cpp +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/main.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.cpp b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.cpp index ee2e2fd5eae9..1916500e6440 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.cpp +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.h b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.h index a24c47f2e55f..819ed3ed4995 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.h +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/run_loop.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.cpp b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.cpp index 9eba364025d0..537728149601 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.cpp +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.h b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.h index 640587eb23ab..16b3f0794597 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.h +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/utils.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.cpp b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.cpp index 97628170c2c2..a609a2002bb3 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.cpp +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.h b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.h index 59b78382b27d..d2a730052223 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.h +++ b/packages/shared_preferences/shared_preferences_windows/example/windows/runner/win32_window.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart index 04efce9946d4..8bbda6ec139a 100644 --- a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart +++ b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart b/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart index a78dce207c09..e577b9f76e48 100644 --- a/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart +++ b/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/LICENSE b/packages/url_launcher/url_launcher/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/url_launcher/url_launcher/LICENSE +++ b/packages/url_launcher/url_launcher/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/MethodCallHandlerImpl.java b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/MethodCallHandlerImpl.java index 7b858fbafdb3..9e798abcdbb5 100644 --- a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/MethodCallHandlerImpl.java +++ b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/MethodCallHandlerImpl.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java index b6446458322b..07f7ef3ee7dc 100644 --- a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java +++ b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncher.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java index cafc7a65c04b..3c9db478e14b 100644 --- a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java +++ b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java index 53b2e8a44479..7f26c18740ec 100644 --- a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java +++ b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/android/src/test/java/io/flutter/plugins/urllauncher/MethodCallHandlerImplTest.java b/packages/url_launcher/url_launcher/android/src/test/java/io/flutter/plugins/urllauncher/MethodCallHandlerImplTest.java index 0055659c5fc0..5e0811399ac6 100644 --- a/packages/url_launcher/url_launcher/android/src/test/java/io/flutter/plugins/urllauncher/MethodCallHandlerImplTest.java +++ b/packages/url_launcher/url_launcher/android/src/test/java/io/flutter/plugins/urllauncher/MethodCallHandlerImplTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/EmbeddingV1ActivityTest.java b/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/EmbeddingV1ActivityTest.java index 9002012ce18c..4fb52708b9eb 100644 --- a/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/EmbeddingV1ActivityTest.java +++ b/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/MainActivityTest.java b/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/MainActivityTest.java index 7760741b2127..9e343b82a193 100644 --- a/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/MainActivityTest.java +++ b/packages/url_launcher/url_launcher/example/android/app/src/androidTestDebug/java/io/flutter/plugins/urllauncherexample/MainActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/android/app/src/main/java/io/flutter/plugins/urllauncherexample/EmbeddingV1Activity.java b/packages/url_launcher/url_launcher/example/android/app/src/main/java/io/flutter/plugins/urllauncherexample/EmbeddingV1Activity.java index a005c452d426..969b4713dc16 100644 --- a/packages/url_launcher/url_launcher/example/android/app/src/main/java/io/flutter/plugins/urllauncherexample/EmbeddingV1Activity.java +++ b/packages/url_launcher/url_launcher/example/android/app/src/main/java/io/flutter/plugins/urllauncherexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher/example/integration_test/url_launcher_test.dart index 62343c6dc689..933a3c0ed851 100644 --- a/packages/url_launcher/url_launcher/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher/example/integration_test/url_launcher_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/ios/Runner/AppDelegate.h b/packages/url_launcher/url_launcher/example/ios/Runner/AppDelegate.h index 31fc381e7066..0681d288bb70 100644 --- a/packages/url_launcher/url_launcher/example/ios/Runner/AppDelegate.h +++ b/packages/url_launcher/url_launcher/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/ios/Runner/AppDelegate.m b/packages/url_launcher/url_launcher/example/ios/Runner/AppDelegate.m index 07cf6cb9b49f..83f0621aceba 100644 --- a/packages/url_launcher/url_launcher/example/ios/Runner/AppDelegate.m +++ b/packages/url_launcher/url_launcher/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/ios/Runner/main.m b/packages/url_launcher/url_launcher/example/ios/Runner/main.m index f451b14cb751..f97b9ef5c8a1 100644 --- a/packages/url_launcher/url_launcher/example/ios/Runner/main.m +++ b/packages/url_launcher/url_launcher/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/lib/main.dart b/packages/url_launcher/url_launcher/example/lib/main.dart index 8af62ed7859e..7faf2a895c98 100644 --- a/packages/url_launcher/url_launcher/example/lib/main.dart +++ b/packages/url_launcher/url_launcher/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/linux/main.cc b/packages/url_launcher/url_launcher/example/linux/main.cc index 612325f29cd7..1507d02825e7 100644 --- a/packages/url_launcher/url_launcher/example/linux/main.cc +++ b/packages/url_launcher/url_launcher/example/linux/main.cc @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/linux/my_application.cc b/packages/url_launcher/url_launcher/example/linux/my_application.cc index 1a873cdf7b19..878cd973d997 100644 --- a/packages/url_launcher/url_launcher/example/linux/my_application.cc +++ b/packages/url_launcher/url_launcher/example/linux/my_application.cc @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/linux/my_application.h b/packages/url_launcher/url_launcher/example/linux/my_application.h index b3d62442a005..6e9f0c3ff665 100644 --- a/packages/url_launcher/url_launcher/example/linux/my_application.h +++ b/packages/url_launcher/url_launcher/example/linux/my_application.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/macos/Runner/AppDelegate.swift b/packages/url_launcher/url_launcher/example/macos/Runner/AppDelegate.swift index ca19fe95f8cf..5cec4c48f620 100644 --- a/packages/url_launcher/url_launcher/example/macos/Runner/AppDelegate.swift +++ b/packages/url_launcher/url_launcher/example/macos/Runner/AppDelegate.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/macos/Runner/MainFlutterWindow.swift b/packages/url_launcher/url_launcher/example/macos/Runner/MainFlutterWindow.swift index 2ce11b78604b..32aaeedceb1f 100644 --- a/packages/url_launcher/url_launcher/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/url_launcher/url_launcher/example/macos/Runner/MainFlutterWindow.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/test_driver/integration_test.dart b/packages/url_launcher/url_launcher/example/test_driver/integration_test.dart index f044c8de676e..053e985a78ce 100644 --- a/packages/url_launcher/url_launcher/example/test_driver/integration_test.dart +++ b/packages/url_launcher/url_launcher/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/web/index.html b/packages/url_launcher/url_launcher/example/web/index.html index 1127c04820dd..c3d22621fc4f 100644 --- a/packages/url_launcher/url_launcher/example/web/index.html +++ b/packages/url_launcher/url_launcher/example/web/index.html @@ -1,5 +1,5 @@ - diff --git a/packages/url_launcher/url_launcher/example/windows/runner/flutter_window.cpp b/packages/url_launcher/url_launcher/example/windows/runner/flutter_window.cpp index b7d078e4d4a5..8e415602cf3b 100644 --- a/packages/url_launcher/url_launcher/example/windows/runner/flutter_window.cpp +++ b/packages/url_launcher/url_launcher/example/windows/runner/flutter_window.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/windows/runner/flutter_window.h b/packages/url_launcher/url_launcher/example/windows/runner/flutter_window.h index 9b4ef089621b..8e9c12bbe022 100644 --- a/packages/url_launcher/url_launcher/example/windows/runner/flutter_window.h +++ b/packages/url_launcher/url_launcher/example/windows/runner/flutter_window.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/windows/runner/main.cpp b/packages/url_launcher/url_launcher/example/windows/runner/main.cpp index e74157ed999a..126302b0be18 100644 --- a/packages/url_launcher/url_launcher/example/windows/runner/main.cpp +++ b/packages/url_launcher/url_launcher/example/windows/runner/main.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/windows/runner/run_loop.cpp b/packages/url_launcher/url_launcher/example/windows/runner/run_loop.cpp index ee2e2fd5eae9..1916500e6440 100644 --- a/packages/url_launcher/url_launcher/example/windows/runner/run_loop.cpp +++ b/packages/url_launcher/url_launcher/example/windows/runner/run_loop.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/windows/runner/run_loop.h b/packages/url_launcher/url_launcher/example/windows/runner/run_loop.h index a24c47f2e55f..819ed3ed4995 100644 --- a/packages/url_launcher/url_launcher/example/windows/runner/run_loop.h +++ b/packages/url_launcher/url_launcher/example/windows/runner/run_loop.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/windows/runner/utils.cpp b/packages/url_launcher/url_launcher/example/windows/runner/utils.cpp index 9eba364025d0..537728149601 100644 --- a/packages/url_launcher/url_launcher/example/windows/runner/utils.cpp +++ b/packages/url_launcher/url_launcher/example/windows/runner/utils.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/windows/runner/utils.h b/packages/url_launcher/url_launcher/example/windows/runner/utils.h index 640587eb23ab..16b3f0794597 100644 --- a/packages/url_launcher/url_launcher/example/windows/runner/utils.h +++ b/packages/url_launcher/url_launcher/example/windows/runner/utils.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/windows/runner/win32_window.cpp b/packages/url_launcher/url_launcher/example/windows/runner/win32_window.cpp index 97628170c2c2..a609a2002bb3 100644 --- a/packages/url_launcher/url_launcher/example/windows/runner/win32_window.cpp +++ b/packages/url_launcher/url_launcher/example/windows/runner/win32_window.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/example/windows/runner/win32_window.h b/packages/url_launcher/url_launcher/example/windows/runner/win32_window.h index 59b78382b27d..d2a730052223 100644 --- a/packages/url_launcher/url_launcher/example/windows/runner/win32_window.h +++ b/packages/url_launcher/url_launcher/example/windows/runner/win32_window.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.h b/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.h index 35eade666e15..73589d2a0b7d 100644 --- a/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.h +++ b/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.m b/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.m index bbcfdfdc949c..6fbc3a522f36 100644 --- a/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.m +++ b/packages/url_launcher/url_launcher/ios/Classes/FLTURLLauncherPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/lib/link.dart b/packages/url_launcher/url_launcher/lib/link.dart index cdcc2ee1a016..12a213b62761 100644 --- a/packages/url_launcher/url_launcher/lib/link.dart +++ b/packages/url_launcher/url_launcher/lib/link.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/lib/src/link.dart b/packages/url_launcher/url_launcher/lib/src/link.dart index e614c2200b02..259ac8dd1c66 100644 --- a/packages/url_launcher/url_launcher/lib/src/link.dart +++ b/packages/url_launcher/url_launcher/lib/src/link.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/lib/url_launcher.dart b/packages/url_launcher/url_launcher/lib/url_launcher.dart index 1a3ac40ce5e2..b59c91d02a1a 100644 --- a/packages/url_launcher/url_launcher/lib/url_launcher.dart +++ b/packages/url_launcher/url_launcher/lib/url_launcher.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/test/link_test.dart b/packages/url_launcher/url_launcher/test/link_test.dart index 02678a3559dd..833797409c8a 100644 --- a/packages/url_launcher/url_launcher/test/link_test.dart +++ b/packages/url_launcher/url_launcher/test/link_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/test/mock_url_launcher_platform.dart b/packages/url_launcher/url_launcher/test/mock_url_launcher_platform.dart index 6d862844e1d0..789c1435df80 100644 --- a/packages/url_launcher/url_launcher/test/mock_url_launcher_platform.dart +++ b/packages/url_launcher/url_launcher/test/mock_url_launcher_platform.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher/test/url_launcher_test.dart b/packages/url_launcher/url_launcher/test/url_launcher_test.dart index 89eb259e2fa9..9b2d167483cd 100644 --- a/packages/url_launcher/url_launcher/test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher/test/url_launcher_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_linux/LICENSE b/packages/url_launcher/url_launcher_linux/LICENSE index 67c7e2c52e46..c6823b81eb84 100644 --- a/packages/url_launcher/url_launcher_linux/LICENSE +++ b/packages/url_launcher/url_launcher_linux/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/url_launcher/url_launcher_linux/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_linux/example/integration_test/url_launcher_test.dart index b14cc943c90d..7cc90885129b 100644 --- a/packages/url_launcher/url_launcher_linux/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_linux/example/integration_test/url_launcher_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_linux/example/lib/main.dart b/packages/url_launcher/url_launcher_linux/example/lib/main.dart index e6e027b4a6ba..86e06f3fafed 100644 --- a/packages/url_launcher/url_launcher_linux/example/lib/main.dart +++ b/packages/url_launcher/url_launcher_linux/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_linux/example/linux/main.cc b/packages/url_launcher/url_launcher_linux/example/linux/main.cc index 612325f29cd7..1507d02825e7 100644 --- a/packages/url_launcher/url_launcher_linux/example/linux/main.cc +++ b/packages/url_launcher/url_launcher_linux/example/linux/main.cc @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_linux/example/linux/my_application.cc b/packages/url_launcher/url_launcher_linux/example/linux/my_application.cc index 1a873cdf7b19..878cd973d997 100644 --- a/packages/url_launcher/url_launcher_linux/example/linux/my_application.cc +++ b/packages/url_launcher/url_launcher_linux/example/linux/my_application.cc @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_linux/example/linux/my_application.h b/packages/url_launcher/url_launcher_linux/example/linux/my_application.h index b3d62442a005..6e9f0c3ff665 100644 --- a/packages/url_launcher/url_launcher_linux/example/linux/my_application.h +++ b/packages/url_launcher/url_launcher_linux/example/linux/my_application.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_linux/example/test_driver/integration_test.dart b/packages/url_launcher/url_launcher_linux/example/test_driver/integration_test.dart index ac2a0cf5f19b..257b0d3c0930 100644 --- a/packages/url_launcher/url_launcher_linux/example/test_driver/integration_test.dart +++ b/packages/url_launcher/url_launcher_linux/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_linux/linux/include/url_launcher_linux/url_launcher_plugin.h b/packages/url_launcher/url_launcher_linux/linux/include/url_launcher_linux/url_launcher_plugin.h index 399bde268919..f4d19395e37f 100644 --- a/packages/url_launcher/url_launcher_linux/linux/include/url_launcher_linux/url_launcher_plugin.h +++ b/packages/url_launcher/url_launcher_linux/linux/include/url_launcher_linux/url_launcher_plugin.h @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_linux/linux/url_launcher_plugin.cc b/packages/url_launcher/url_launcher_linux/linux/url_launcher_plugin.cc index 17431d1c2f81..6e10607dd14e 100644 --- a/packages/url_launcher/url_launcher_linux/linux/url_launcher_plugin.cc +++ b/packages/url_launcher/url_launcher_linux/linux/url_launcher_plugin.cc @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_macos/LICENSE b/packages/url_launcher/url_launcher_macos/LICENSE index b257ce7c224c..c6823b81eb84 100644 --- a/packages/url_launcher/url_launcher_macos/LICENSE +++ b/packages/url_launcher/url_launcher_macos/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/url_launcher/url_launcher_macos/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_macos/example/integration_test/url_launcher_test.dart index ade3da82700d..6d31d6ea0aa3 100644 --- a/packages/url_launcher/url_launcher_macos/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_macos/example/integration_test/url_launcher_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_macos/example/lib/main.dart b/packages/url_launcher/url_launcher_macos/example/lib/main.dart index e6e027b4a6ba..86e06f3fafed 100644 --- a/packages/url_launcher/url_launcher_macos/example/lib/main.dart +++ b/packages/url_launcher/url_launcher_macos/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_macos/example/macos/Runner/AppDelegate.swift b/packages/url_launcher/url_launcher_macos/example/macos/Runner/AppDelegate.swift index ca19fe95f8cf..5cec4c48f620 100644 --- a/packages/url_launcher/url_launcher_macos/example/macos/Runner/AppDelegate.swift +++ b/packages/url_launcher/url_launcher_macos/example/macos/Runner/AppDelegate.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_macos/example/macos/Runner/MainFlutterWindow.swift b/packages/url_launcher/url_launcher_macos/example/macos/Runner/MainFlutterWindow.swift index 2ce11b78604b..32aaeedceb1f 100644 --- a/packages/url_launcher/url_launcher_macos/example/macos/Runner/MainFlutterWindow.swift +++ b/packages/url_launcher/url_launcher_macos/example/macos/Runner/MainFlutterWindow.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_macos/example/test_driver/integration_test.dart b/packages/url_launcher/url_launcher_macos/example/test_driver/integration_test.dart index ac2a0cf5f19b..257b0d3c0930 100644 --- a/packages/url_launcher/url_launcher_macos/example/test_driver/integration_test.dart +++ b/packages/url_launcher/url_launcher_macos/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_macos/macos/Classes/UrlLauncherPlugin.swift b/packages/url_launcher/url_launcher_macos/macos/Classes/UrlLauncherPlugin.swift index 46df87a34304..ab89038fa01d 100644 --- a/packages/url_launcher/url_launcher_macos/macos/Classes/UrlLauncherPlugin.swift +++ b/packages/url_launcher/url_launcher_macos/macos/Classes/UrlLauncherPlugin.swift @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_platform_interface/LICENSE b/packages/url_launcher/url_launcher_platform_interface/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/url_launcher/url_launcher_platform_interface/LICENSE +++ b/packages/url_launcher/url_launcher_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/url_launcher/url_launcher_platform_interface/lib/link.dart b/packages/url_launcher/url_launcher_platform_interface/lib/link.dart index 6c1a13b604a8..9784a3d9ec79 100644 --- a/packages/url_launcher/url_launcher_platform_interface/lib/link.dart +++ b/packages/url_launcher/url_launcher_platform_interface/lib/link.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_platform_interface/lib/method_channel_url_launcher.dart b/packages/url_launcher/url_launcher_platform_interface/lib/method_channel_url_launcher.dart index 93fdaff7ea1b..e75e283eeca7 100644 --- a/packages/url_launcher/url_launcher_platform_interface/lib/method_channel_url_launcher.dart +++ b/packages/url_launcher/url_launcher_platform_interface/lib/method_channel_url_launcher.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_platform_interface/lib/url_launcher_platform_interface.dart b/packages/url_launcher/url_launcher_platform_interface/lib/url_launcher_platform_interface.dart index d34ce7512afb..e9435b8dc4e3 100644 --- a/packages/url_launcher/url_launcher_platform_interface/lib/url_launcher_platform_interface.dart +++ b/packages/url_launcher/url_launcher_platform_interface/lib/url_launcher_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_platform_interface/test/link_test.dart b/packages/url_launcher/url_launcher_platform_interface/test/link_test.dart index e60cc25f25fe..638a65547dc4 100644 --- a/packages/url_launcher/url_launcher_platform_interface/test/link_test.dart +++ b/packages/url_launcher/url_launcher_platform_interface/test/link_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_platform_interface/test/method_channel_url_launcher_test.dart b/packages/url_launcher/url_launcher_platform_interface/test/method_channel_url_launcher_test.dart index 3e450e83e41b..5bfc78c5c5a2 100644 --- a/packages/url_launcher/url_launcher_platform_interface/test/method_channel_url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_platform_interface/test/method_channel_url_launcher_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_web/LICENSE b/packages/url_launcher/url_launcher_web/LICENSE index b66343316afd..dd4ac737fc37 100644 --- a/packages/url_launcher/url_launcher_web/LICENSE +++ b/packages/url_launcher/url_launcher_web/LICENSE @@ -1,6 +1,6 @@ url_launcher_web -Copyright 2019 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart b/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart index 43bd2234ec84..7bbc889d9d4c 100644 --- a/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart +++ b/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart index f8057d5f4204..0b53a1ffb1dd 100644 --- a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart +++ b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart index 7e72b5ff1da3..5c55ec779c9c 100644 --- a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart +++ b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_web/example/run_test.sh b/packages/url_launcher/url_launcher_web/example/run_test.sh index 5d235967ac3d..1960bde25d17 100755 --- a/packages/url_launcher/url_launcher_web/example/run_test.sh +++ b/packages/url_launcher/url_launcher_web/example/run_test.sh @@ -1,5 +1,5 @@ #!/usr/bin/bash -# Copyright 2017 The Flutter Authors. All rights reserved. +# Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_web/example/test_driver/integration_test_driver.dart b/packages/url_launcher/url_launcher_web/example/test_driver/integration_test_driver.dart index 0dd5f694f16b..f26b6a310cfe 100644 --- a/packages/url_launcher/url_launcher_web/example/test_driver/integration_test_driver.dart +++ b/packages/url_launcher/url_launcher_web/example/test_driver/integration_test_driver.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_web/example/web/index.html b/packages/url_launcher/url_launcher_web/example/web/index.html index dc8d0cfe0428..dc9f89762aec 100644 --- a/packages/url_launcher/url_launcher_web/example/web/index.html +++ b/packages/url_launcher/url_launcher_web/example/web/index.html @@ -1,5 +1,5 @@ - diff --git a/packages/url_launcher/url_launcher_web/lib/src/link.dart b/packages/url_launcher/url_launcher_web/lib/src/link.dart index a39dbd4edf58..fcbbaaec4e56 100644 --- a/packages/url_launcher/url_launcher_web/lib/src/link.dart +++ b/packages/url_launcher/url_launcher_web/lib/src/link.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui.dart b/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui.dart index ec93f431138b..5eacec5fe867 100644 --- a/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui.dart +++ b/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui_fake.dart b/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui_fake.dart index 2a8c7f5f5c6e..f2862af8b704 100644 --- a/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui_fake.dart +++ b/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui_fake.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui_real.dart b/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui_real.dart index b6c2f8812a1b..276b768c76c5 100644 --- a/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui_real.dart +++ b/packages/url_launcher/url_launcher_web/lib/src/shims/dart_ui_real.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart b/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart index a2a1f2a9d863..9249837bd46b 100644 --- a/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart +++ b/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart b/packages/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart index 64d8e547e485..442c50144727 100644 --- a/packages/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart +++ b/packages/url_launcher/url_launcher_web/test/tests_exist_elsewhere_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_windows/LICENSE b/packages/url_launcher/url_launcher_windows/LICENSE index b257ce7c224c..c6823b81eb84 100644 --- a/packages/url_launcher/url_launcher_windows/LICENSE +++ b/packages/url_launcher/url_launcher_windows/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/url_launcher/url_launcher_windows/example/integration_test/url_launcher_test.dart b/packages/url_launcher/url_launcher_windows/example/integration_test/url_launcher_test.dart index b14cc943c90d..7cc90885129b 100644 --- a/packages/url_launcher/url_launcher_windows/example/integration_test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher_windows/example/integration_test/url_launcher_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_windows/example/lib/main.dart b/packages/url_launcher/url_launcher_windows/example/lib/main.dart index e6e027b4a6ba..86e06f3fafed 100644 --- a/packages/url_launcher/url_launcher_windows/example/lib/main.dart +++ b/packages/url_launcher/url_launcher_windows/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_windows/example/test_driver/integration_test.dart b/packages/url_launcher/url_launcher_windows/example/test_driver/integration_test.dart index ac2a0cf5f19b..257b0d3c0930 100644 --- a/packages/url_launcher/url_launcher_windows/example/test_driver/integration_test.dart +++ b/packages/url_launcher/url_launcher_windows/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_windows/example/windows/runner/flutter_window.cpp b/packages/url_launcher/url_launcher_windows/example/windows/runner/flutter_window.cpp index b7d078e4d4a5..8e415602cf3b 100644 --- a/packages/url_launcher/url_launcher_windows/example/windows/runner/flutter_window.cpp +++ b/packages/url_launcher/url_launcher_windows/example/windows/runner/flutter_window.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_windows/example/windows/runner/flutter_window.h b/packages/url_launcher/url_launcher_windows/example/windows/runner/flutter_window.h index 9b4ef089621b..8e9c12bbe022 100644 --- a/packages/url_launcher/url_launcher_windows/example/windows/runner/flutter_window.h +++ b/packages/url_launcher/url_launcher_windows/example/windows/runner/flutter_window.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_windows/example/windows/runner/main.cpp b/packages/url_launcher/url_launcher_windows/example/windows/runner/main.cpp index e74157ed999a..126302b0be18 100644 --- a/packages/url_launcher/url_launcher_windows/example/windows/runner/main.cpp +++ b/packages/url_launcher/url_launcher_windows/example/windows/runner/main.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_windows/example/windows/runner/run_loop.cpp b/packages/url_launcher/url_launcher_windows/example/windows/runner/run_loop.cpp index ee2e2fd5eae9..1916500e6440 100644 --- a/packages/url_launcher/url_launcher_windows/example/windows/runner/run_loop.cpp +++ b/packages/url_launcher/url_launcher_windows/example/windows/runner/run_loop.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_windows/example/windows/runner/run_loop.h b/packages/url_launcher/url_launcher_windows/example/windows/runner/run_loop.h index a24c47f2e55f..819ed3ed4995 100644 --- a/packages/url_launcher/url_launcher_windows/example/windows/runner/run_loop.h +++ b/packages/url_launcher/url_launcher_windows/example/windows/runner/run_loop.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_windows/example/windows/runner/utils.cpp b/packages/url_launcher/url_launcher_windows/example/windows/runner/utils.cpp index 9eba364025d0..537728149601 100644 --- a/packages/url_launcher/url_launcher_windows/example/windows/runner/utils.cpp +++ b/packages/url_launcher/url_launcher_windows/example/windows/runner/utils.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_windows/example/windows/runner/utils.h b/packages/url_launcher/url_launcher_windows/example/windows/runner/utils.h index 640587eb23ab..16b3f0794597 100644 --- a/packages/url_launcher/url_launcher_windows/example/windows/runner/utils.h +++ b/packages/url_launcher/url_launcher_windows/example/windows/runner/utils.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_windows/example/windows/runner/win32_window.cpp b/packages/url_launcher/url_launcher_windows/example/windows/runner/win32_window.cpp index 97628170c2c2..a609a2002bb3 100644 --- a/packages/url_launcher/url_launcher_windows/example/windows/runner/win32_window.cpp +++ b/packages/url_launcher/url_launcher_windows/example/windows/runner/win32_window.cpp @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_windows/example/windows/runner/win32_window.h b/packages/url_launcher/url_launcher_windows/example/windows/runner/win32_window.h index 59b78382b27d..d2a730052223 100644 --- a/packages/url_launcher/url_launcher_windows/example/windows/runner/win32_window.h +++ b/packages/url_launcher/url_launcher_windows/example/windows/runner/win32_window.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/url_launcher/url_launcher_windows/windows/include/url_launcher_windows/url_launcher_plugin.h b/packages/url_launcher/url_launcher_windows/windows/include/url_launcher_windows/url_launcher_plugin.h index 7ffb0f93f271..8af3924ded81 100644 --- a/packages/url_launcher/url_launcher_windows/windows/include/url_launcher_windows/url_launcher_plugin.h +++ b/packages/url_launcher/url_launcher_windows/windows/include/url_launcher_windows/url_launcher_plugin.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. #ifndef PACKAGES_URL_LAUNCHER_URL_LAUNCHER_WINDOWS_WINDOWS_INCLUDE_URL_LAUNCHER_WINDOWS_URL_LAUNCHER_PLUGIN_H_ diff --git a/packages/url_launcher/url_launcher_windows/windows/url_launcher_plugin.cpp b/packages/url_launcher/url_launcher_windows/windows/url_launcher_plugin.cpp index e6a36f76ad77..51740a3a4b04 100644 --- a/packages/url_launcher/url_launcher_windows/windows/url_launcher_plugin.cpp +++ b/packages/url_launcher/url_launcher_windows/windows/url_launcher_plugin.cpp @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. #include "include/url_launcher_windows/url_launcher_plugin.h" diff --git a/packages/video_player/video_player/LICENSE b/packages/video_player/video_player/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/video_player/video_player/LICENSE +++ b/packages/video_player/video_player/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/CustomSSLSocketFactory.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/CustomSSLSocketFactory.java index 0deb06b6fa08..fb6d2d4108cd 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/CustomSSLSocketFactory.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/CustomSSLSocketFactory.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java index c42abff848d5..f1a909534d58 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/QueuingEventSink.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/QueuingEventSink.java index fc1acc3250f9..981389583d2d 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/QueuingEventSink.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/QueuingEventSink.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java index dae24d17ece2..840b1464b4d4 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerOptions.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerOptions.java index 63b1896038c7..85ad892f9e19 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerOptions.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerOptions.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java index 644c0e88c226..2895db2acd6a 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/example/android/app/src/main/java/io/flutter/plugins/videoplayerexample/EmbeddingV1Activity.java b/packages/video_player/video_player/example/android/app/src/main/java/io/flutter/plugins/videoplayerexample/EmbeddingV1Activity.java index 60bebe82d4df..87c39ca07117 100644 --- a/packages/video_player/video_player/example/android/app/src/main/java/io/flutter/plugins/videoplayerexample/EmbeddingV1Activity.java +++ b/packages/video_player/video_player/example/android/app/src/main/java/io/flutter/plugins/videoplayerexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/example/android/app/src/test/java/io/flutter/plugins/videoplayerexample/FlutterActivityTest.java b/packages/video_player/video_player/example/android/app/src/test/java/io/flutter/plugins/videoplayerexample/FlutterActivityTest.java index e62e70cd54ad..434861f4b754 100644 --- a/packages/video_player/video_player/example/android/app/src/test/java/io/flutter/plugins/videoplayerexample/FlutterActivityTest.java +++ b/packages/video_player/video_player/example/android/app/src/test/java/io/flutter/plugins/videoplayerexample/FlutterActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/example/integration_test/video_player_test.dart b/packages/video_player/video_player/example/integration_test/video_player_test.dart index 0566ceeb01c4..f04dad5711a2 100644 --- a/packages/video_player/video_player/example/integration_test/video_player_test.dart +++ b/packages/video_player/video_player/example/integration_test/video_player_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/example/ios/Runner/AppDelegate.h b/packages/video_player/video_player/example/ios/Runner/AppDelegate.h index 31fc381e7066..0681d288bb70 100644 --- a/packages/video_player/video_player/example/ios/Runner/AppDelegate.h +++ b/packages/video_player/video_player/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/example/ios/Runner/AppDelegate.m b/packages/video_player/video_player/example/ios/Runner/AppDelegate.m index 2147d3d605ac..30b87969f44a 100644 --- a/packages/video_player/video_player/example/ios/Runner/AppDelegate.m +++ b/packages/video_player/video_player/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/example/ios/Runner/main.m b/packages/video_player/video_player/example/ios/Runner/main.m index f451b14cb751..f97b9ef5c8a1 100644 --- a/packages/video_player/video_player/example/ios/Runner/main.m +++ b/packages/video_player/video_player/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/example/lib/main.dart b/packages/video_player/video_player/example/lib/main.dart index 8ab4ff12216c..eef23197ef50 100644 --- a/packages/video_player/video_player/example/lib/main.dart +++ b/packages/video_player/video_player/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/example/test_driver/integration_test.dart b/packages/video_player/video_player/example/test_driver/integration_test.dart index 2a2476ac7a1a..6a3ccada0232 100644 --- a/packages/video_player/video_player/example/test_driver/integration_test.dart +++ b/packages/video_player/video_player/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/example/test_driver/video_player.dart b/packages/video_player/video_player/example/test_driver/video_player.dart index 317632834566..824b59922ca3 100644 --- a/packages/video_player/video_player/example/test_driver/video_player.dart +++ b/packages/video_player/video_player/example/test_driver/video_player.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/example/test_driver/video_player_test.dart b/packages/video_player/video_player/example/test_driver/video_player_test.dart index 63e53f0b69e9..ddb088a6dac3 100644 --- a/packages/video_player/video_player/example/test_driver/video_player_test.dart +++ b/packages/video_player/video_player/example/test_driver/video_player_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/example/web/index.html b/packages/video_player/video_player/example/web/index.html index 763ea662e8e3..0df50f1192dc 100644 --- a/packages/video_player/video_player/example/web/index.html +++ b/packages/video_player/video_player/example/web/index.html @@ -1,5 +1,5 @@ - diff --git a/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.h b/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.h index 80f07014954e..6c9d91468d6b 100644 --- a/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.h +++ b/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m b/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m index ed1623f4f575..83144a9cb378 100644 --- a/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m +++ b/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/ios/Classes/messages.h b/packages/video_player/video_player/ios/Classes/messages.h index ab54e8d8048f..9717f65b23c3 100644 --- a/packages/video_player/video_player/ios/Classes/messages.h +++ b/packages/video_player/video_player/ios/Classes/messages.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/ios/Classes/messages.m b/packages/video_player/video_player/ios/Classes/messages.m index 78174d43a153..0993c947c2cb 100644 --- a/packages/video_player/video_player/ios/Classes/messages.m +++ b/packages/video_player/video_player/ios/Classes/messages.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/lib/src/closed_caption_file.dart b/packages/video_player/video_player/lib/src/closed_caption_file.dart index 1542746e08b1..3c7d69b89598 100644 --- a/packages/video_player/video_player/lib/src/closed_caption_file.dart +++ b/packages/video_player/video_player/lib/src/closed_caption_file.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/lib/src/sub_rip.dart b/packages/video_player/video_player/lib/src/sub_rip.dart index 89c1d5f78b01..73cd8266c2e9 100644 --- a/packages/video_player/video_player/lib/src/sub_rip.dart +++ b/packages/video_player/video_player/lib/src/sub_rip.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/lib/video_player.dart b/packages/video_player/video_player/lib/video_player.dart index 4d3e4fa2dcbc..08bd1d499c36 100644 --- a/packages/video_player/video_player/lib/video_player.dart +++ b/packages/video_player/video_player/lib/video_player.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/pigeons/messages.dart b/packages/video_player/video_player/pigeons/messages.dart index 43bcf4d6a3c2..c0a76dd301af 100644 --- a/packages/video_player/video_player/pigeons/messages.dart +++ b/packages/video_player/video_player/pigeons/messages.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/test/closed_caption_file_test.dart b/packages/video_player/video_player/test/closed_caption_file_test.dart index 9b5ca8a11b22..369a3b362557 100644 --- a/packages/video_player/video_player/test/closed_caption_file_test.dart +++ b/packages/video_player/video_player/test/closed_caption_file_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/test/sub_rip_file_test.dart b/packages/video_player/video_player/test/sub_rip_file_test.dart index 5f696fa0d351..5808e0b9d2e3 100644 --- a/packages/video_player/video_player/test/sub_rip_file_test.dart +++ b/packages/video_player/video_player/test/sub_rip_file_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/test/video_player_initialization_test.dart b/packages/video_player/video_player/test/video_player_initialization_test.dart index 64bbb99d09b8..74973294d13a 100644 --- a/packages/video_player/video_player/test/video_player_initialization_test.dart +++ b/packages/video_player/video_player/test/video_player_initialization_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player/test/video_player_test.dart b/packages/video_player/video_player/test/video_player_test.dart index bdb9dc9ec432..580c9ad914dd 100644 --- a/packages/video_player/video_player/test/video_player_test.dart +++ b/packages/video_player/video_player/test/video_player_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player_platform_interface/LICENSE b/packages/video_player/video_player_platform_interface/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/video_player/video_player_platform_interface/LICENSE +++ b/packages/video_player/video_player_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/video_player/video_player_platform_interface/lib/messages.dart b/packages/video_player/video_player_platform_interface/lib/messages.dart index 83e34ee33eb8..2b7d8821a0cc 100644 --- a/packages/video_player/video_player_platform_interface/lib/messages.dart +++ b/packages/video_player/video_player_platform_interface/lib/messages.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart b/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart index 9a37d6084c0a..bd9708a117be 100644 --- a/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart +++ b/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player_platform_interface/lib/test.dart b/packages/video_player/video_player_platform_interface/lib/test.dart index fd23a61a0365..b4fd81f44f41 100644 --- a/packages/video_player/video_player_platform_interface/lib/test.dart +++ b/packages/video_player/video_player_platform_interface/lib/test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart index bf30ecc6fc93..1960253af193 100644 --- a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart +++ b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart b/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart index 7a5192d861c0..00ec64305a31 100644 --- a/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart +++ b/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player_web/LICENSE b/packages/video_player/video_player_web/LICENSE index bb6f2c07756f..c6823b81eb84 100644 --- a/packages/video_player/video_player_web/LICENSE +++ b/packages/video_player/video_player_web/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/video_player/video_player_web/lib/src/shims/dart_ui.dart b/packages/video_player/video_player_web/lib/src/shims/dart_ui.dart index ec93f431138b..5eacec5fe867 100644 --- a/packages/video_player/video_player_web/lib/src/shims/dart_ui.dart +++ b/packages/video_player/video_player_web/lib/src/shims/dart_ui.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player_web/lib/src/shims/dart_ui_fake.dart b/packages/video_player/video_player_web/lib/src/shims/dart_ui_fake.dart index 2a8c7f5f5c6e..f2862af8b704 100644 --- a/packages/video_player/video_player_web/lib/src/shims/dart_ui_fake.dart +++ b/packages/video_player/video_player_web/lib/src/shims/dart_ui_fake.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player_web/lib/src/shims/dart_ui_real.dart b/packages/video_player/video_player_web/lib/src/shims/dart_ui_real.dart index b6c2f8812a1b..276b768c76c5 100644 --- a/packages/video_player/video_player_web/lib/src/shims/dart_ui_real.dart +++ b/packages/video_player/video_player_web/lib/src/shims/dart_ui_real.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player_web/lib/video_player_web.dart b/packages/video_player/video_player_web/lib/video_player_web.dart index 6c99e24c4feb..a61e01071b0f 100644 --- a/packages/video_player/video_player_web/lib/video_player_web.dart +++ b/packages/video_player/video_player_web/lib/video_player_web.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/video_player/video_player_web/test/video_player_web_test.dart b/packages/video_player/video_player_web/test/video_player_web_test.dart index 4fdbc7e9d3d6..18272662fccf 100644 --- a/packages/video_player/video_player_web/test/video_player_web_test.dart +++ b/packages/video_player/video_player_web/test/video_player_web_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/LICENSE b/packages/webview_flutter/LICENSE index 050e2c7cac4f..c6823b81eb84 100644 --- a/packages/webview_flutter/LICENSE +++ b/packages/webview_flutter/LICENSE @@ -1,4 +1,4 @@ -Copyright 2018 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/DisplayListenerProxy.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/DisplayListenerProxy.java index 2d66da8fc918..31e3fe08c057 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/DisplayListenerProxy.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/DisplayListenerProxy.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterCookieManager.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterCookieManager.java index 456d07c2d214..df3f21daadeb 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterCookieManager.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterCookieManager.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index f170e7267c56..ebc7c31987f4 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java index 30bbeafd1b68..148be952db6e 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/InputAwareWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/InputAwareWebView.java index 51758d05c57a..51b2a3809fff 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/InputAwareWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/InputAwareWebView.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/JavaScriptChannel.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/JavaScriptChannel.java index 4b39d3bb83ef..4d596351b3d0 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/JavaScriptChannel.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/JavaScriptChannel.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/ThreadedInputConnectionProxyAdapterView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/ThreadedInputConnectionProxyAdapterView.java index 2be6dc1f575c..1c865c9444e2 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/ThreadedInputConnectionProxyAdapterView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/ThreadedInputConnectionProxyAdapterView.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFactory.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFactory.java index 054e68554df4..22de668e0126 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFactory.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFactory.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java index 23926c4577ea..dc329e2273d0 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1ActivityTest.java b/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1ActivityTest.java index aebeb6d0a3b0..56691d2fc82a 100644 --- a/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1ActivityTest.java +++ b/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1ActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/MainActivityTest.java b/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/MainActivityTest.java index e3d794e52dcc..b18308ab2feb 100644 --- a/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/MainActivityTest.java +++ b/packages/webview_flutter/example/android/app/src/androidTestDebug/java/io/flutter/plugins/webviewflutterexample/MainActivityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/example/android/app/src/main/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1Activity.java b/packages/webview_flutter/example/android/app/src/main/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1Activity.java index 8eda066ea776..88c023a35fc8 100644 --- a/packages/webview_flutter/example/android/app/src/main/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1Activity.java +++ b/packages/webview_flutter/example/android/app/src/main/java/io/flutter/plugins/webviewflutterexample/EmbeddingV1Activity.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. 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 37da553b0893..2c7c765f34bf 100644 --- a/packages/webview_flutter/example/integration_test/webview_flutter_test.dart +++ b/packages/webview_flutter/example/integration_test/webview_flutter_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/example/ios/Runner/AppDelegate.h b/packages/webview_flutter/example/ios/Runner/AppDelegate.h index d0578fc417d7..0681d288bb70 100644 --- a/packages/webview_flutter/example/ios/Runner/AppDelegate.h +++ b/packages/webview_flutter/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/example/ios/Runner/AppDelegate.m b/packages/webview_flutter/example/ios/Runner/AppDelegate.m index f6a895ac8dd8..30b87969f44a 100644 --- a/packages/webview_flutter/example/ios/Runner/AppDelegate.m +++ b/packages/webview_flutter/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/example/ios/Runner/main.m b/packages/webview_flutter/example/ios/Runner/main.m index a6d55eceeb0e..f97b9ef5c8a1 100644 --- a/packages/webview_flutter/example/ios/Runner/main.m +++ b/packages/webview_flutter/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/example/lib/main.dart b/packages/webview_flutter/example/lib/main.dart index 5c9e638ee1aa..88256cc66287 100644 --- a/packages/webview_flutter/example/lib/main.dart +++ b/packages/webview_flutter/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/example/test_driver/integration_test.dart b/packages/webview_flutter/example/test_driver/integration_test.dart index ac2a0cf5f19b..257b0d3c0930 100644 --- a/packages/webview_flutter/example/test_driver/integration_test.dart +++ b/packages/webview_flutter/example/test_driver/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/ios/Classes/FLTCookieManager.h b/packages/webview_flutter/ios/Classes/FLTCookieManager.h index 29e028ced59f..8fe331875250 100644 --- a/packages/webview_flutter/ios/Classes/FLTCookieManager.h +++ b/packages/webview_flutter/ios/Classes/FLTCookieManager.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/ios/Classes/FLTCookieManager.m b/packages/webview_flutter/ios/Classes/FLTCookieManager.m index 0a15c7ceb975..f4783ffb4123 100644 --- a/packages/webview_flutter/ios/Classes/FLTCookieManager.m +++ b/packages/webview_flutter/ios/Classes/FLTCookieManager.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.h b/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.h index 3e661ff93b3e..31edadc8cc05 100644 --- a/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.h +++ b/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m b/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m index 85a5decf6e3e..8b7ee7d0cfb7 100644 --- a/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m +++ b/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.h b/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.h index 36ed108bb727..96af4ef6c578 100644 --- a/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.h +++ b/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.m b/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.m index d53f132bea25..b65d557aa427 100644 --- a/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.m +++ b/packages/webview_flutter/ios/Classes/FLTWKProgressionDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.h b/packages/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.h index 109170e9af66..2a80c7d886f2 100644 --- a/packages/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.h +++ b/packages/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.m b/packages/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.m index 3d39d96a6771..9f01416acc6a 100644 --- a/packages/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.m +++ b/packages/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.h b/packages/webview_flutter/ios/Classes/FlutterWebView.h index 555a90837da9..6e795f7d1528 100644 --- a/packages/webview_flutter/ios/Classes/FlutterWebView.h +++ b/packages/webview_flutter/ios/Classes/FlutterWebView.h @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.m b/packages/webview_flutter/ios/Classes/FlutterWebView.m index a1ea10c397f9..7ca36e33031c 100644 --- a/packages/webview_flutter/ios/Classes/FlutterWebView.m +++ b/packages/webview_flutter/ios/Classes/FlutterWebView.m @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/ios/Classes/JavaScriptChannelHandler.h b/packages/webview_flutter/ios/Classes/JavaScriptChannelHandler.h index d3b1261dae94..a0a5ec657295 100644 --- a/packages/webview_flutter/ios/Classes/JavaScriptChannelHandler.h +++ b/packages/webview_flutter/ios/Classes/JavaScriptChannelHandler.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/ios/Classes/JavaScriptChannelHandler.m b/packages/webview_flutter/ios/Classes/JavaScriptChannelHandler.m index 2e9e1b864f34..ec9a363a4b2e 100644 --- a/packages/webview_flutter/ios/Classes/JavaScriptChannelHandler.m +++ b/packages/webview_flutter/ios/Classes/JavaScriptChannelHandler.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/ios/Tests/FLTWKNavigationDelegateTests.m b/packages/webview_flutter/ios/Tests/FLTWKNavigationDelegateTests.m index af6ce0b71450..9d3a2aed64eb 100644 --- a/packages/webview_flutter/ios/Tests/FLTWKNavigationDelegateTests.m +++ b/packages/webview_flutter/ios/Tests/FLTWKNavigationDelegateTests.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/ios/Tests/FLTWebViewTests.m b/packages/webview_flutter/ios/Tests/FLTWebViewTests.m index 9a886d383c22..f8229935cbe6 100644 --- a/packages/webview_flutter/ios/Tests/FLTWebViewTests.m +++ b/packages/webview_flutter/ios/Tests/FLTWebViewTests.m @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/lib/platform_interface.dart b/packages/webview_flutter/lib/platform_interface.dart index 198e07767fc5..92aa87b7480f 100644 --- a/packages/webview_flutter/lib/platform_interface.dart +++ b/packages/webview_flutter/lib/platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/lib/src/webview_android.dart b/packages/webview_flutter/lib/src/webview_android.dart index a8b87fc52616..8850c7977e9c 100644 --- a/packages/webview_flutter/lib/src/webview_android.dart +++ b/packages/webview_flutter/lib/src/webview_android.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/lib/src/webview_cupertino.dart b/packages/webview_flutter/lib/src/webview_cupertino.dart index eb1e75876d4e..8d4be3800a28 100644 --- a/packages/webview_flutter/lib/src/webview_cupertino.dart +++ b/packages/webview_flutter/lib/src/webview_cupertino.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/lib/src/webview_method_channel.dart index bd042130f92a..05831a9d8794 100644 --- a/packages/webview_flutter/lib/src/webview_method_channel.dart +++ b/packages/webview_flutter/lib/src/webview_method_channel.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart index af373d1bcbb7..92ff8e00a50e 100644 --- a/packages/webview_flutter/lib/webview_flutter.dart +++ b/packages/webview_flutter/lib/webview_flutter.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/webview_flutter/test/webview_flutter_test.dart b/packages/webview_flutter/test/webview_flutter_test.dart index afe6664a5957..4360484408b5 100644 --- a/packages/webview_flutter/test/webview_flutter_test.dart +++ b/packages/webview_flutter/test/webview_flutter_test.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/LICENSE b/packages/wifi_info_flutter/wifi_info_flutter/LICENSE index 67c7e2c52e46..c6823b81eb84 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/LICENSE +++ b/packages/wifi_info_flutter/wifi_info_flutter/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java b/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java index 6425b9be2909..bd4c8f10ce3b 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java +++ b/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutter.java @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterMethodChannelHandler.java b/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterMethodChannelHandler.java index 77861fd4b5fa..9ceed5968e63 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterMethodChannelHandler.java +++ b/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterMethodChannelHandler.java @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterPlugin.java b/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterPlugin.java index f1b3c0e181ba..7757688bc9fa 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterPlugin.java +++ b/packages/wifi_info_flutter/wifi_info_flutter/android/src/main/java/io/flutter/plugins/wifi_info_flutter/WifiInfoFlutterPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/android/app/src/main/java/io/flutter/plugins/wifi_info_flutter_example/MainActivity.java b/packages/wifi_info_flutter/wifi_info_flutter/example/android/app/src/main/java/io/flutter/plugins/wifi_info_flutter_example/MainActivity.java index f3747669929d..b52123be65d4 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/android/app/src/main/java/io/flutter/plugins/wifi_info_flutter_example/MainActivity.java +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/android/app/src/main/java/io/flutter/plugins/wifi_info_flutter_example/MainActivity.java @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/AppDelegate.h b/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/AppDelegate.h index 31fc381e7066..0681d288bb70 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/AppDelegate.h +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/AppDelegate.h @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/AppDelegate.m b/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/AppDelegate.m index 558d1adc9a4a..442514aaecbe 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/AppDelegate.m +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/AppDelegate.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/main.m b/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/main.m index f451b14cb751..f97b9ef5c8a1 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/main.m +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Runner/main.m @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/lib/main.dart b/packages/wifi_info_flutter/wifi_info_flutter/example/lib/main.dart index 7e25bc527b2a..8258815b0c09 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/lib/main.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/lib/main.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/integration_test/wifi_info_test.dart b/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/integration_test/wifi_info_test.dart index 98f56d4e5e25..103be52aa56b 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/integration_test/wifi_info_test.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/integration_test/wifi_info_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/test/integration_test.dart b/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/test/integration_test.dart index 8997c9275a06..9647a12d77ce 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/test/integration_test.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/test_driver/test/integration_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/integration_test/wifi_info_test.dart b/packages/wifi_info_flutter/wifi_info_flutter/integration_test/wifi_info_test.dart index 5b6c0ded11cf..e72db0a9f7b0 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/integration_test/wifi_info_test.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/integration_test/wifi_info_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/FLTWifiInfoLocationHandler.h b/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/FLTWifiInfoLocationHandler.h index 05b885c7d2ac..359562b7761c 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/FLTWifiInfoLocationHandler.h +++ b/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/FLTWifiInfoLocationHandler.h @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/FLTWifiInfoLocationHandler.m b/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/FLTWifiInfoLocationHandler.m index 331b6cca2ea8..2fe19c5e70e9 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/FLTWifiInfoLocationHandler.m +++ b/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/FLTWifiInfoLocationHandler.m @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.h b/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.h index 66e3dd18c9b4..41f165717809 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.h +++ b/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.m b/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.m index 1db163a65766..47bd90c4429b 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.m +++ b/packages/wifi_info_flutter/wifi_info_flutter/ios/Classes/WifiInfoFlutterPlugin.m @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/lib/wifi_info_flutter.dart b/packages/wifi_info_flutter/wifi_info_flutter/lib/wifi_info_flutter.dart index c15718bdb82d..1c89ee82fc3e 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/lib/wifi_info_flutter.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/lib/wifi_info_flutter.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter/test/wifi_info_flutter_test.dart b/packages/wifi_info_flutter/wifi_info_flutter/test/wifi_info_flutter_test.dart index c0874d10aa07..93cf378de437 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter/test/wifi_info_flutter_test.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter/test/wifi_info_flutter_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/LICENSE b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/LICENSE index 67c7e2c52e46..c6823b81eb84 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/LICENSE +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020 The Flutter Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/enums.dart b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/enums.dart index 8dae9737981a..d5f05e6121a9 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/enums.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/enums.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/method_channel_wifi_info_flutter.dart b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/method_channel_wifi_info_flutter.dart index efd775ab7486..79f27e8cde44 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/method_channel_wifi_info_flutter.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/src/method_channel_wifi_info_flutter.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/wifi_info_flutter_platform_interface.dart b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/wifi_info_flutter_platform_interface.dart index 7e8de96336b4..62330d4261a0 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/wifi_info_flutter_platform_interface.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/lib/wifi_info_flutter_platform_interface.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/test/method_channel_wifi_info_flutter_test.dart b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/test/method_channel_wifi_info_flutter_test.dart index c30713a65b72..875f2ab4089a 100644 --- a/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/test/method_channel_wifi_info_flutter_test.dart +++ b/packages/wifi_info_flutter/wifi_info_flutter_platform_interface/test/method_channel_wifi_info_flutter_test.dart @@ -1,4 +1,4 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/build_all_plugins_app.sh b/script/build_all_plugins_app.sh index 864a81a85057..ab15a7d64249 100755 --- a/script/build_all_plugins_app.sh +++ b/script/build_all_plugins_app.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2017 The Flutter Authors. All rights reserved. +# Copyright 2013 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. diff --git a/script/check_publish.sh b/script/check_publish.sh index 5c68806c092a..a08df7a0b5d8 100755 --- a/script/check_publish.sh +++ b/script/check_publish.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2017 The Flutter Authors. All rights reserved. +# Copyright 2013 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. diff --git a/script/common.sh b/script/common.sh index 81fc96cbdc18..52eeefa6e9ff 100644 --- a/script/common.sh +++ b/script/common.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2017 The Flutter Authors. All rights reserved. +# Copyright 2013 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. diff --git a/script/incremental_build.sh b/script/incremental_build.sh index d087745eb88d..c14197c85ae7 100755 --- a/script/incremental_build.sh +++ b/script/incremental_build.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2017 The Flutter Authors. All rights reserved. +# Copyright 2013 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. diff --git a/script/tool/lib/src/analyze_command.dart b/script/tool/lib/src/analyze_command.dart index 7a0b47261a90..b2586c4b0fcf 100644 --- a/script/tool/lib/src/analyze_command.dart +++ b/script/tool/lib/src/analyze_command.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/lib/src/build_examples_command.dart b/script/tool/lib/src/build_examples_command.dart index 22029791f324..966fdc9b99df 100644 --- a/script/tool/lib/src/build_examples_command.dart +++ b/script/tool/lib/src/build_examples_command.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/lib/src/common.dart b/script/tool/lib/src/common.dart index 1228aef5b0f6..7d3063a20f53 100644 --- a/script/tool/lib/src/common.dart +++ b/script/tool/lib/src/common.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/lib/src/create_all_plugins_app_command.dart b/script/tool/lib/src/create_all_plugins_app_command.dart index ec2fb7ed698e..f1f11d15ca95 100644 --- a/script/tool/lib/src/create_all_plugins_app_command.dart +++ b/script/tool/lib/src/create_all_plugins_app_command.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/lib/src/drive_examples_command.dart b/script/tool/lib/src/drive_examples_command.dart index 4b5b33ff9029..529268ab4eb2 100644 --- a/script/tool/lib/src/drive_examples_command.dart +++ b/script/tool/lib/src/drive_examples_command.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/lib/src/firebase_test_lab_command.dart b/script/tool/lib/src/firebase_test_lab_command.dart index 382161226987..8e0abd507464 100644 --- a/script/tool/lib/src/firebase_test_lab_command.dart +++ b/script/tool/lib/src/firebase_test_lab_command.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/lib/src/format_command.dart b/script/tool/lib/src/format_command.dart index 54895cbae094..d849dc9aa9d2 100644 --- a/script/tool/lib/src/format_command.dart +++ b/script/tool/lib/src/format_command.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/lib/src/java_test_command.dart b/script/tool/lib/src/java_test_command.dart index 07800349a37b..45042c3c7006 100644 --- a/script/tool/lib/src/java_test_command.dart +++ b/script/tool/lib/src/java_test_command.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/lib/src/license_check_command.dart b/script/tool/lib/src/license_check_command.dart index 2df217ef78fd..4f78e4e96639 100644 --- a/script/tool/lib/src/license_check_command.dart +++ b/script/tool/lib/src/license_check_command.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. @@ -41,34 +41,30 @@ const Set _ignoredFullBasenameList = { 'resource.h', // Generated by VS. }; -// Copyright and license regexes. +// Copyright and license regexes for third-party code. // -// These are intentionally very simple, since almost all source in this -// repository should be using the same license text, comment style, etc., so -// they shouldn't need to be very flexible. Complexity can be added as-needed -// on a case-by-case basis. -final RegExp _copyrightRegex = - RegExp(r'^(?://|#|'), + final Map firstPartyLicenseBlockByExtension = + { + '.sh': _generateLicenseBlock('# '), + '.html': _generateLicenseBlock('', prefix: ''), }; for (final File file in codeFiles) { _print('Checking ${file.path}'); final String content = await file.readAsString(); - final RegExpMatch copyright = _copyrightRegex.firstMatch(content); - if (copyright == null) { - filesWithoutDetectedCopyright.add(file); - continue; - } - final String author = copyright.group(1); - if (author != _firstPartyAuthors && !_isThirdParty(file)) { - misplacedThirdPartyFiles.add(file); - } - - final String bsdLicense = - bsdLicenseBlockByExtension[p.extension(file.path)] ?? - defaultBsdLicenseBlock; - if (!content.contains(bsdLicense) && - !_workivaLicenseRegex.hasMatch(content)) { - filesWithoutDetectedLicense.add(file); + if (_isThirdParty(file)) { + if (!_thirdPartyLicenseBlockRegexes + .any((regex) => regex.hasMatch(content))) { + unrecognizedThirdPartyFiles.add(file); + } + } else { + final String license = + firstPartyLicenseBlockByExtension[p.extension(file.path)] ?? + defaultFirstParyLicenseBlock; + if (!content.contains(license)) { + incorrectFirstPartyFiles.add(file); + } } } _print('\n'); // Sort by path for more usable output. final pathCompare = (File a, File b) => a.path.compareTo(b.path); - filesWithoutDetectedCopyright.sort(pathCompare); - filesWithoutDetectedLicense.sort(pathCompare); - misplacedThirdPartyFiles.sort(pathCompare); + incorrectFirstPartyFiles.sort(pathCompare); + unrecognizedThirdPartyFiles.sort(pathCompare); - if (filesWithoutDetectedCopyright.isNotEmpty) { - _print('No copyright line was found for the following files:'); - for (final File file in filesWithoutDetectedCopyright) { + if (incorrectFirstPartyFiles.isNotEmpty) { + _print('The license block for these files is missing or incorrect:'); + for (final File file in incorrectFirstPartyFiles) { _print(' ${file.path}'); } - _print('Please check that they have a copyright and license block. ' - 'If they do, the license check may need to be updated to recognize its ' - 'format.\n'); + _print('If this third-party code, move it to a "third_party/" directory, ' + 'otherwise ensure that you are using the exact copyright and license ' + 'text used by all first-party files in this repository.\n'); } - if (filesWithoutDetectedLicense.isNotEmpty) { - _print('No recognized license was found for the following files:'); - for (final File file in filesWithoutDetectedLicense) { + if (unrecognizedThirdPartyFiles.isNotEmpty) { + _print( + 'No recognized license was found for the following third-party files:'); + for (final File file in unrecognizedThirdPartyFiles) { _print(' ${file.path}'); } _print('Please check that they have a license at the top of the file. ' - 'If they do, the license check may need to be updated to recognize ' - 'either the license or the specific format of the license ' - 'block.\n'); - } - - if (misplacedThirdPartyFiles.isNotEmpty) { - _print('The following files do not have a recognized first-party author ' - 'but are not in a "third_party/" directory:'); - for (final File file in misplacedThirdPartyFiles) { - _print(' ${file.path}'); - } - _print('Please move these files to "third_party/".\n'); + 'If they do, the license check needs to be updated to recognize ' + 'the new third-party license block.\n'); } - bool succeeded = filesWithoutDetectedCopyright.isEmpty && - filesWithoutDetectedLicense.isEmpty && - misplacedThirdPartyFiles.isEmpty; + bool succeeded = + incorrectFirstPartyFiles.isEmpty && unrecognizedThirdPartyFiles.isEmpty; if (succeeded) { _print('All source files passed validation!'); } @@ -241,7 +226,8 @@ class LicenseCheckCommand extends PluginCommand { for (final File file in incorrectLicenseFiles) { _print(' ${file.path}'); } - _print('Please ensure that they use the exact format used in this repository".\n'); + _print( + 'Please ensure that they use the exact format used in this repository".\n'); } bool succeeded = incorrectLicenseFiles.isEmpty; diff --git a/script/tool/lib/src/lint_podspecs_command.dart b/script/tool/lib/src/lint_podspecs_command.dart index 1e75eb62e4ea..3261072d71a1 100644 --- a/script/tool/lib/src/lint_podspecs_command.dart +++ b/script/tool/lib/src/lint_podspecs_command.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/lib/src/list_command.dart b/script/tool/lib/src/list_command.dart index 53c1ba2f3ea3..3571786ab7f8 100644 --- a/script/tool/lib/src/list_command.dart +++ b/script/tool/lib/src/list_command.dart @@ -1,4 +1,4 @@ -// Copyright 2018 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/lib/src/main.dart b/script/tool/lib/src/main.dart index bb8af5d5ad58..2e29aac1e784 100644 --- a/script/tool/lib/src/main.dart +++ b/script/tool/lib/src/main.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/lib/src/publish_check_command.dart b/script/tool/lib/src/publish_check_command.dart index 53002b57897a..dcd28d9a89f3 100644 --- a/script/tool/lib/src/publish_check_command.dart +++ b/script/tool/lib/src/publish_check_command.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/lib/src/publish_plugin_command.dart b/script/tool/lib/src/publish_plugin_command.dart index d48ed5b7fe7d..eb59091db34a 100644 --- a/script/tool/lib/src/publish_plugin_command.dart +++ b/script/tool/lib/src/publish_plugin_command.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/lib/src/test_command.dart b/script/tool/lib/src/test_command.dart index 47f7ad89cb8d..10ded4621ab5 100644 --- a/script/tool/lib/src/test_command.dart +++ b/script/tool/lib/src/test_command.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/lib/src/version_check_command.dart b/script/tool/lib/src/version_check_command.dart index 36105ad300ab..fb939a71e38a 100644 --- a/script/tool/lib/src/version_check_command.dart +++ b/script/tool/lib/src/version_check_command.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/lib/src/xctest_command.dart b/script/tool/lib/src/xctest_command.dart index cdc02594a192..41974713f99b 100644 --- a/script/tool/lib/src/xctest_command.dart +++ b/script/tool/lib/src/xctest_command.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/test/analyze_command_test.dart b/script/tool/test/analyze_command_test.dart index 6474d02f3d28..7b4ef81e0fc2 100644 --- a/script/tool/test/analyze_command_test.dart +++ b/script/tool/test/analyze_command_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/test/build_examples_command_test.dart b/script/tool/test/build_examples_command_test.dart index ef959a6e251c..f9ee6dcf25db 100644 --- a/script/tool/test/build_examples_command_test.dart +++ b/script/tool/test/build_examples_command_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/test/common_test.dart b/script/tool/test/common_test.dart index 8ee82ca2e95a..6f51ade64e83 100644 --- a/script/tool/test/common_test.dart +++ b/script/tool/test/common_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/test/drive_examples_command_test.dart b/script/tool/test/drive_examples_command_test.dart index 63a3e69adcdc..2b20f23d7da9 100644 --- a/script/tool/test/drive_examples_command_test.dart +++ b/script/tool/test/drive_examples_command_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/test/firebase_test_lab_test.dart b/script/tool/test/firebase_test_lab_test.dart index 6db4461a23a8..f1141ae19d80 100644 --- a/script/tool/test/firebase_test_lab_test.dart +++ b/script/tool/test/firebase_test_lab_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/test/license_check_command_test.dart b/script/tool/test/license_check_command_test.dart index 69879bff8869..f8646da5d83a 100644 --- a/script/tool/test/license_check_command_test.dart +++ b/script/tool/test/license_check_command_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. @@ -45,7 +45,7 @@ void main() { String prefix = '', String suffix = '', String copyright = - 'Copyright 2019 The Flutter Authors. All rights reserved.', + 'Copyright 2013 The Flutter Authors. All rights reserved.', List license = const [ 'Use of this source code is governed by a BSD-style license that can be', 'found in the LICENSE file.', @@ -171,8 +171,10 @@ void main() { throwsA(const TypeMatcher())); // Failure should give information about the problematic files. - expect(printedMessages, - contains('No copyright line was found for the following files:')); + expect( + printedMessages, + contains( + 'The license block for these files is missing or incorrect:')); expect(printedMessages, contains(' bad.cc')); expect(printedMessages, contains(' bad.h')); // Failure shouldn't print the success message. @@ -192,8 +194,10 @@ void main() { throwsA(const TypeMatcher())); // Failure should give information about the problematic files. - expect(printedMessages, - contains('No copyright line was found for the following files:')); + expect( + printedMessages, + contains( + 'The license block for these files is missing or incorrect:')); expect(printedMessages, contains(' bad.cc')); // Failure shouldn't print the success message. expect(printedMessages, @@ -212,8 +216,10 @@ void main() { throwsA(const TypeMatcher())); // Failure should give information about the problematic files. - expect(printedMessages, - contains('No recognized license was found for the following files:')); + expect( + printedMessages, + contains( + 'The license block for these files is missing or incorrect:')); expect(printedMessages, contains(' bad.cc')); // Failure shouldn't print the success message. expect(printedMessages, @@ -233,8 +239,7 @@ void main() { expect( printedMessages, contains( - 'The following files do not have a recognized first-party author ' - 'but are not in a "third_party/" directory:')); + 'The license block for these files is missing or incorrect:')); expect(printedMessages, contains(' third_party.cc')); // Failure shouldn't print the success message. expect(printedMessages, @@ -249,7 +254,12 @@ void main() { .childDirectory('third_party') .childFile('file.cc'); thirdPartyFile.createSync(recursive: true); - _writeLicense(thirdPartyFile, copyright: 'Copyright 2017 Someone Else'); + _writeLicense(thirdPartyFile, + copyright: 'Copyright 2017 Workiva Inc.', + license: [ + 'Licensed under the Apache License, Version 2.0 (the "License");', + 'you may not use this file except in compliance with the License.' + ]); await runner.run(['license-check']); @@ -274,8 +284,10 @@ void main() { throwsA(const TypeMatcher())); // Failure should give information about the problematic files. - expect(printedMessages, - contains('No recognized license was found for the following files:')); + expect( + printedMessages, + contains( + 'No recognized license was found for the following third-party files:')); expect(printedMessages, contains(' third_party/bad.cc')); // Failure shouldn't print the success message. expect(printedMessages, @@ -291,10 +303,11 @@ void main() { bad.createSync(recursive: true); _writeLicense( bad, - copyright: 'Copyright 2017 Some New Authors', - license: [ - 'Licensed under the Apache License, Version 2.0', - ], + copyright: 'Copyright 2017 Some New Authors.', + license: [ + 'Licensed under the Apache License, Version 2.0 (the "License");', + 'you may not use this file except in compliance with the License.' + ], ); await expectLater(() => runner.run(['license-check']), @@ -302,7 +315,7 @@ void main() { // Failure should give information about the problematic files. expect(printedMessages, - contains('No recognized license was found for the following files:')); + contains('No recognized license was found for the following third-party files:')); expect(printedMessages, contains(' third_party/bad.cc')); // Failure shouldn't print the success message. expect(printedMessages, @@ -335,8 +348,7 @@ void main() { isNot(contains('All LICENSE files passed validation!'))); }); - test('ignores third-party LICENSE format', - () async { + test('ignores third-party LICENSE format', () async { File license = root.childDirectory('third_party').childFile('LICENSE'); license.createSync(recursive: true); license.writeAsStringSync(_incorrectLicenseFileText); @@ -351,7 +363,7 @@ void main() { } const String _correctLicenseFileText = - '''Copyright 2017 The Flutter Authors. All rights reserved. + '''Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -381,7 +393,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // A common incorrect version created by copying text intended for a code file, // with comment markers. const String _incorrectLicenseFileText = - '''// Copyright 2017 The Flutter Authors. All rights reserved. + '''// Copyright 2013 The Flutter Authors. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are diff --git a/script/tool/test/lint_podspecs_command_test.dart b/script/tool/test/lint_podspecs_command_test.dart index 44e94ee873e4..5475641cba93 100644 --- a/script/tool/test/lint_podspecs_command_test.dart +++ b/script/tool/test/lint_podspecs_command_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/test/list_command_test.dart b/script/tool/test/list_command_test.dart index e9b68254fb5d..19e9df0dd38d 100644 --- a/script/tool/test/list_command_test.dart +++ b/script/tool/test/list_command_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/test/mocks.dart b/script/tool/test/mocks.dart index d5cfe4ec4f76..2ef9d72e3637 100644 --- a/script/tool/test/mocks.dart +++ b/script/tool/test/mocks.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/test/publish_plugin_command_test.dart b/script/tool/test/publish_plugin_command_test.dart index b8ab1d25e532..9a0f1d6b6e63 100644 --- a/script/tool/test/publish_plugin_command_test.dart +++ b/script/tool/test/publish_plugin_command_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/test/test_command_test.dart b/script/tool/test/test_command_test.dart index eb9f3a9b0cf3..66471263f661 100644 --- a/script/tool/test/test_command_test.dart +++ b/script/tool/test/test_command_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/test/util.dart b/script/tool/test/util.dart index e463b88a1abb..908b67b3cf75 100644 --- a/script/tool/test/util.dart +++ b/script/tool/test/util.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/test/version_check_test.dart b/script/tool/test/version_check_test.dart index 9e610d8a7a20..dc36c6c32284 100644 --- a/script/tool/test/version_check_test.dart +++ b/script/tool/test/version_check_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019 The Flutter Authors. All rights reserved. +// Copyright 2013 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. diff --git a/script/tool/test/xctest_command_test.dart b/script/tool/test/xctest_command_test.dart index 3b76fa6ffa19..aa71c25835c8 100644 --- a/script/tool/test/xctest_command_test.dart +++ b/script/tool/test/xctest_command_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017 The Flutter Authors. All rights reserved. +// Copyright 2013 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. From 2068cce1d06c7cbbc6e241f83af24e67dc72863d Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 19 Mar 2021 14:11:06 -0700 Subject: [PATCH 0284/1565] Enable web integration tests in CI (#3738) --- .ci/Dockerfile-LegacyChrome | 29 ------ .cirrus.yml | 59 +++++-------- .../tool/lib/src/drive_examples_command.dart | 38 +++++--- .../test/drive_examples_command_test.dart | 88 ++++++++++++++++++- 4 files changed, 134 insertions(+), 80 deletions(-) delete mode 100644 .ci/Dockerfile-LegacyChrome diff --git a/.ci/Dockerfile-LegacyChrome b/.ci/Dockerfile-LegacyChrome deleted file mode 100644 index 13ac087498d1..000000000000 --- a/.ci/Dockerfile-LegacyChrome +++ /dev/null @@ -1,29 +0,0 @@ -FROM cirrusci/flutter:stable - -RUN sudo apt-get update -y - -RUN sudo apt-get install -y --no-install-recommends gnupg - -# Add repo for gcloud sdk and install it -RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | \ - sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list - -RUN curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | \ - sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - - -RUN sudo apt-get update && sudo apt-get install -y google-cloud-sdk && \ - gcloud config set core/disable_usage_reporting true && \ - gcloud config set component_manager/disable_update_check true - -RUN yes | sdkmanager \ - "platforms;android-27" \ - "build-tools;27.0.3" \ - "extras;google;m2repository" \ - "extras;android;m2repository" - -RUN yes | sdkmanager --licenses - -# Add repo for Google Chrome and install it -RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add - -RUN echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | sudo tee /etc/apt/sources.list.d/google-chrome.list -RUN sudo apt-get update && sudo apt-get install -y --no-install-recommends google-chrome-stable diff --git a/.cirrus.yml b/.cirrus.yml index 26264b3fb926..c2bbd35e15e7 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -93,13 +93,6 @@ task: CHANNEL: "stable" script: - ./script/build_all_plugins_app.sh web - - name: build-web-examples - env: - matrix: - CHANNEL: "master" - build_script: - - ./script/incremental_build.sh build-examples --web - # TODO: Add driving examples (and move to heavy-workload group). ### Linux desktop tasks ### - name: build_all_plugins_linux env: @@ -117,35 +110,8 @@ task: build_script: - flutter config --enable-linux-desktop - ./script/incremental_build.sh build-examples --linux - - xvfb-run ./script/incremental_build.sh drive-examples --linux - -# Legacy Dockerfile configuration for web integration tests. -# https://github.com/flutter/web_installers doesn't yet support the current -# stable version of Chrome, so newly-generated Docker images don't work. -# TODO: Merge this task into the "Web tasks" section of the "Light-workload -# tasks" block above once web_installers has been updated to support Chrome 89 -# (which is what the current image generated from .ci/Dockerfile has). -task: - << : *FLUTTER_UPGRADE_TEMPLATE - container: - dockerfile: .ci/Dockerfile-LegacyChrome - matrix: - - name: integration_web_smoke_test - env: - matrix: - CHANNEL: "master" - CHANNEL: "stable" - # Tests integration example test in web. - only_if: "changesInclude('.cirrus.yml', 'packages/integration_test/**') || $CIRRUS_PR == ''" - install_script: - - git clone https://github.com/flutter/web_installers.git - - cd web_installers/packages/web_drivers/ - - pub get - - dart lib/web_driver_installer.dart chromedriver --install-only - - ./chromedriver/chromedriver --port=4444 & test_script: - - cd $INTEGRATION_TEST_PATH/example/ - - flutter drive -v --driver=test_driver/integration_test.dart --target=integration_test/example_test.dart -d web-server --release --browser-name=chrome + - xvfb-run ./script/incremental_build.sh drive-examples --linux # Heavy-workload Linux tasks. # These use machines with more CPUs and memory, so will reduce parallelization @@ -191,6 +157,27 @@ task: - fi - export CIRRUS_CHANGE_MESSAGE=`cat /tmp/cirrus_change_message.txt` - export CIRRUS_COMMIT_MESSAGE=`cat /tmp/cirrus_commit_message.txt` + ### Web tasks ### + - name: build-web+drive-examples + env: + matrix: + CHANNEL: "master" + CHANNEL: "stable" + install_script: + - git clone https://github.com/flutter/web_installers.git + - cd web_installers/packages/web_drivers/ + - pub get + - dart lib/web_driver_installer.dart chromedriver --install-only + - ./chromedriver/chromedriver --port=4444 & + build_script: + - ./script/incremental_build.sh build-examples --web + test_script: + # TODO(stuartmorgan): Eliminate this check once 2.1 reaches stable. + - if [[ "$CHANNEL" == "master" ]]; then + - ./script/incremental_build.sh drive-examples --web + - else + - echo "Requires null-safe integration_test; skipping." + - fi # macOS tasks. task: @@ -223,6 +210,7 @@ task: - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-11 com.apple.CoreSimulator.SimRuntime.iOS-14-3 | xargs xcrun simctl boot build_script: - ./script/incremental_build.sh build-examples --ipa + test_script: - ./script/incremental_build.sh xctest --skip $PLUGINS_TO_SKIP_XCTESTS --ios-destination "platform=iOS Simulator,name=iPhone 11,OS=latest" # `drive-examples` contains integration tests, which changes the UI of the application. # This UI change sometimes affects `xctest`. @@ -246,6 +234,7 @@ task: build_script: - flutter config --enable-macos-desktop - ./script/incremental_build.sh build-examples --macos --no-ipa + test_script: - ./script/incremental_build.sh drive-examples --macos task: diff --git a/script/tool/lib/src/drive_examples_command.dart b/script/tool/lib/src/drive_examples_command.dart index 529268ab4eb2..de5dc9ebfc62 100644 --- a/script/tool/lib/src/drive_examples_command.dart +++ b/script/tool/lib/src/drive_examples_command.dart @@ -14,16 +14,18 @@ class DriveExamplesCommand extends PluginCommand { FileSystem fileSystem, { ProcessRunner processRunner = const ProcessRunner(), }) : super(packagesDir, fileSystem, processRunner: processRunner) { + argParser.addFlag(kAndroid, + help: 'Runs the Android implementation of the examples'); + argParser.addFlag(kIos, + help: 'Runs the iOS implementation of the examples'); argParser.addFlag(kLinux, help: 'Runs the Linux implementation of the examples'); argParser.addFlag(kMacos, help: 'Runs the macOS implementation of the examples'); + argParser.addFlag(kWeb, + help: 'Runs the web implementation of the examples'); argParser.addFlag(kWindows, help: 'Runs the Windows implementation of the examples'); - argParser.addFlag(kIos, - help: 'Runs the iOS implementation of the examples'); - argParser.addFlag(kAndroid, - help: 'Runs the Android implementation of the examples'); argParser.addOption( kEnableExperiment, defaultsTo: '', @@ -51,6 +53,7 @@ class DriveExamplesCommand extends PluginCommand { final List failingTests = []; final bool isLinux = argResults[kLinux]; final bool isMacos = argResults[kMacos]; + final bool isWeb = argResults[kWeb]; final bool isWindows = argResults[kWindows]; await for (Directory plugin in getPlugins()) { final String flutterCommand = @@ -139,6 +142,13 @@ Tried searching for the following: 'macos', ]); } + if (isWeb && isWebPlugin(plugin, fileSystem)) { + driveArgs.addAll([ + '-d', + 'web-server', + '--browser-name=chrome', + ]); + } if (isWindows && isWindowsPlugin(plugin, fileSystem)) { driveArgs.addAll([ '-d', @@ -180,26 +190,30 @@ Tried searching for the following: Future pluginSupportedOnCurrentPlatform( FileSystemEntity plugin, FileSystem fileSystem) async { + final bool isAndroid = argResults[kAndroid]; + final bool isIOS = argResults[kIos]; final bool isLinux = argResults[kLinux]; final bool isMacos = argResults[kMacos]; + final bool isWeb = argResults[kWeb]; final bool isWindows = argResults[kWindows]; - final bool isIOS = argResults[kIos]; - final bool isAndroid = argResults[kAndroid]; + if (isAndroid) { + return (isAndroidPlugin(plugin, fileSystem)); + } + if (isIOS) { + return isIosPlugin(plugin, fileSystem); + } if (isLinux) { return isLinuxPlugin(plugin, fileSystem); } if (isMacos) { return isMacOsPlugin(plugin, fileSystem); } + if (isWeb) { + return isWebPlugin(plugin, fileSystem); + } if (isWindows) { return isWindowsPlugin(plugin, fileSystem); } - if (isIOS) { - return isIosPlugin(plugin, fileSystem); - } - if (isAndroid) { - return (isAndroidPlugin(plugin, fileSystem)); - } // When we are here, no flags are specified. Only return true if the plugin // supports Android for legacy command support. TODO(cyanglaz): Make Android // flag also required like other platforms (breaking change). diff --git a/script/tool/test/drive_examples_command_test.dart b/script/tool/test/drive_examples_command_test.dart index 2b20f23d7da9..65bdf99c165d 100644 --- a/script/tool/test/drive_examples_command_test.dart +++ b/script/tool/test/drive_examples_command_test.dart @@ -357,13 +357,13 @@ void main() { ])); }); - test('driving when plugin does not suppport windows is a no-op', () async { + test('driving when plugin does not suppport web is a no-op', () async { createFakePlugin('plugin', withExtraFiles: >[ ['example', 'test_driver', 'plugin_test.dart'], ['example', 'test_driver', 'plugin.dart'], ], - isMacOsPlugin: false); + isWebPlugin: false); final Directory pluginExampleDirectory = mockPackagesDir.childDirectory('plugin').childDirectory('example'); @@ -372,7 +372,7 @@ void main() { final List output = await runCapturingPrint(runner, [ 'drive-examples', - '--windows', + '--web', ]); expect( @@ -384,11 +384,91 @@ void main() { ); print(processRunner.recordedCalls); - // Output should be empty since running drive-examples --windows on a non-windows + // Output should be empty since running drive-examples --web on a non-web // plugin is a no-op. expect(processRunner.recordedCalls, []); }); + test('driving a web plugin', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test_driver', 'plugin_test.dart'], + ['example', 'test_driver', 'plugin.dart'], + ], + isWebPlugin: true); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint(runner, [ + 'drive-examples', + '--web', + ]); + + expect( + output, + orderedEquals([ + '\n\n', + 'All driver tests successful!', + ]), + ); + + String deviceTestPath = p.join('test_driver', 'plugin.dart'); + String driverTestPath = p.join('test_driver', 'plugin_test.dart'); + print(processRunner.recordedCalls); + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + flutterCommand, + [ + 'drive', + '-d', + 'web-server', + '--browser-name=chrome', + '--driver', + driverTestPath, + '--target', + deviceTestPath + ], + pluginExampleDirectory.path), + ])); + }); + + test('driving when plugin does not suppport Windows is a no-op', () async { + createFakePlugin('plugin', + withExtraFiles: >[ + ['example', 'test_driver', 'plugin_test.dart'], + ['example', 'test_driver', 'plugin.dart'], + ], + isWindowsPlugin: false); + + final Directory pluginExampleDirectory = + mockPackagesDir.childDirectory('plugin').childDirectory('example'); + + createFakePubspec(pluginExampleDirectory, isFlutter: true); + + final List output = await runCapturingPrint(runner, [ + 'drive-examples', + '--windows', + ]); + + expect( + output, + orderedEquals([ + '\n\n', + 'All driver tests successful!', + ]), + ); + + print(processRunner.recordedCalls); + // Output should be empty since running drive-examples --windows on a + // non-Windows plugin is a no-op. + expect(processRunner.recordedCalls, []); + }); + test('driving on a Windows plugin', () async { createFakePlugin('plugin', withExtraFiles: >[ From a85f397e760817b4fe1bb38f84cf3a0cea30c6fa Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Fri, 19 Mar 2021 16:34:20 -0700 Subject: [PATCH 0285/1565] [ci] Run more web tests (#3739) This change enables the integration_tests of the following packages to run in Cirrus CI: * google_sign_in_web * connectivity_for_web * google_maps_flutter_web * url_launcher_web --- .../connectivity_for_web/example/run_test.sh | 4 +- ...tion_driver.dart => integration_test.dart} | 0 .../example/run_test.sh | 4 +- ...tion_driver.dart => integration_test.dart} | 0 .../example/web/index.html | 3 +- .../google_sign_in_web/example/run_test.sh | 4 +- ...tion_driver.dart => integration_test.dart} | 0 .../url_launcher_web_test.mocks.dart | 854 ++++++++++-------- .../url_launcher_web/example/run_test.sh | 4 +- ...test_driver.dart => integration_test.dart} | 0 .../tool/lib/src/drive_examples_command.dart | 1 + .../test/drive_examples_command_test.dart | 1 + 12 files changed, 470 insertions(+), 405 deletions(-) rename packages/connectivity/connectivity_for_web/example/test_driver/{integration_driver.dart => integration_test.dart} (100%) rename packages/google_maps_flutter/google_maps_flutter_web/example/test_driver/{integration_driver.dart => integration_test.dart} (100%) rename packages/google_sign_in/google_sign_in_web/example/test_driver/{integration_driver.dart => integration_test.dart} (100%) rename packages/url_launcher/url_launcher_web/example/test_driver/{integration_test_driver.dart => integration_test.dart} (100%) diff --git a/packages/connectivity/connectivity_for_web/example/run_test.sh b/packages/connectivity/connectivity_for_web/example/run_test.sh index dbf0ec55fd8f..aa52974f310e 100755 --- a/packages/connectivity/connectivity_for_web/example/run_test.sh +++ b/packages/connectivity/connectivity_for_web/example/run_test.sh @@ -8,11 +8,11 @@ if pgrep -lf chromedriver > /dev/null; then if [ $# -eq 0 ]; then echo "No target specified, running all tests..." - find integration_test/ -iname *_test.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_driver.dart --target='{}' + find integration_test/ -iname *_test.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_test.dart --target='{}' else echo "Running test target: $1..." set -x - flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_driver.dart --target=$1 + flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_test.dart --target=$1 fi else diff --git a/packages/connectivity/connectivity_for_web/example/test_driver/integration_driver.dart b/packages/connectivity/connectivity_for_web/example/test_driver/integration_test.dart similarity index 100% rename from packages/connectivity/connectivity_for_web/example/test_driver/integration_driver.dart rename to packages/connectivity/connectivity_for_web/example/test_driver/integration_test.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh b/packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh index dbf0ec55fd8f..aa52974f310e 100755 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh @@ -8,11 +8,11 @@ if pgrep -lf chromedriver > /dev/null; then if [ $# -eq 0 ]; then echo "No target specified, running all tests..." - find integration_test/ -iname *_test.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_driver.dart --target='{}' + find integration_test/ -iname *_test.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_test.dart --target='{}' else echo "Running test target: $1..." set -x - flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_driver.dart --target=$1 + flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_test.dart --target=$1 fi else diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/test_driver/integration_driver.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/test_driver/integration_test.dart similarity index 100% rename from packages/google_maps_flutter/google_maps_flutter_web/example/test_driver/integration_driver.dart rename to packages/google_maps_flutter/google_maps_flutter_web/example/test_driver/integration_test.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html index d48ebfe62c37..f324d1c7538f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html @@ -5,7 +5,8 @@ Browser Tests - + + diff --git a/packages/google_sign_in/google_sign_in_web/example/run_test.sh b/packages/google_sign_in/google_sign_in_web/example/run_test.sh index fe30bc8652d0..28877dce8d6e 100755 --- a/packages/google_sign_in/google_sign_in_web/example/run_test.sh +++ b/packages/google_sign_in/google_sign_in_web/example/run_test.sh @@ -8,11 +8,11 @@ if pgrep -lf chromedriver > /dev/null; then if [ $# -eq 0 ]; then echo "No target specified, running all tests..." - find integration_test/ -iname *_test.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_driver.dart --target='{}' + find integration_test/ -iname *_test.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_test.dart --target='{}' else echo "Running test target: $1..." set -x - flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_driver.dart --target=$1 + flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_test.dart --target=$1 fi else diff --git a/packages/google_sign_in/google_sign_in_web/example/test_driver/integration_driver.dart b/packages/google_sign_in/google_sign_in_web/example/test_driver/integration_test.dart similarity index 100% rename from packages/google_sign_in/google_sign_in_web/example/test_driver/integration_driver.dart rename to packages/google_sign_in/google_sign_in_web/example/test_driver/integration_test.dart diff --git a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart index 5c55ec779c9c..9cd0196f51db 100644 --- a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart +++ b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart @@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Mocks generated by Mockito 5.0.2 from annotations +// in regular_integration_tests/integration_test/url_launcher_web_test.dart. +// Do not manually edit this file. + import 'dart:async' as _i4; import 'dart:html' as _i2; import 'dart:math' as _i5; @@ -10,7 +14,6 @@ import 'dart:web_sql' as _i3; import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: comment_references - // ignore_for_file: unnecessary_parenthesis class _FakeDocument extends _i1.Fake implements _i2.Document {} @@ -61,415 +64,450 @@ class MockWindow extends _i1.Mock implements _i2.Window { @override _i4.Future get animationFrame => - (super.noSuchMethod(Invocation.getter(#animationFrame), Future.value(0)) - as _i4.Future); + (super.noSuchMethod(Invocation.getter(#animationFrame), + returnValue: Future.value(0)) as _i4.Future); @override - _i2.Document get document => - (super.noSuchMethod(Invocation.getter(#document), _FakeDocument()) - as _i2.Document); + _i2.Document get document => (super.noSuchMethod(Invocation.getter(#document), + returnValue: _FakeDocument()) as _i2.Document); @override - _i2.Location get location => - (super.noSuchMethod(Invocation.getter(#location), _FakeLocation()) - as _i2.Location); + _i2.Location get location => (super.noSuchMethod(Invocation.getter(#location), + returnValue: _FakeLocation()) as _i2.Location); @override set location(_i2.LocationBase? value) => - super.noSuchMethod(Invocation.setter(#location, value)); + super.noSuchMethod(Invocation.setter(#location, value), + returnValueForMissingStub: null); @override - _i2.Console get console => - (super.noSuchMethod(Invocation.getter(#console), _FakeConsole()) - as _i2.Console); + _i2.Console get console => (super.noSuchMethod(Invocation.getter(#console), + returnValue: _FakeConsole()) as _i2.Console); @override num get devicePixelRatio => - (super.noSuchMethod(Invocation.getter(#devicePixelRatio), 0) as num); + (super.noSuchMethod(Invocation.getter(#devicePixelRatio), returnValue: 0) + as num); @override - _i2.History get history => - (super.noSuchMethod(Invocation.getter(#history), _FakeHistory()) - as _i2.History); + _i2.History get history => (super.noSuchMethod(Invocation.getter(#history), + returnValue: _FakeHistory()) as _i2.History); @override _i2.Storage get localStorage => - (super.noSuchMethod(Invocation.getter(#localStorage), _FakeStorage()) - as _i2.Storage); + (super.noSuchMethod(Invocation.getter(#localStorage), + returnValue: _FakeStorage()) as _i2.Storage); @override _i2.Navigator get navigator => - (super.noSuchMethod(Invocation.getter(#navigator), _FakeNavigator()) - as _i2.Navigator); + (super.noSuchMethod(Invocation.getter(#navigator), + returnValue: _FakeNavigator()) as _i2.Navigator); @override int get outerHeight => - (super.noSuchMethod(Invocation.getter(#outerHeight), 0) as int); + (super.noSuchMethod(Invocation.getter(#outerHeight), returnValue: 0) + as int); @override int get outerWidth => - (super.noSuchMethod(Invocation.getter(#outerWidth), 0) as int); + (super.noSuchMethod(Invocation.getter(#outerWidth), returnValue: 0) + as int); @override _i2.Performance get performance => - (super.noSuchMethod(Invocation.getter(#performance), _FakePerformance()) - as _i2.Performance); + (super.noSuchMethod(Invocation.getter(#performance), + returnValue: _FakePerformance()) as _i2.Performance); @override _i2.Storage get sessionStorage => - (super.noSuchMethod(Invocation.getter(#sessionStorage), _FakeStorage()) - as _i2.Storage); + (super.noSuchMethod(Invocation.getter(#sessionStorage), + returnValue: _FakeStorage()) as _i2.Storage); @override - _i4.Stream<_i2.Event> get onContentLoaded => (super.noSuchMethod( - Invocation.getter(#onContentLoaded), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); + _i4.Stream<_i2.Event> get onContentLoaded => + (super.noSuchMethod(Invocation.getter(#onContentLoaded), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onAbort => (super - .noSuchMethod(Invocation.getter(#onAbort), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); + _i4.Stream<_i2.Event> get onAbort => + (super.noSuchMethod(Invocation.getter(#onAbort), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); @override _i4.Stream<_i2.Event> get onBlur => - (super.noSuchMethod(Invocation.getter(#onBlur), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); + (super.noSuchMethod(Invocation.getter(#onBlur), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onCanPlay => (super.noSuchMethod( - Invocation.getter(#onCanPlay), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); + _i4.Stream<_i2.Event> get onCanPlay => + (super.noSuchMethod(Invocation.getter(#onCanPlay), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onCanPlayThrough => (super.noSuchMethod( - Invocation.getter(#onCanPlayThrough), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); + _i4.Stream<_i2.Event> get onCanPlayThrough => + (super.noSuchMethod(Invocation.getter(#onCanPlayThrough), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onChange => (super - .noSuchMethod(Invocation.getter(#onChange), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); + _i4.Stream<_i2.Event> get onChange => + (super.noSuchMethod(Invocation.getter(#onChange), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); @override - _i4.Stream<_i2.MouseEvent> get onClick => (super.noSuchMethod( - Invocation.getter(#onClick), Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); + _i4.Stream<_i2.MouseEvent> get onClick => + (super.noSuchMethod(Invocation.getter(#onClick), + returnValue: Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); @override - _i4.Stream<_i2.MouseEvent> get onContextMenu => (super.noSuchMethod( - Invocation.getter(#onContextMenu), Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); + _i4.Stream<_i2.MouseEvent> get onContextMenu => + (super.noSuchMethod(Invocation.getter(#onContextMenu), + returnValue: Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); @override - _i4.Stream<_i2.Event> get onDoubleClick => (super.noSuchMethod( - Invocation.getter(#onDoubleClick), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); + _i4.Stream<_i2.Event> get onDoubleClick => + (super.noSuchMethod(Invocation.getter(#onDoubleClick), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); @override - _i4.Stream<_i2.DeviceMotionEvent> get onDeviceMotion => (super.noSuchMethod( - Invocation.getter(#onDeviceMotion), - Stream<_i2.DeviceMotionEvent>.empty()) - as _i4.Stream<_i2.DeviceMotionEvent>); + _i4.Stream<_i2.DeviceMotionEvent> get onDeviceMotion => + (super.noSuchMethod(Invocation.getter(#onDeviceMotion), + returnValue: Stream<_i2.DeviceMotionEvent>.empty()) + as _i4.Stream<_i2.DeviceMotionEvent>); @override _i4.Stream<_i2.DeviceOrientationEvent> get onDeviceOrientation => (super.noSuchMethod(Invocation.getter(#onDeviceOrientation), - Stream<_i2.DeviceOrientationEvent>.empty()) + returnValue: Stream<_i2.DeviceOrientationEvent>.empty()) as _i4.Stream<_i2.DeviceOrientationEvent>); @override - _i4.Stream<_i2.MouseEvent> get onDrag => (super.noSuchMethod( - Invocation.getter(#onDrag), Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); - @override - _i4.Stream<_i2.MouseEvent> get onDragEnd => (super.noSuchMethod( - Invocation.getter(#onDragEnd), Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); - @override - _i4.Stream<_i2.MouseEvent> get onDragEnter => (super.noSuchMethod( - Invocation.getter(#onDragEnter), Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); - @override - _i4.Stream<_i2.MouseEvent> get onDragLeave => (super.noSuchMethod( - Invocation.getter(#onDragLeave), Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); - @override - _i4.Stream<_i2.MouseEvent> get onDragOver => (super.noSuchMethod( - Invocation.getter(#onDragOver), Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); - @override - _i4.Stream<_i2.MouseEvent> get onDragStart => (super.noSuchMethod( - Invocation.getter(#onDragStart), Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); - @override - _i4.Stream<_i2.MouseEvent> get onDrop => (super.noSuchMethod( - Invocation.getter(#onDrop), Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); - @override - _i4.Stream<_i2.Event> get onDurationChange => (super.noSuchMethod( - Invocation.getter(#onDurationChange), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onEmptied => (super.noSuchMethod( - Invocation.getter(#onEmptied), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onEnded => (super - .noSuchMethod(Invocation.getter(#onEnded), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onError => (super - .noSuchMethod(Invocation.getter(#onError), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onFocus => (super - .noSuchMethod(Invocation.getter(#onFocus), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onHashChange => (super.noSuchMethod( - Invocation.getter(#onHashChange), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onInput => (super - .noSuchMethod(Invocation.getter(#onInput), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onInvalid => (super.noSuchMethod( - Invocation.getter(#onInvalid), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.KeyboardEvent> get onKeyDown => (super.noSuchMethod( - Invocation.getter(#onKeyDown), Stream<_i2.KeyboardEvent>.empty()) - as _i4.Stream<_i2.KeyboardEvent>); - @override - _i4.Stream<_i2.KeyboardEvent> get onKeyPress => (super.noSuchMethod( - Invocation.getter(#onKeyPress), Stream<_i2.KeyboardEvent>.empty()) - as _i4.Stream<_i2.KeyboardEvent>); - @override - _i4.Stream<_i2.KeyboardEvent> get onKeyUp => (super.noSuchMethod( - Invocation.getter(#onKeyUp), Stream<_i2.KeyboardEvent>.empty()) - as _i4.Stream<_i2.KeyboardEvent>); + _i4.Stream<_i2.MouseEvent> get onDrag => + (super.noSuchMethod(Invocation.getter(#onDrag), + returnValue: Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDragEnd => + (super.noSuchMethod(Invocation.getter(#onDragEnd), + returnValue: Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDragEnter => + (super.noSuchMethod(Invocation.getter(#onDragEnter), + returnValue: Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDragLeave => + (super.noSuchMethod(Invocation.getter(#onDragLeave), + returnValue: Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDragOver => + (super.noSuchMethod(Invocation.getter(#onDragOver), + returnValue: Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDragStart => + (super.noSuchMethod(Invocation.getter(#onDragStart), + returnValue: Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onDrop => + (super.noSuchMethod(Invocation.getter(#onDrop), + returnValue: Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.Event> get onDurationChange => + (super.noSuchMethod(Invocation.getter(#onDurationChange), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onEmptied => + (super.noSuchMethod(Invocation.getter(#onEmptied), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onEnded => + (super.noSuchMethod(Invocation.getter(#onEnded), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onError => + (super.noSuchMethod(Invocation.getter(#onError), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onFocus => + (super.noSuchMethod(Invocation.getter(#onFocus), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onHashChange => + (super.noSuchMethod(Invocation.getter(#onHashChange), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onInput => + (super.noSuchMethod(Invocation.getter(#onInput), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onInvalid => + (super.noSuchMethod(Invocation.getter(#onInvalid), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.KeyboardEvent> get onKeyDown => + (super.noSuchMethod(Invocation.getter(#onKeyDown), + returnValue: Stream<_i2.KeyboardEvent>.empty()) + as _i4.Stream<_i2.KeyboardEvent>); + @override + _i4.Stream<_i2.KeyboardEvent> get onKeyPress => + (super.noSuchMethod(Invocation.getter(#onKeyPress), + returnValue: Stream<_i2.KeyboardEvent>.empty()) + as _i4.Stream<_i2.KeyboardEvent>); + @override + _i4.Stream<_i2.KeyboardEvent> get onKeyUp => + (super.noSuchMethod(Invocation.getter(#onKeyUp), + returnValue: Stream<_i2.KeyboardEvent>.empty()) + as _i4.Stream<_i2.KeyboardEvent>); @override _i4.Stream<_i2.Event> get onLoad => - (super.noSuchMethod(Invocation.getter(#onLoad), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onLoadedData => (super.noSuchMethod( - Invocation.getter(#onLoadedData), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onLoadedMetadata => (super.noSuchMethod( - Invocation.getter(#onLoadedMetadata), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onLoadStart => (super.noSuchMethod( - Invocation.getter(#onLoadStart), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.MessageEvent> get onMessage => (super.noSuchMethod( - Invocation.getter(#onMessage), Stream<_i2.MessageEvent>.empty()) - as _i4.Stream<_i2.MessageEvent>); - @override - _i4.Stream<_i2.MouseEvent> get onMouseDown => (super.noSuchMethod( - Invocation.getter(#onMouseDown), Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); - @override - _i4.Stream<_i2.MouseEvent> get onMouseEnter => (super.noSuchMethod( - Invocation.getter(#onMouseEnter), Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); - @override - _i4.Stream<_i2.MouseEvent> get onMouseLeave => (super.noSuchMethod( - Invocation.getter(#onMouseLeave), Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); - @override - _i4.Stream<_i2.MouseEvent> get onMouseMove => (super.noSuchMethod( - Invocation.getter(#onMouseMove), Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); - @override - _i4.Stream<_i2.MouseEvent> get onMouseOut => (super.noSuchMethod( - Invocation.getter(#onMouseOut), Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); - @override - _i4.Stream<_i2.MouseEvent> get onMouseOver => (super.noSuchMethod( - Invocation.getter(#onMouseOver), Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); - @override - _i4.Stream<_i2.MouseEvent> get onMouseUp => (super.noSuchMethod( - Invocation.getter(#onMouseUp), Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); - @override - _i4.Stream<_i2.WheelEvent> get onMouseWheel => (super.noSuchMethod( - Invocation.getter(#onMouseWheel), Stream<_i2.WheelEvent>.empty()) - as _i4.Stream<_i2.WheelEvent>); - @override - _i4.Stream<_i2.Event> get onOffline => (super.noSuchMethod( - Invocation.getter(#onOffline), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onOnline => (super - .noSuchMethod(Invocation.getter(#onOnline), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onPageHide => (super.noSuchMethod( - Invocation.getter(#onPageHide), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onPageShow => (super.noSuchMethod( - Invocation.getter(#onPageShow), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onPause => (super - .noSuchMethod(Invocation.getter(#onPause), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); + (super.noSuchMethod(Invocation.getter(#onLoad), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onLoadedData => + (super.noSuchMethod(Invocation.getter(#onLoadedData), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onLoadedMetadata => + (super.noSuchMethod(Invocation.getter(#onLoadedMetadata), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onLoadStart => + (super.noSuchMethod(Invocation.getter(#onLoadStart), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.MessageEvent> get onMessage => + (super.noSuchMethod(Invocation.getter(#onMessage), + returnValue: Stream<_i2.MessageEvent>.empty()) + as _i4.Stream<_i2.MessageEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseDown => + (super.noSuchMethod(Invocation.getter(#onMouseDown), + returnValue: Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseEnter => + (super.noSuchMethod(Invocation.getter(#onMouseEnter), + returnValue: Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseLeave => + (super.noSuchMethod(Invocation.getter(#onMouseLeave), + returnValue: Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseMove => + (super.noSuchMethod(Invocation.getter(#onMouseMove), + returnValue: Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseOut => + (super.noSuchMethod(Invocation.getter(#onMouseOut), + returnValue: Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseOver => + (super.noSuchMethod(Invocation.getter(#onMouseOver), + returnValue: Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.MouseEvent> get onMouseUp => + (super.noSuchMethod(Invocation.getter(#onMouseUp), + returnValue: Stream<_i2.MouseEvent>.empty()) + as _i4.Stream<_i2.MouseEvent>); + @override + _i4.Stream<_i2.WheelEvent> get onMouseWheel => + (super.noSuchMethod(Invocation.getter(#onMouseWheel), + returnValue: Stream<_i2.WheelEvent>.empty()) + as _i4.Stream<_i2.WheelEvent>); + @override + _i4.Stream<_i2.Event> get onOffline => + (super.noSuchMethod(Invocation.getter(#onOffline), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onOnline => + (super.noSuchMethod(Invocation.getter(#onOnline), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onPageHide => + (super.noSuchMethod(Invocation.getter(#onPageHide), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onPageShow => + (super.noSuchMethod(Invocation.getter(#onPageShow), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onPause => + (super.noSuchMethod(Invocation.getter(#onPause), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); @override _i4.Stream<_i2.Event> get onPlay => - (super.noSuchMethod(Invocation.getter(#onPlay), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onPlaying => (super.noSuchMethod( - Invocation.getter(#onPlaying), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.PopStateEvent> get onPopState => (super.noSuchMethod( - Invocation.getter(#onPopState), Stream<_i2.PopStateEvent>.empty()) - as _i4.Stream<_i2.PopStateEvent>); - @override - _i4.Stream<_i2.Event> get onProgress => (super.noSuchMethod( - Invocation.getter(#onProgress), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onRateChange => (super.noSuchMethod( - Invocation.getter(#onRateChange), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onReset => (super - .noSuchMethod(Invocation.getter(#onReset), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onResize => (super - .noSuchMethod(Invocation.getter(#onResize), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onScroll => (super - .noSuchMethod(Invocation.getter(#onScroll), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onSearch => (super - .noSuchMethod(Invocation.getter(#onSearch), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onSeeked => (super - .noSuchMethod(Invocation.getter(#onSeeked), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onSeeking => (super.noSuchMethod( - Invocation.getter(#onSeeking), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onSelect => (super - .noSuchMethod(Invocation.getter(#onSelect), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onStalled => (super.noSuchMethod( - Invocation.getter(#onStalled), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.StorageEvent> get onStorage => (super.noSuchMethod( - Invocation.getter(#onStorage), Stream<_i2.StorageEvent>.empty()) - as _i4.Stream<_i2.StorageEvent>); - @override - _i4.Stream<_i2.Event> get onSubmit => (super - .noSuchMethod(Invocation.getter(#onSubmit), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onSuspend => (super.noSuchMethod( - Invocation.getter(#onSuspend), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onTimeUpdate => (super.noSuchMethod( - Invocation.getter(#onTimeUpdate), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.TouchEvent> get onTouchCancel => (super.noSuchMethod( - Invocation.getter(#onTouchCancel), Stream<_i2.TouchEvent>.empty()) - as _i4.Stream<_i2.TouchEvent>); - @override - _i4.Stream<_i2.TouchEvent> get onTouchEnd => (super.noSuchMethod( - Invocation.getter(#onTouchEnd), Stream<_i2.TouchEvent>.empty()) - as _i4.Stream<_i2.TouchEvent>); - @override - _i4.Stream<_i2.TouchEvent> get onTouchMove => (super.noSuchMethod( - Invocation.getter(#onTouchMove), Stream<_i2.TouchEvent>.empty()) - as _i4.Stream<_i2.TouchEvent>); - @override - _i4.Stream<_i2.TouchEvent> get onTouchStart => (super.noSuchMethod( - Invocation.getter(#onTouchStart), Stream<_i2.TouchEvent>.empty()) - as _i4.Stream<_i2.TouchEvent>); - @override - _i4.Stream<_i2.TransitionEvent> get onTransitionEnd => (super.noSuchMethod( - Invocation.getter(#onTransitionEnd), - Stream<_i2.TransitionEvent>.empty()) as _i4.Stream<_i2.TransitionEvent>); - @override - _i4.Stream<_i2.Event> get onUnload => (super - .noSuchMethod(Invocation.getter(#onUnload), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onVolumeChange => (super.noSuchMethod( - Invocation.getter(#onVolumeChange), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.Event> get onWaiting => (super.noSuchMethod( - Invocation.getter(#onWaiting), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); - @override - _i4.Stream<_i2.AnimationEvent> get onAnimationEnd => (super.noSuchMethod( - Invocation.getter(#onAnimationEnd), - Stream<_i2.AnimationEvent>.empty()) as _i4.Stream<_i2.AnimationEvent>); + (super.noSuchMethod(Invocation.getter(#onPlay), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onPlaying => + (super.noSuchMethod(Invocation.getter(#onPlaying), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.PopStateEvent> get onPopState => + (super.noSuchMethod(Invocation.getter(#onPopState), + returnValue: Stream<_i2.PopStateEvent>.empty()) + as _i4.Stream<_i2.PopStateEvent>); + @override + _i4.Stream<_i2.Event> get onProgress => + (super.noSuchMethod(Invocation.getter(#onProgress), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onRateChange => + (super.noSuchMethod(Invocation.getter(#onRateChange), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onReset => + (super.noSuchMethod(Invocation.getter(#onReset), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onResize => + (super.noSuchMethod(Invocation.getter(#onResize), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onScroll => + (super.noSuchMethod(Invocation.getter(#onScroll), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onSearch => + (super.noSuchMethod(Invocation.getter(#onSearch), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onSeeked => + (super.noSuchMethod(Invocation.getter(#onSeeked), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onSeeking => + (super.noSuchMethod(Invocation.getter(#onSeeking), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onSelect => + (super.noSuchMethod(Invocation.getter(#onSelect), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onStalled => + (super.noSuchMethod(Invocation.getter(#onStalled), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.StorageEvent> get onStorage => + (super.noSuchMethod(Invocation.getter(#onStorage), + returnValue: Stream<_i2.StorageEvent>.empty()) + as _i4.Stream<_i2.StorageEvent>); + @override + _i4.Stream<_i2.Event> get onSubmit => + (super.noSuchMethod(Invocation.getter(#onSubmit), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onSuspend => + (super.noSuchMethod(Invocation.getter(#onSuspend), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onTimeUpdate => + (super.noSuchMethod(Invocation.getter(#onTimeUpdate), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.TouchEvent> get onTouchCancel => + (super.noSuchMethod(Invocation.getter(#onTouchCancel), + returnValue: Stream<_i2.TouchEvent>.empty()) + as _i4.Stream<_i2.TouchEvent>); + @override + _i4.Stream<_i2.TouchEvent> get onTouchEnd => + (super.noSuchMethod(Invocation.getter(#onTouchEnd), + returnValue: Stream<_i2.TouchEvent>.empty()) + as _i4.Stream<_i2.TouchEvent>); + @override + _i4.Stream<_i2.TouchEvent> get onTouchMove => + (super.noSuchMethod(Invocation.getter(#onTouchMove), + returnValue: Stream<_i2.TouchEvent>.empty()) + as _i4.Stream<_i2.TouchEvent>); + @override + _i4.Stream<_i2.TouchEvent> get onTouchStart => + (super.noSuchMethod(Invocation.getter(#onTouchStart), + returnValue: Stream<_i2.TouchEvent>.empty()) + as _i4.Stream<_i2.TouchEvent>); + @override + _i4.Stream<_i2.TransitionEvent> get onTransitionEnd => + (super.noSuchMethod(Invocation.getter(#onTransitionEnd), + returnValue: Stream<_i2.TransitionEvent>.empty()) + as _i4.Stream<_i2.TransitionEvent>); + @override + _i4.Stream<_i2.Event> get onUnload => + (super.noSuchMethod(Invocation.getter(#onUnload), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onVolumeChange => + (super.noSuchMethod(Invocation.getter(#onVolumeChange), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.Event> get onWaiting => + (super.noSuchMethod(Invocation.getter(#onWaiting), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + @override + _i4.Stream<_i2.AnimationEvent> get onAnimationEnd => + (super.noSuchMethod(Invocation.getter(#onAnimationEnd), + returnValue: Stream<_i2.AnimationEvent>.empty()) + as _i4.Stream<_i2.AnimationEvent>); @override _i4.Stream<_i2.AnimationEvent> get onAnimationIteration => (super.noSuchMethod(Invocation.getter(#onAnimationIteration), - Stream<_i2.AnimationEvent>.empty()) + returnValue: Stream<_i2.AnimationEvent>.empty()) as _i4.Stream<_i2.AnimationEvent>); @override - _i4.Stream<_i2.AnimationEvent> get onAnimationStart => (super.noSuchMethod( - Invocation.getter(#onAnimationStart), - Stream<_i2.AnimationEvent>.empty()) as _i4.Stream<_i2.AnimationEvent>); + _i4.Stream<_i2.AnimationEvent> get onAnimationStart => + (super.noSuchMethod(Invocation.getter(#onAnimationStart), + returnValue: Stream<_i2.AnimationEvent>.empty()) + as _i4.Stream<_i2.AnimationEvent>); @override - _i4.Stream<_i2.Event> get onBeforeUnload => (super.noSuchMethod( - Invocation.getter(#onBeforeUnload), Stream<_i2.Event>.empty()) - as _i4.Stream<_i2.Event>); + _i4.Stream<_i2.Event> get onBeforeUnload => + (super.noSuchMethod(Invocation.getter(#onBeforeUnload), + returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); @override - _i4.Stream<_i2.WheelEvent> get onWheel => (super.noSuchMethod( - Invocation.getter(#onWheel), Stream<_i2.WheelEvent>.empty()) - as _i4.Stream<_i2.WheelEvent>); + _i4.Stream<_i2.WheelEvent> get onWheel => + (super.noSuchMethod(Invocation.getter(#onWheel), + returnValue: Stream<_i2.WheelEvent>.empty()) + as _i4.Stream<_i2.WheelEvent>); @override int get pageXOffset => - (super.noSuchMethod(Invocation.getter(#pageXOffset), 0) as int); + (super.noSuchMethod(Invocation.getter(#pageXOffset), returnValue: 0) + as int); @override int get pageYOffset => - (super.noSuchMethod(Invocation.getter(#pageYOffset), 0) as int); + (super.noSuchMethod(Invocation.getter(#pageYOffset), returnValue: 0) + as int); @override int get scrollX => - (super.noSuchMethod(Invocation.getter(#scrollX), 0) as int); + (super.noSuchMethod(Invocation.getter(#scrollX), returnValue: 0) as int); @override int get scrollY => - (super.noSuchMethod(Invocation.getter(#scrollY), 0) as int); + (super.noSuchMethod(Invocation.getter(#scrollY), returnValue: 0) as int); @override _i2.Events get on => - (super.noSuchMethod(Invocation.getter(#on), _FakeEvents()) as _i2.Events); + (super.noSuchMethod(Invocation.getter(#on), returnValue: _FakeEvents()) + as _i2.Events); @override int get hashCode => - (super.noSuchMethod(Invocation.getter(#hashCode), 0) as int); + (super.noSuchMethod(Invocation.getter(#hashCode), returnValue: 0) as int); @override - Type get runtimeType => - (super.noSuchMethod(Invocation.getter(#runtimeType), _FakeType()) - as Type); + Type get runtimeType => (super.noSuchMethod(Invocation.getter(#runtimeType), + returnValue: _FakeType()) as Type); @override _i2.WindowBase open(String? url, String? name, [String? options]) => - (super.noSuchMethod( - Invocation.method(#open, [url, name, options]), _FakeWindowBase()) - as _i2.WindowBase); + (super.noSuchMethod(Invocation.method(#open, [url, name, options]), + returnValue: _FakeWindowBase()) as _i2.WindowBase); @override int requestAnimationFrame(_i2.FrameRequestCallback? callback) => - (super.noSuchMethod( - Invocation.method(#requestAnimationFrame, [callback]), 0) as int); + (super.noSuchMethod(Invocation.method(#requestAnimationFrame, [callback]), + returnValue: 0) as int); @override void cancelAnimationFrame(int? id) => - super.noSuchMethod(Invocation.method(#cancelAnimationFrame, [id])); + super.noSuchMethod(Invocation.method(#cancelAnimationFrame, [id]), + returnValueForMissingStub: null); @override - _i4.Future<_i2.FileSystem> requestFileSystem(int? size, {bool? persistent}) => + _i4.Future<_i2.FileSystem> requestFileSystem(int? size, + {bool? persistent = false}) => (super.noSuchMethod( - Invocation.method( - #requestFileSystem, [size], {#persistent: persistent}), - Future.value(_FakeFileSystem())) as _i4.Future<_i2.FileSystem>); + Invocation.method( + #requestFileSystem, [size], {#persistent: persistent}), + returnValue: Future.value(_FakeFileSystem())) + as _i4.Future<_i2.FileSystem>); @override void cancelIdleCallback(int? handle) => - super.noSuchMethod(Invocation.method(#cancelIdleCallback, [handle])); + super.noSuchMethod(Invocation.method(#cancelIdleCallback, [handle]), + returnValueForMissingStub: null); @override bool confirm([String? message]) => - (super.noSuchMethod(Invocation.method(#confirm, [message]), false) - as bool); + (super.noSuchMethod(Invocation.method(#confirm, [message]), + returnValue: false) as bool); @override _i4.Future fetch(dynamic input, [Map? init]) => - (super.noSuchMethod( - Invocation.method(#fetch, [input, init]), Future.value(null)) - as _i4.Future); + (super.noSuchMethod(Invocation.method(#fetch, [input, init]), + returnValue: Future.value(null)) as _i4.Future); @override bool find(String? string, bool? caseSensitive, bool? backwards, bool? wrap, bool? wholeWord, bool? searchInFrames, bool? showDialog) => @@ -483,56 +521,64 @@ class MockWindow extends _i1.Mock implements _i2.Window { searchInFrames, showDialog ]), - false) as bool); + returnValue: false) as bool); @override _i2.StylePropertyMapReadonly getComputedStyleMap( _i2.Element? element, String? pseudoElement) => (super.noSuchMethod( - Invocation.method(#getComputedStyleMap, [element, pseudoElement]), - _FakeStylePropertyMapReadonly()) as _i2.StylePropertyMapReadonly); + Invocation.method(#getComputedStyleMap, [element, pseudoElement]), + returnValue: _FakeStylePropertyMapReadonly()) + as _i2.StylePropertyMapReadonly); @override List<_i2.CssRule> getMatchedCssRules( _i2.Element? element, String? pseudoElement) => (super.noSuchMethod( Invocation.method(#getMatchedCssRules, [element, pseudoElement]), - <_i2.CssRule>[]) as List<_i2.CssRule>); + returnValue: <_i2.CssRule>[]) as List<_i2.CssRule>); @override - _i2.MediaQueryList matchMedia(String? query) => (super.noSuchMethod( - Invocation.method(#matchMedia, [query]), _FakeMediaQueryList()) - as _i2.MediaQueryList); + _i2.MediaQueryList matchMedia(String? query) => + (super.noSuchMethod(Invocation.method(#matchMedia, [query]), + returnValue: _FakeMediaQueryList()) as _i2.MediaQueryList); @override void moveBy(int? x, int? y) => - super.noSuchMethod(Invocation.method(#moveBy, [x, y])); + super.noSuchMethod(Invocation.method(#moveBy, [x, y]), + returnValueForMissingStub: null); @override void postMessage(dynamic message, String? targetOrigin, [List? transfer]) => super.noSuchMethod( - Invocation.method(#postMessage, [message, targetOrigin, transfer])); + Invocation.method(#postMessage, [message, targetOrigin, transfer]), + returnValueForMissingStub: null); @override int requestIdleCallback(_i2.IdleRequestCallback? callback, [Map? options]) => (super.noSuchMethod( - Invocation.method(#requestIdleCallback, [callback, options]), 0) - as int); + Invocation.method(#requestIdleCallback, [callback, options]), + returnValue: 0) as int); @override void resizeBy(int? x, int? y) => - super.noSuchMethod(Invocation.method(#resizeBy, [x, y])); + super.noSuchMethod(Invocation.method(#resizeBy, [x, y]), + returnValueForMissingStub: null); @override void resizeTo(int? x, int? y) => - super.noSuchMethod(Invocation.method(#resizeTo, [x, y])); + super.noSuchMethod(Invocation.method(#resizeTo, [x, y]), + returnValueForMissingStub: null); @override _i4.Future<_i2.Entry> resolveLocalFileSystemUrl(String? url) => (super.noSuchMethod(Invocation.method(#resolveLocalFileSystemUrl, [url]), - Future.value(_FakeEntry())) as _i4.Future<_i2.Entry>); + returnValue: Future.value(_FakeEntry())) as _i4.Future<_i2.Entry>); @override String atob(String? atob) => - (super.noSuchMethod(Invocation.method(#atob, [atob]), '') as String); + (super.noSuchMethod(Invocation.method(#atob, [atob]), returnValue: '') + as String); @override String btoa(String? btoa) => - (super.noSuchMethod(Invocation.method(#btoa, [btoa]), '') as String); + (super.noSuchMethod(Invocation.method(#btoa, [btoa]), returnValue: '') + as String); @override void moveTo(_i5.Point? p) => - super.noSuchMethod(Invocation.method(#moveTo, [p])); + super.noSuchMethod(Invocation.method(#moveTo, [p]), + returnValueForMissingStub: null); @override _i3.SqlDatabase openDatabase(String? name, String? version, String? displayName, int? estimatedSize, @@ -540,27 +586,31 @@ class MockWindow extends _i1.Mock implements _i2.Window { (super.noSuchMethod( Invocation.method(#openDatabase, [name, version, displayName, estimatedSize, creationCallback]), - _FakeSqlDatabase()) as _i3.SqlDatabase); + returnValue: _FakeSqlDatabase()) as _i3.SqlDatabase); @override void addEventListener(String? type, _i2.EventListener? listener, [bool? useCapture]) => super.noSuchMethod( - Invocation.method(#addEventListener, [type, listener, useCapture])); + Invocation.method(#addEventListener, [type, listener, useCapture]), + returnValueForMissingStub: null); @override void removeEventListener(String? type, _i2.EventListener? listener, [bool? useCapture]) => - super.noSuchMethod(Invocation.method( - #removeEventListener, [type, listener, useCapture])); + super.noSuchMethod( + Invocation.method(#removeEventListener, [type, listener, useCapture]), + returnValueForMissingStub: null); @override bool dispatchEvent(_i2.Event? event) => - (super.noSuchMethod(Invocation.method(#dispatchEvent, [event]), false) - as bool); + (super.noSuchMethod(Invocation.method(#dispatchEvent, [event]), + returnValue: false) as bool); @override bool operator ==(Object? other) => - (super.noSuchMethod(Invocation.method(#==, [other]), false) as bool); + (super.noSuchMethod(Invocation.method(#==, [other]), returnValue: false) + as bool); @override String toString() => - (super.noSuchMethod(Invocation.method(#toString, []), '') as String); + (super.noSuchMethod(Invocation.method(#toString, []), returnValue: '') + as String); } /// A class which mocks [Navigator]. @@ -573,92 +623,104 @@ class MockNavigator extends _i1.Mock implements _i2.Navigator { @override String get language => - (super.noSuchMethod(Invocation.getter(#language), '') as String); + (super.noSuchMethod(Invocation.getter(#language), returnValue: '') + as String); @override _i2.Geolocation get geolocation => - (super.noSuchMethod(Invocation.getter(#geolocation), _FakeGeolocation()) - as _i2.Geolocation); + (super.noSuchMethod(Invocation.getter(#geolocation), + returnValue: _FakeGeolocation()) as _i2.Geolocation); @override String get vendor => - (super.noSuchMethod(Invocation.getter(#vendor), '') as String); + (super.noSuchMethod(Invocation.getter(#vendor), returnValue: '') + as String); @override String get vendorSub => - (super.noSuchMethod(Invocation.getter(#vendorSub), '') as String); + (super.noSuchMethod(Invocation.getter(#vendorSub), returnValue: '') + as String); @override String get appCodeName => - (super.noSuchMethod(Invocation.getter(#appCodeName), '') as String); + (super.noSuchMethod(Invocation.getter(#appCodeName), returnValue: '') + as String); @override String get appName => - (super.noSuchMethod(Invocation.getter(#appName), '') as String); + (super.noSuchMethod(Invocation.getter(#appName), returnValue: '') + as String); @override String get appVersion => - (super.noSuchMethod(Invocation.getter(#appVersion), '') as String); + (super.noSuchMethod(Invocation.getter(#appVersion), returnValue: '') + as String); @override String get product => - (super.noSuchMethod(Invocation.getter(#product), '') as String); + (super.noSuchMethod(Invocation.getter(#product), returnValue: '') + as String); @override String get userAgent => - (super.noSuchMethod(Invocation.getter(#userAgent), '') as String); + (super.noSuchMethod(Invocation.getter(#userAgent), returnValue: '') + as String); @override int get hashCode => - (super.noSuchMethod(Invocation.getter(#hashCode), 0) as int); + (super.noSuchMethod(Invocation.getter(#hashCode), returnValue: 0) as int); @override - Type get runtimeType => - (super.noSuchMethod(Invocation.getter(#runtimeType), _FakeType()) - as Type); + Type get runtimeType => (super.noSuchMethod(Invocation.getter(#runtimeType), + returnValue: _FakeType()) as Type); @override List<_i2.Gamepad?> getGamepads() => - (super.noSuchMethod(Invocation.method(#getGamepads, []), <_i2.Gamepad?>[]) - as List<_i2.Gamepad?>); + (super.noSuchMethod(Invocation.method(#getGamepads, []), + returnValue: <_i2.Gamepad?>[]) as List<_i2.Gamepad?>); @override - _i4.Future<_i2.MediaStream> getUserMedia({dynamic audio, dynamic video}) => + _i4.Future<_i2.MediaStream> getUserMedia( + {dynamic audio = false, dynamic video = false}) => (super.noSuchMethod( Invocation.method(#getUserMedia, [], {#audio: audio, #video: video}), - Future.value(_FakeMediaStream())) as _i4.Future<_i2.MediaStream>); + returnValue: + Future.value(_FakeMediaStream())) as _i4.Future<_i2.MediaStream>); @override - _i4.Future getBattery() => (super - .noSuchMethod(Invocation.method(#getBattery, []), Future.value(null)) - as _i4.Future); + _i4.Future getBattery() => + (super.noSuchMethod(Invocation.method(#getBattery, []), + returnValue: Future.value(null)) as _i4.Future); @override _i4.Future<_i2.RelatedApplication> getInstalledRelatedApps() => (super.noSuchMethod(Invocation.method(#getInstalledRelatedApps, []), - Future.value(_FakeRelatedApplication())) + returnValue: Future.value(_FakeRelatedApplication())) as _i4.Future<_i2.RelatedApplication>); @override - _i4.Future getVRDisplays() => (super.noSuchMethod( - Invocation.method(#getVRDisplays, []), Future.value(null)) - as _i4.Future); + _i4.Future getVRDisplays() => + (super.noSuchMethod(Invocation.method(#getVRDisplays, []), + returnValue: Future.value(null)) as _i4.Future); @override void registerProtocolHandler(String? scheme, String? url, String? title) => super.noSuchMethod( - Invocation.method(#registerProtocolHandler, [scheme, url, title])); + Invocation.method(#registerProtocolHandler, [scheme, url, title]), + returnValueForMissingStub: null); @override _i4.Future requestKeyboardLock([List? keyCodes]) => (super.noSuchMethod(Invocation.method(#requestKeyboardLock, [keyCodes]), - Future.value(null)) as _i4.Future); + returnValue: Future.value(null)) as _i4.Future); @override _i4.Future requestMidiAccess([Map? options]) => (super.noSuchMethod(Invocation.method(#requestMidiAccess, [options]), - Future.value(null)) as _i4.Future); + returnValue: Future.value(null)) as _i4.Future); @override _i4.Future requestMediaKeySystemAccess(String? keySystem, List>? supportedConfigurations) => (super.noSuchMethod( Invocation.method(#requestMediaKeySystemAccess, [keySystem, supportedConfigurations]), - Future.value(null)) as _i4.Future); + returnValue: Future.value(null)) as _i4.Future); @override bool sendBeacon(String? url, Object? data) => - (super.noSuchMethod(Invocation.method(#sendBeacon, [url, data]), false) - as bool); + (super.noSuchMethod(Invocation.method(#sendBeacon, [url, data]), + returnValue: false) as bool); @override _i4.Future share([Map? data]) => - (super.noSuchMethod(Invocation.method(#share, [data]), Future.value(null)) - as _i4.Future); + (super.noSuchMethod(Invocation.method(#share, [data]), + returnValue: Future.value(null)) as _i4.Future); @override bool operator ==(Object? other) => - (super.noSuchMethod(Invocation.method(#==, [other]), false) as bool); + (super.noSuchMethod(Invocation.method(#==, [other]), returnValue: false) + as bool); @override String toString() => - (super.noSuchMethod(Invocation.method(#toString, []), '') as String); + (super.noSuchMethod(Invocation.method(#toString, []), returnValue: '') + as String); } diff --git a/packages/url_launcher/url_launcher_web/example/run_test.sh b/packages/url_launcher/url_launcher_web/example/run_test.sh index 1960bde25d17..dabf9a8630e6 100755 --- a/packages/url_launcher/url_launcher_web/example/run_test.sh +++ b/packages/url_launcher/url_launcher_web/example/run_test.sh @@ -13,11 +13,11 @@ if pgrep -lf chromedriver > /dev/null; then if [ $# -eq 0 ]; then echo "No target specified, running all tests..." - find integration_test/ -iname *_test.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_test_driver.dart --target='{}' + find integration_test/ -iname *_test.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_test.dart --target='{}' else echo "Running test target: $1..." set -x - flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_test_driver.dart --target=$1 + flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_test.dart --target=$1 fi else diff --git a/packages/url_launcher/url_launcher_web/example/test_driver/integration_test_driver.dart b/packages/url_launcher/url_launcher_web/example/test_driver/integration_test.dart similarity index 100% rename from packages/url_launcher/url_launcher_web/example/test_driver/integration_test_driver.dart rename to packages/url_launcher/url_launcher_web/example/test_driver/integration_test.dart diff --git a/script/tool/lib/src/drive_examples_command.dart b/script/tool/lib/src/drive_examples_command.dart index de5dc9ebfc62..54e0eee26425 100644 --- a/script/tool/lib/src/drive_examples_command.dart +++ b/script/tool/lib/src/drive_examples_command.dart @@ -146,6 +146,7 @@ Tried searching for the following: driveArgs.addAll([ '-d', 'web-server', + '--web-port=7357', '--browser-name=chrome', ]); } diff --git a/script/tool/test/drive_examples_command_test.dart b/script/tool/test/drive_examples_command_test.dart index 65bdf99c165d..58b8fb0d087d 100644 --- a/script/tool/test/drive_examples_command_test.dart +++ b/script/tool/test/drive_examples_command_test.dart @@ -427,6 +427,7 @@ void main() { 'drive', '-d', 'web-server', + '--web-port=7357', '--browser-name=chrome', '--driver', driverTestPath, From 7b9ac6b0c20da2ae3cdbaf4f2a06a9b9eb6e1474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl?= <32639467+danielroek@users.noreply.github.com> Date: Sat, 20 Mar 2021 17:28:14 +0100 Subject: [PATCH 0286/1565] [quick_actions] 2/3 Quick actions federated platform interface (#3735) * Moved quickactions to a subfolder * Added platform interface with tests * Added exports * Formatted, made initialize return Future instead of void * Fixed formatting * formatting * Fixed analyze issue with import * Fixed formatting * Fixed formatting * Added license in files * Removed accidental \\\ * changed license to Flutter 2017 * Moved quickactions to a subfolder * Added platform interface with tests * Added exports * Formatted, made initialize return Future instead of void * Fixed formatting * formatting * Fixed analyze issue with import * Fixed formatting * Fixed formatting * Added license in files * Removed accidental \\\ * changed license to Flutter 2017 * Implemented feedback * Changed 2017 to 2013 * Changed 2017 to 2013 * Implemented feedback. --- packages/quick_actions/AUTHORS | 66 -------- .../test/quick_actions_test.dart | 1 + .../CHANGELOG.md | 3 + .../quick_actions_platform_interface/LICENSE | 25 +++ .../README.md | 26 +++ .../method_channel_quick_actions.dart | 52 ++++++ .../quick_actions_platform.dart | 55 +++++++ .../lib/quick_actions_platform_interface.dart | 6 + .../lib/types/quick_action_handler.dart | 8 + .../lib/types/shortcut_item.dart | 26 +++ .../lib/types/types.dart | 6 + .../pubspec.yaml | 22 +++ .../method_channel_quick_actions_test.dart | 155 ++++++++++++++++++ ...quick_actions_platform_interface_test.dart | 73 +++++++++ 14 files changed, 458 insertions(+), 66 deletions(-) delete mode 100644 packages/quick_actions/AUTHORS create mode 100644 packages/quick_actions/quick_actions_platform_interface/CHANGELOG.md create mode 100644 packages/quick_actions/quick_actions_platform_interface/LICENSE create mode 100644 packages/quick_actions/quick_actions_platform_interface/README.md create mode 100644 packages/quick_actions/quick_actions_platform_interface/lib/method_channel/method_channel_quick_actions.dart create mode 100644 packages/quick_actions/quick_actions_platform_interface/lib/platform_interface/quick_actions_platform.dart create mode 100644 packages/quick_actions/quick_actions_platform_interface/lib/quick_actions_platform_interface.dart create mode 100644 packages/quick_actions/quick_actions_platform_interface/lib/types/quick_action_handler.dart create mode 100644 packages/quick_actions/quick_actions_platform_interface/lib/types/shortcut_item.dart create mode 100644 packages/quick_actions/quick_actions_platform_interface/lib/types/types.dart create mode 100644 packages/quick_actions/quick_actions_platform_interface/pubspec.yaml create mode 100644 packages/quick_actions/quick_actions_platform_interface/test/method_channel_quick_actions_test.dart create mode 100644 packages/quick_actions/quick_actions_platform_interface/test/quick_actions_platform_interface_test.dart diff --git a/packages/quick_actions/AUTHORS b/packages/quick_actions/AUTHORS deleted file mode 100644 index 493a0b4ef9c2..000000000000 --- a/packages/quick_actions/AUTHORS +++ /dev/null @@ -1,66 +0,0 @@ -# Below is a list of people and organizations that have contributed -# to the Flutter project. Names should be added to the list like so: -# -# Name/Organization - -Google Inc. -The Chromium Authors -German Saprykin -Benjamin Sauer -larsenthomasj@gmail.com -Ali Bitek -Pol Batlló -Anatoly Pulyaevskiy -Hayden Flinner -Stefano Rodriguez -Salvatore Giordano -Brian Armstrong -Paul DeMarco -Fabricio Nogueira -Simon Lightfoot -Ashton Thomas -Thomas Danner -Diego Velásquez -Hajime Nakamura -Tuyển Vũ Xuân -Miguel Ruivo -Sarthak Verma -Mike Diarmid -Invertase -Elliot Hesp -Vince Varga -Aawaz Gyawali -EUI Limited -Katarina Sheremet -Thomas Stockx -Sarbagya Dhaubanjar -Ozkan Eksi -Rishab Nayak -ko2ic -Jonathan Younger -Jose Sanchez -Debkanchan Samadder -Audrius Karosevicius -Lukasz Piliszczuk -SoundReply Solutions GmbH -Rafal Wachol -Pau Picas -Christian Weder -Alexandru Tuca -Christian Weder -Rhodes Davis Jr. -Luigi Agosti -Quentin Le Guennec -Koushik Ravikumar -Nissim Dsilva -Giancarlo Rocha -Ryo Miyake -Théo Champion -Kazuki Yamaguchi -Eitan Schwartz -Chris Rutkowski -Juan Alvarez -Aleksandr Yurkovskiy -Anton Borries -Alex Li -Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/quick_actions/quick_actions/test/quick_actions_test.dart b/packages/quick_actions/quick_actions/test/quick_actions_test.dart index f2b9a9aefc8d..ccb593f149fb 100644 --- a/packages/quick_actions/quick_actions/test/quick_actions_test.dart +++ b/packages/quick_actions/quick_actions/test/quick_actions_test.dart @@ -1,6 +1,7 @@ // Copyright 2013 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'; diff --git a/packages/quick_actions/quick_actions_platform_interface/CHANGELOG.md b/packages/quick_actions/quick_actions_platform_interface/CHANGELOG.md new file mode 100644 index 000000000000..4b63991e9c4a --- /dev/null +++ b/packages/quick_actions/quick_actions_platform_interface/CHANGELOG.md @@ -0,0 +1,3 @@ +# 1.0.0 + +* Initial release of quick_actions_platform_interface diff --git a/packages/quick_actions/quick_actions_platform_interface/LICENSE b/packages/quick_actions/quick_actions_platform_interface/LICENSE new file mode 100644 index 000000000000..4c99d1dcb85e --- /dev/null +++ b/packages/quick_actions/quick_actions_platform_interface/LICENSE @@ -0,0 +1,25 @@ +Copyright 2013 The Chromium Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/quick_actions/quick_actions_platform_interface/README.md b/packages/quick_actions/quick_actions_platform_interface/README.md new file mode 100644 index 000000000000..ce8136ee9614 --- /dev/null +++ b/packages/quick_actions/quick_actions_platform_interface/README.md @@ -0,0 +1,26 @@ +# quick_actions_platform_interface + +A common platform interface for the [`quick_actions`][1] plugin. + +This interface allows platform-specific implementations of the `quick_actions` +plugin, as well as the plugin itself, to ensure they are supporting the +same interface. + +# Usage + +To implement a new platform-specific implementation of `quick_actions`, extend +[`QuickActionsPlatform`][2] with an implementation that performs the +platform-specific behavior, and when you register your plugin, set the default +`QuickActionsPlatform` by calling +`QuickActionsPlatform.instance = MyPlatformQuickActions()`. + +# Note on breaking changes + +Strongly prefer non-breaking changes (such as adding a method to the interface) +over breaking changes for this package. + +See https://flutter.dev/go/platform-interface-breaking-changes for a discussion +on why a less-clean interface is preferable to a breaking change. + +[1]: ../quick_actions +[2]: lib/quick_actions_platform_interface.dart diff --git a/packages/quick_actions/quick_actions_platform_interface/lib/method_channel/method_channel_quick_actions.dart b/packages/quick_actions/quick_actions_platform_interface/lib/method_channel/method_channel_quick_actions.dart new file mode 100644 index 000000000000..8172fe017a4d --- /dev/null +++ b/packages/quick_actions/quick_actions_platform_interface/lib/method_channel/method_channel_quick_actions.dart @@ -0,0 +1,52 @@ +// Copyright 2013 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/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:meta/meta.dart' show visibleForTesting; +import 'package:quick_actions_platform_interface/types/types.dart'; + +import '../platform_interface/quick_actions_platform.dart'; + +final MethodChannel _channel = + MethodChannel('plugins.flutter.io/quick_actions'); + +/// An implementation of [QuickActionsPlatform] that uses method channels. +class MethodChannelQuickActions extends QuickActionsPlatform { + /// The MethodChannel that is being used by this implementation of the plugin. + @visibleForTesting + MethodChannel get channel => _channel; + + @override + Future initialize(QuickActionHandler handler) async { + channel.setMethodCallHandler((MethodCall call) async { + assert(call.method == 'launch'); + handler(call.arguments); + }); + final String? action = + await channel.invokeMethod('getLaunchAction'); + if (action != null) { + handler(action); + } + } + + @override + Future setShortcutItems(List items) async { + final List> itemsList = + items.map(_serializeItem).toList(); + await channel.invokeMethod('setShortcutItems', itemsList); + } + + @override + Future clearShortcutItems() => + channel.invokeMethod('clearShortcutItems'); + + Map _serializeItem(ShortcutItem item) { + return { + 'type': item.type, + 'localizedTitle': item.localizedTitle, + 'icon': item.icon, + }; + } +} diff --git a/packages/quick_actions/quick_actions_platform_interface/lib/platform_interface/quick_actions_platform.dart b/packages/quick_actions/quick_actions_platform_interface/lib/platform_interface/quick_actions_platform.dart new file mode 100644 index 000000000000..b15fb8b43233 --- /dev/null +++ b/packages/quick_actions/quick_actions_platform_interface/lib/platform_interface/quick_actions_platform.dart @@ -0,0 +1,55 @@ +// Copyright 2013 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:plugin_platform_interface/plugin_platform_interface.dart'; +import 'package:quick_actions_platform_interface/types/types.dart'; + +import '../method_channel/method_channel_quick_actions.dart'; + +/// The interface that implementations of quick_actions must implement. +/// +/// Platform implementations should extend this class rather than implement it as `quick_actions` +/// does not consider newly added methods to be breaking changes. Extending this class +/// (using `extends`) ensures that the subclass will get the default implementation, while +/// platform implementations that `implements` this interface will be broken by newly added +/// [QuickActionsPlatform] methods. +abstract class QuickActionsPlatform extends PlatformInterface { + /// Constructs a QuickActionsPlatform. + QuickActionsPlatform() : super(token: _token); + + static final Object _token = Object(); + + static QuickActionsPlatform _instance = MethodChannelQuickActions(); + + /// The default instance of [QuickActionsPlatform] to use. + /// + /// Defaults to [MethodChannelQuickActions]. + static QuickActionsPlatform get instance => _instance; + + /// Platform-specific plugins should set this with their own platform-specific + /// class that extends [QuickActionsPlatform] when they register themselves. + // TODO(amirh): Extract common platform interface logic. + // https://github.com/flutter/flutter/issues/43368 + static set instance(QuickActionsPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + _instance = instance; + } + + /// Initializes this plugin. + /// + /// Call this once before any further interaction with the the plugin. + Future initialize(QuickActionHandler handler) async { + throw UnimplementedError("initialize() has not been implemented."); + } + + /// Sets the [ShortcutItem]s to become the app's quick actions. + Future setShortcutItems(List items) async { + throw UnimplementedError("setShortcutItems() has not been implemented."); + } + + /// Removes all [ShortcutItem]s registered for the app. + Future clearShortcutItems() { + throw UnimplementedError("clearShortcutItems() has not been implemented."); + } +} diff --git a/packages/quick_actions/quick_actions_platform_interface/lib/quick_actions_platform_interface.dart b/packages/quick_actions/quick_actions_platform_interface/lib/quick_actions_platform_interface.dart new file mode 100644 index 000000000000..51bed8f230a8 --- /dev/null +++ b/packages/quick_actions/quick_actions_platform_interface/lib/quick_actions_platform_interface.dart @@ -0,0 +1,6 @@ +// Copyright 2013 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. + +export 'package:quick_actions_platform_interface/platform_interface/quick_actions_platform.dart'; +export 'package:quick_actions_platform_interface/types/types.dart'; diff --git a/packages/quick_actions/quick_actions_platform_interface/lib/types/quick_action_handler.dart b/packages/quick_actions/quick_actions_platform_interface/lib/types/quick_action_handler.dart new file mode 100644 index 000000000000..27c6bb494dfd --- /dev/null +++ b/packages/quick_actions/quick_actions_platform_interface/lib/types/quick_action_handler.dart @@ -0,0 +1,8 @@ +// Copyright 2013 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. + +/// Handler for a quick action launch event. +/// +/// The argument [type] corresponds to the [ShortcutItem]'s field. +typedef void QuickActionHandler(String type); diff --git a/packages/quick_actions/quick_actions_platform_interface/lib/types/shortcut_item.dart b/packages/quick_actions/quick_actions_platform_interface/lib/types/shortcut_item.dart new file mode 100644 index 000000000000..1d84e16ac996 --- /dev/null +++ b/packages/quick_actions/quick_actions_platform_interface/lib/types/shortcut_item.dart @@ -0,0 +1,26 @@ +// Copyright 2013 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. + +/// Home screen quick-action shortcut item. +class ShortcutItem { + /// Constructs an instance with the given [type], [localizedTitle], and + /// [icon]. + /// + /// Only [icon] should be nullable. It will remain `null` if unset. + const ShortcutItem({ + required this.type, + required this.localizedTitle, + this.icon, + }); + + /// The identifier of this item; should be unique within the app. + final String type; + + /// Localized title of the item. + final String localizedTitle; + + /// Name of native resource (xcassets etc; NOT a Flutter asset) to be + /// displayed as the icon for this item. + final String? icon; +} diff --git a/packages/quick_actions/quick_actions_platform_interface/lib/types/types.dart b/packages/quick_actions/quick_actions_platform_interface/lib/types/types.dart new file mode 100644 index 000000000000..ab85ca8260ce --- /dev/null +++ b/packages/quick_actions/quick_actions_platform_interface/lib/types/types.dart @@ -0,0 +1,6 @@ +// Copyright 2013 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. + +export 'quick_action_handler.dart'; +export 'shortcut_item.dart'; diff --git a/packages/quick_actions/quick_actions_platform_interface/pubspec.yaml b/packages/quick_actions/quick_actions_platform_interface/pubspec.yaml new file mode 100644 index 000000000000..eb1ff40bb4a4 --- /dev/null +++ b/packages/quick_actions/quick_actions_platform_interface/pubspec.yaml @@ -0,0 +1,22 @@ +name: quick_actions_platform_interface +description: A common platform interface for the quick_actions plugin. +homepage: https://github.com/flutter/plugins/tree/master/packages/quick_actions/quick_actions_platform_interface +# NOTE: We strongly prefer non-breaking changes, even at the expense of a +# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes +version: 1.0.0 + +dependencies: + flutter: + sdk: flutter + meta: ^1.3.0 + plugin_platform_interface: ^2.0.0 + +dev_dependencies: + flutter_test: + sdk: flutter + mockito: ^5.0.1 + pedantic: ^1.11.0 + +environment: + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.22.0" diff --git a/packages/quick_actions/quick_actions_platform_interface/test/method_channel_quick_actions_test.dart b/packages/quick_actions/quick_actions_platform_interface/test/method_channel_quick_actions_test.dart new file mode 100644 index 000000000000..f3e172e207fe --- /dev/null +++ b/packages/quick_actions/quick_actions_platform_interface/test/method_channel_quick_actions_test.dart @@ -0,0 +1,155 @@ +// Copyright 2013 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 'package:flutter_test/flutter_test.dart'; +import 'package:quick_actions_platform_interface/method_channel/method_channel_quick_actions.dart'; +import 'package:quick_actions_platform_interface/types/shortcut_item.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('$MethodChannelQuickActions', () { + MethodChannelQuickActions quickActions = MethodChannelQuickActions(); + + final List log = []; + + setUp(() { + quickActions.channel + .setMockMethodCallHandler((MethodCall methodCall) async { + log.add(methodCall); + return ''; + }); + + log.clear(); + }); + + group('#initialize', () { + test('passes getLaunchAction on launch method', () { + quickActions.initialize((type) { + 'launch'; + }); + + expect( + log, + [ + isMethodCall('getLaunchAction', arguments: null), + ], + ); + }); + + test('initialize', () async { + final Completer quickActionsHandler = Completer(); + await quickActions + .initialize((_) => quickActionsHandler.complete(true)); + expect( + log, + [ + isMethodCall('getLaunchAction', arguments: null), + ], + ); + log.clear(); + + expect(quickActionsHandler.future, completion(isTrue)); + }); + }); + + group('#setShortCutItems', () { + test('passes shortcutItem through channel', () { + quickActions.initialize((type) { + 'launch'; + }); + quickActions.setShortcutItems([ + ShortcutItem(type: 'test', localizedTitle: 'title', icon: 'icon.svg') + ]); + + expect( + log, + [ + isMethodCall('getLaunchAction', arguments: null), + isMethodCall('setShortcutItems', arguments: [ + { + 'type': 'test', + 'localizedTitle': 'title', + 'icon': 'icon.svg', + } + ]), + ], + ); + }); + + test('setShortcutItems with demo data', () async { + const String type = 'type'; + const String localizedTitle = 'localizedTitle'; + const String icon = 'icon'; + await quickActions.setShortcutItems( + const [ + ShortcutItem(type: type, localizedTitle: localizedTitle, icon: icon) + ], + ); + expect( + log, + [ + isMethodCall( + 'setShortcutItems', + arguments: >[ + { + 'type': type, + 'localizedTitle': localizedTitle, + 'icon': icon, + } + ], + ), + ], + ); + log.clear(); + }); + }); + + group('#clearShortCutItems', () { + test('send clearShortcutItems through channel', () { + quickActions.initialize((type) { + 'launch'; + }); + quickActions.clearShortcutItems(); + + expect( + log, + [ + isMethodCall('getLaunchAction', arguments: null), + isMethodCall('clearShortcutItems', arguments: null), + ], + ); + }); + + test('clearShortcutItems', () { + quickActions.clearShortcutItems(); + expect( + log, + [ + isMethodCall('clearShortcutItems', arguments: null), + ], + ); + log.clear(); + }); + }); + }); + + group('$ShortcutItem', () { + test('Shortcut item can be constructed', () { + const String type = 'type'; + const String localizedTitle = 'title'; + const String icon = 'foo'; + + const ShortcutItem item = + ShortcutItem(type: type, localizedTitle: localizedTitle, icon: icon); + + expect(item.type, type); + expect(item.localizedTitle, localizedTitle); + expect(item.icon, icon); + }); + }); +} diff --git a/packages/quick_actions/quick_actions_platform_interface/test/quick_actions_platform_interface_test.dart b/packages/quick_actions/quick_actions_platform_interface/test/quick_actions_platform_interface_test.dart new file mode 100644 index 000000000000..8ce40816217f --- /dev/null +++ b/packages/quick_actions/quick_actions_platform_interface/test/quick_actions_platform_interface_test.dart @@ -0,0 +1,73 @@ +// Copyright 2013 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_test/flutter_test.dart'; +import 'package:quick_actions_platform_interface/method_channel/method_channel_quick_actions.dart'; +import 'package:quick_actions_platform_interface/platform_interface/quick_actions_platform.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('$QuickActionsPlatform', () { + test('$MethodChannelQuickActions is the default instance', () { + expect(QuickActionsPlatform.instance, isA()); + }); + + test('Cannot be implemented with `implements`', () { + expect(() { + QuickActionsPlatform.instance = ImplementsQuickActionsPlatform(); + }, throwsNoSuchMethodError); + }); + + test('Can be extended', () { + QuickActionsPlatform.instance = ExtendsQuickActionsPlatform(); + }); + + test( + 'Default implementation of initialize() should throw unimplemented error', + () { + // Arrange + final QuickActionsPlatform = ExtendsQuickActionsPlatform(); + + // Act & Assert + expect( + () => QuickActionsPlatform.initialize((type) {}), + throwsUnimplementedError, + ); + }); + + test( + 'Default implementation of setShortcutItems() should throw unimplemented error', + () { + // Arrange + final QuickActionsPlatform = ExtendsQuickActionsPlatform(); + + // Act & Assert + expect( + () => QuickActionsPlatform.setShortcutItems([]), + throwsUnimplementedError, + ); + }); + + test( + 'Default implementation of clearShortcutItems() should throw unimplemented error', + () { + // Arrange + final QuickActionsPlatform = ExtendsQuickActionsPlatform(); + + // Act & Assert + expect( + () => QuickActionsPlatform.clearShortcutItems(), + throwsUnimplementedError, + ); + }); + }); +} + +class ImplementsQuickActionsPlatform implements QuickActionsPlatform { + @override + dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +} + +class ExtendsQuickActionsPlatform extends QuickActionsPlatform {} From 8621694430d0a164c358ab590519742af88cc2f4 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Mon, 22 Mar 2021 11:49:45 +0100 Subject: [PATCH 0287/1565] Update LICENSE (#3741) --- packages/quick_actions/quick_actions_platform_interface/LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/quick_actions/quick_actions_platform_interface/LICENSE b/packages/quick_actions/quick_actions_platform_interface/LICENSE index 4c99d1dcb85e..c6823b81eb84 100644 --- a/packages/quick_actions/quick_actions_platform_interface/LICENSE +++ b/packages/quick_actions/quick_actions_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2013 The Chromium Authors. All rights reserved. +Copyright 2013 The Flutter Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: From 7173380dd3f573877c0acd2b4f56e3df5a9c7c25 Mon Sep 17 00:00:00 2001 From: Taha Tesser Date: Tue, 23 Mar 2021 20:46:03 +0200 Subject: [PATCH 0288/1565] [url_launcher] Update readme for URL schemes on iOS (#3252) --- .../url_launcher/url_launcher/CHANGELOG.md | 4 ++++ packages/url_launcher/url_launcher/README.md | 18 +++++++++++++++++- .../url_launcher/url_launcher/pubspec.yaml | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index 9741f53ed329..f732fa58f8c6 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.0.3 + +* Updat README notes about URL schemes on iOS + ## 6.0.2 * Update platform_plugin_interface version requirement. diff --git a/packages/url_launcher/url_launcher/README.md b/packages/url_launcher/url_launcher/README.md index daf21738d9b7..31fed9a833f1 100644 --- a/packages/url_launcher/url_launcher/README.md +++ b/packages/url_launcher/url_launcher/README.md @@ -8,6 +8,22 @@ iOS, Android, web, Windows, macOS, and Linux. ## Usage To use this plugin, add `url_launcher` as a [dependency in your pubspec.yaml file](https://flutter.dev/platform-plugins/). +## Installation + +### iOS +Add any URL schemes passed to `canLaunch` as `LSApplicationQueriesSchemes` entries in your Info.plist file. + +Example: +``` +LSApplicationQueriesSchemes + + https + http + +``` + +See [`-[UIApplication canOpenURL:]`](https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl) for more details. + ### Example ``` dart @@ -97,4 +113,4 @@ By default, Android opens up a browser when handling URLs. You can pass If you do this for a URL of a page containing JavaScript, make sure to pass in `enableJavaScript: true`, or else the launch method will not work properly. On iOS, the default behavior is to open all web URLs within the app. Everything -else is redirected to the app handler. +else is redirected to the app handler. \ No newline at end of file diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index 7a4d1820fb1f..c8c5163d0e97 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -2,7 +2,7 @@ name: url_launcher description: Flutter plugin for launching a URL. Supports web, phone, SMS, and email schemes. homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher -version: 6.0.2 +version: 6.0.3 flutter: plugin: From 9548bc27af5da89544e8b1d8c31d12aaa9d673ca Mon Sep 17 00:00:00 2001 From: godofredoc <54371434+godofredoc@users.noreply.github.com> Date: Tue, 23 Mar 2021 13:48:22 -0700 Subject: [PATCH 0289/1565] Use flutter gcp project for linux tasks. (#3733) * Use flutter gcp project for linux tasks. Bug: https://github.com/flutter/flutter/issues/77624 * Merge upstream changes and change cluster. * Add test_script back. --- .cirrus.yml | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index c2bbd35e15e7..e9db1b7b6bf8 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,7 +1,8 @@ +gcp_credentials: ENCRYPTED[ec898795b6f1b54f9cc2ab4104909f1053651f65fcab96397cfdc33dae6df5fd0fa972e29ba19f4f95125de844ab1641] + # Don't run on release tags since it creates O(n^2) tasks where n is the # number of plugins only_if: $CIRRUS_TAG == '' -use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' && $CIRRUS_PR == '' env: INTEGRATION_TEST_PATH: "./packages/integration_test" CHANNEL: "master" # Default to master when not explicitly set by a task. @@ -32,8 +33,13 @@ macos_template: &MACOS_TEMPLATE # concurrency limits. task: << : *FLUTTER_UPGRADE_TEMPLATE - container: + gke_container: dockerfile: .ci/Dockerfile + builder_image_name: docker-builder # gce vm image + builder_image_project: flutter-cirrus + cluster_name: test-cluster + zone: us-central1-a + namespace: default matrix: ### Platform-agnostic tasks ### - name: plugin_tools_tests @@ -118,8 +124,13 @@ task: # for non-credit runs. task: << : *FLUTTER_UPGRADE_TEMPLATE - container: + gke_container: dockerfile: .ci/Dockerfile + builder_image_name: docker-builder # gce vm image + builder_image_project: flutter-cirrus + cluster_name: test-cluster + zone: us-central1-a + namespace: default cpu: 4 memory: 12G matrix: From 9cd84bdba7fcb18750f9916e3cad70963950709b Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Wed, 24 Mar 2021 15:35:57 +0100 Subject: [PATCH 0290/1565] [camera] Fix iOS rotation issue (#3591) * Fix iOS rotation issue * Fix orientation issues on iOS * Merged with master and added test * Test RotationBox turns according to device orientation * Fix formatting * Removed merge conflict tags from CHANGELOG * Fix license header in test --- packages/camera/camera/CHANGELOG.md | 4 + .../camera/camera/ios/Classes/CameraPlugin.m | 104 +++++--- .../camera/camera/lib/src/camera_preview.dart | 31 ++- packages/camera/camera/pubspec.yaml | 2 +- .../camera/test/camera_preview_test.dart | 239 ++++++++++++++++++ 5 files changed, 324 insertions(+), 56 deletions(-) create mode 100644 packages/camera/camera/test/camera_preview_test.dart diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index f1d771496dde..eb88683bee8f 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.8.1 + +* Solved a rotation issue on iOS which caused the default preview to be displayed as landscape right instead of portrait. + ## 0.8.0 * Stable null safety release. diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index e867491fcf8f..5c43f78a8c4b 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -345,6 +345,7 @@ @interface FLTCam : NSObject _videoWriter.status == AVAssetWriterStatusCompleted) { + [self updateOrientation]; result(self->_videoRecordingPath); self->_videoRecordingPath = nil; } else { @@ -854,12 +884,18 @@ - (void)lockCaptureOrientationWithResult:(FlutterResult)result result(getFlutterError(e)); return; } - _lockedCaptureOrientation = orientation; + + if (_lockedCaptureOrientation != orientation) { + _lockedCaptureOrientation = orientation; + [self updateOrientation]; + } + result(nil); } - (void)unlockCaptureOrientationWithResult:(FlutterResult)result { _lockedCaptureOrientation = UIDeviceOrientationUnknown; + [self updateOrientation]; result(nil); } @@ -1101,6 +1137,7 @@ - (BOOL)setupWriterForPath:(NSString *)path { if (_enableAudio && !_isAudioSetup) { [self setUpCaptureSessionForAudio]; } + _videoWriter = [[AVAssetWriter alloc] initWithURL:outputURL fileType:AVFileTypeMPEG4 error:&error]; @@ -1109,11 +1146,9 @@ - (BOOL)setupWriterForPath:(NSString *)path { [_methodChannel invokeMethod:errorMethod arguments:error.description]; return NO; } - NSDictionary *videoSettings = [NSDictionary - dictionaryWithObjectsAndKeys:AVVideoCodecH264, AVVideoCodecKey, - [NSNumber numberWithInt:_previewSize.width], AVVideoWidthKey, - [NSNumber numberWithInt:_previewSize.height], AVVideoHeightKey, - nil]; + + NSDictionary *videoSettings = [_captureVideoOutput + recommendedVideoSettingsForAssetWriterWithOutputFileType:AVFileTypeMPEG4]; _videoWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings]; @@ -1124,14 +1159,7 @@ - (BOOL)setupWriterForPath:(NSString *)path { }]; NSParameterAssert(_videoWriterInput); - CGFloat rotationDegrees; - if (_lockedCaptureOrientation != UIDeviceOrientationUnknown) { - rotationDegrees = [self getRotationFromDeviceOrientation:_lockedCaptureOrientation]; - } else { - rotationDegrees = [self getRotationFromDeviceOrientation:[UIDevice currentDevice].orientation]; - } - _videoWriterInput.transform = CGAffineTransformMakeRotation(rotationDegrees * M_PI / 180); _videoWriterInput.expectsMediaDataInRealTime = YES; // Add the audio input @@ -1194,21 +1222,6 @@ - (void)setUpCaptureSessionForAudio { } } } - -- (int)getRotationFromDeviceOrientation:(UIDeviceOrientation)orientation { - switch (orientation) { - case UIDeviceOrientationPortraitUpsideDown: - return 270; - case UIDeviceOrientationLandscapeRight: - return 180; - case UIDeviceOrientationLandscapeLeft: - return 0; - case UIDeviceOrientationPortrait: - default: - return 90; - }; -} - @end @interface CameraPlugin () @@ -1257,7 +1270,13 @@ - (void)startOrientationListener { - (void)orientationChanged:(NSNotification *)note { UIDevice *device = note.object; - [self sendDeviceOrientation:device.orientation]; + UIDeviceOrientation orientation = device.orientation; + + if (_camera) { + [_camera setDeviceOrientation:orientation]; + } + + [self sendDeviceOrientation:orientation]; } - (void)sendDeviceOrientation:(UIDeviceOrientation)orientation { @@ -1318,6 +1337,7 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re FLTCam *cam = [[FLTCam alloc] initWithCameraName:cameraName resolutionPreset:resolutionPreset enableAudio:[enableAudio boolValue] + orientation:[[UIDevice currentDevice] orientation] dispatchQueue:_dispatchQueue error:&error]; diff --git a/packages/camera/camera/lib/src/camera_preview.dart b/packages/camera/camera/lib/src/camera_preview.dart index 517751b7bf64..e2f1ff931e42 100644 --- a/packages/camera/camera/lib/src/camera_preview.dart +++ b/packages/camera/camera/lib/src/camera_preview.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'package:camera/camera.dart'; -import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -29,11 +28,7 @@ class CameraPreview extends StatelessWidget { child: Stack( fit: StackFit.expand, children: [ - RotatedBox( - quarterTurns: _getQuarterTurns(), - child: - CameraPlatform.instance.buildPreview(controller.cameraId), - ), + _wrapInRotatedBox(child: controller.buildPreview()), child ?? Container(), ], ), @@ -41,11 +36,15 @@ class CameraPreview extends StatelessWidget { : Container(); } - DeviceOrientation _getApplicableOrientation() { - return controller.value.isRecordingVideo - ? controller.value.recordingOrientation! - : (controller.value.lockedCaptureOrientation ?? - controller.value.deviceOrientation); + Widget _wrapInRotatedBox({required Widget child}) { + if (defaultTargetPlatform != TargetPlatform.android) { + return child; + } + + return RotatedBox( + quarterTurns: _getQuarterTurns(), + child: child, + ); } bool _isLandscape() { @@ -54,13 +53,19 @@ class CameraPreview extends StatelessWidget { } int _getQuarterTurns() { - int platformOffset = defaultTargetPlatform == TargetPlatform.iOS ? 1 : 0; Map turns = { DeviceOrientation.portraitUp: 0, DeviceOrientation.landscapeLeft: 1, DeviceOrientation.portraitDown: 2, DeviceOrientation.landscapeRight: 3, }; - return turns[_getApplicableOrientation()]! + platformOffset; + return turns[_getApplicableOrientation()]!; + } + + DeviceOrientation _getApplicableOrientation() { + return controller.value.isRecordingVideo + ? controller.value.recordingOrientation! + : (controller.value.lockedCaptureOrientation ?? + controller.value.deviceOrientation); } } diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 53f9b3b40ad1..58bfa85d6b99 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -2,7 +2,7 @@ name: camera description: A Flutter plugin for getting information about and controlling the camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video, and streaming image buffers to dart. -version: 0.8.0 +version: 0.8.1 homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: diff --git a/packages/camera/camera/test/camera_preview_test.dart b/packages/camera/camera/test/camera_preview_test.dart new file mode 100644 index 000000000000..d579341c0e58 --- /dev/null +++ b/packages/camera/camera/test/camera_preview_test.dart @@ -0,0 +1,239 @@ +// Copyright 2013 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:camera/camera.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:quiver/core.dart'; + +class FakeController extends ValueNotifier + implements CameraController { + FakeController() : super(const CameraValue.uninitialized()); + + @override + Future dispose() async { + super.dispose(); + } + + @override + Widget buildPreview() { + return Texture(textureId: CameraController.kUninitializedCameraId); + } + + @override + int get cameraId => CameraController.kUninitializedCameraId; + + @override + void debugCheckIsDisposed() {} + + @override + CameraDescription get description => CameraDescription( + name: '', lensDirection: CameraLensDirection.back, sensorOrientation: 0); + + @override + bool get enableAudio => false; + + @override + Future getExposureOffsetStepSize() async => 1.0; + + @override + Future getMaxExposureOffset() async => 1.0; + + @override + Future getMaxZoomLevel() async => 1.0; + + @override + Future getMinExposureOffset() async => 1.0; + + @override + Future getMinZoomLevel() async => 1.0; + + @override + ImageFormatGroup? get imageFormatGroup => null; + + @override + Future initialize() async {} + + @override + Future lockCaptureOrientation([DeviceOrientation? orientation]) async {} + + @override + Future pauseVideoRecording() async {} + + @override + Future prepareForVideoRecording() async {} + + @override + ResolutionPreset get resolutionPreset => ResolutionPreset.low; + + @override + Future resumeVideoRecording() async {} + + @override + Future setExposureMode(ExposureMode mode) async {} + + @override + Future setExposureOffset(double offset) async => offset; + + @override + Future setExposurePoint(Offset? point) async {} + + @override + Future setFlashMode(FlashMode mode) async {} + + @override + Future setFocusMode(FocusMode mode) async {} + + @override + Future setFocusPoint(Offset? point) async {} + + @override + Future setZoomLevel(double zoom) async {} + + @override + Future startImageStream(onAvailable) async {} + + @override + Future startVideoRecording() async {} + + @override + Future stopImageStream() async {} + + @override + Future stopVideoRecording() async => XFile(''); + + @override + Future takePicture() async => XFile(''); + + @override + Future unlockCaptureOrientation() async {} +} + +void main() { + group('RotatedBox (Android only)', () { + testWidgets( + 'when recording rotatedBox should turn according to recording orientation', + ( + WidgetTester tester, + ) async { + debugDefaultTargetPlatformOverride = TargetPlatform.android; + + final FakeController controller = FakeController(); + controller.value = controller.value.copyWith( + isInitialized: true, + isRecordingVideo: true, + deviceOrientation: DeviceOrientation.portraitUp, + lockedCaptureOrientation: + Optional.fromNullable(DeviceOrientation.landscapeRight), + recordingOrientation: + Optional.fromNullable(DeviceOrientation.landscapeLeft), + previewSize: Size(480, 640), + ); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: CameraPreview(controller), + ), + ); + expect(find.byType(RotatedBox), findsOneWidget); + + RotatedBox rotatedBox = + tester.widget(find.byType(RotatedBox)); + expect(rotatedBox.quarterTurns, 1); + + debugDefaultTargetPlatformOverride = null; + }); + + testWidgets( + 'when orientation locked rotatedBox should turn according to locked orientation', + ( + WidgetTester tester, + ) async { + debugDefaultTargetPlatformOverride = TargetPlatform.android; + + final FakeController controller = FakeController(); + controller.value = controller.value.copyWith( + isInitialized: true, + deviceOrientation: DeviceOrientation.portraitUp, + lockedCaptureOrientation: + Optional.fromNullable(DeviceOrientation.landscapeRight), + recordingOrientation: + Optional.fromNullable(DeviceOrientation.landscapeLeft), + previewSize: Size(480, 640), + ); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: CameraPreview(controller), + ), + ); + expect(find.byType(RotatedBox), findsOneWidget); + + RotatedBox rotatedBox = + tester.widget(find.byType(RotatedBox)); + expect(rotatedBox.quarterTurns, 3); + + debugDefaultTargetPlatformOverride = null; + }); + + testWidgets( + 'when not locked and not recording rotatedBox should turn according to device orientation', + ( + WidgetTester tester, + ) async { + debugDefaultTargetPlatformOverride = TargetPlatform.android; + + final FakeController controller = FakeController(); + controller.value = controller.value.copyWith( + isInitialized: true, + deviceOrientation: DeviceOrientation.portraitUp, + lockedCaptureOrientation: null, + recordingOrientation: + Optional.fromNullable(DeviceOrientation.landscapeLeft), + previewSize: Size(480, 640), + ); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: CameraPreview(controller), + ), + ); + expect(find.byType(RotatedBox), findsOneWidget); + + RotatedBox rotatedBox = + tester.widget(find.byType(RotatedBox)); + expect(rotatedBox.quarterTurns, 0); + + debugDefaultTargetPlatformOverride = null; + }); + }); + + testWidgets('when not on Android there should not be a rotated box', + (WidgetTester tester) async { + debugDefaultTargetPlatformOverride = TargetPlatform.iOS; + final FakeController controller = FakeController(); + controller.value = controller.value.copyWith( + isInitialized: true, + previewSize: Size(480, 640), + ); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: CameraPreview(controller), + ), + ); + expect(find.byType(RotatedBox), findsNothing); + expect(find.byType(Texture), findsOneWidget); + debugDefaultTargetPlatformOverride = null; + }); +} From e9ed3cdd6b1adbb1a1bce4a5b00c10776a6e20fd Mon Sep 17 00:00:00 2001 From: PiN73 Date: Wed, 24 Mar 2021 19:17:19 +0300 Subject: [PATCH 0291/1565] [video_player_platform_interface] add http headers (#3702) platform_interface portion of #3671 --- .../CHANGELOG.md | 4 ++++ .../lib/messages.dart | 5 ++++- .../lib/method_channel_video_player.dart | 1 + .../lib/video_player_platform_interface.dart | 6 ++++++ .../pubspec.yaml | 2 +- .../test/method_channel_video_player_test.dart | 18 ++++++++++++++++++ 6 files changed, 34 insertions(+), 2 deletions(-) diff --git a/packages/video_player/video_player_platform_interface/CHANGELOG.md b/packages/video_player/video_player_platform_interface/CHANGELOG.md index d0c59bd05023..24631513f800 100644 --- a/packages/video_player/video_player_platform_interface/CHANGELOG.md +++ b/packages/video_player/video_player_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 4.1.0 + +* Add `httpHeaders` to `DataSource` + ## 4.0.0 * **Breaking Changes**: diff --git a/packages/video_player/video_player_platform_interface/lib/messages.dart b/packages/video_player/video_player_platform_interface/lib/messages.dart index 2b7d8821a0cc..0ddbfaeaf247 100644 --- a/packages/video_player/video_player_platform_interface/lib/messages.dart +++ b/packages/video_player/video_player_platform_interface/lib/messages.dart @@ -31,6 +31,7 @@ class CreateMessage { String? uri; String? packageName; String? formatHint; + Map? httpHeaders; Object encode() { final Map pigeonMap = {}; @@ -38,6 +39,7 @@ class CreateMessage { pigeonMap['uri'] = uri; pigeonMap['packageName'] = packageName; pigeonMap['formatHint'] = formatHint; + pigeonMap['httpHeaders'] = httpHeaders; return pigeonMap; } @@ -47,7 +49,8 @@ class CreateMessage { ..asset = pigeonMap['asset'] as String? ..uri = pigeonMap['uri'] as String? ..packageName = pigeonMap['packageName'] as String? - ..formatHint = pigeonMap['formatHint'] as String?; + ..formatHint = pigeonMap['formatHint'] as String? + ..httpHeaders = pigeonMap['httpHeaders'] as Map?; } } diff --git a/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart b/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart index bd9708a117be..e92e87013d68 100644 --- a/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart +++ b/packages/video_player/video_player_platform_interface/lib/method_channel_video_player.dart @@ -37,6 +37,7 @@ class MethodChannelVideoPlayer extends VideoPlayerPlatform { case DataSourceType.network: message.uri = dataSource.uri; message.formatHint = _videoFormatStringMap[dataSource.formatHint]; + message.httpHeaders = dataSource.httpHeaders; break; case DataSourceType.file: message.uri = dataSource.uri; diff --git a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart index 1960253af193..b2bff990401e 100644 --- a/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart +++ b/packages/video_player/video_player_platform_interface/lib/video_player_platform_interface.dart @@ -151,6 +151,7 @@ class DataSource { this.formatHint, this.asset, this.package, + this.httpHeaders = const {}, }); /// The way in which the video was originally loaded. @@ -169,6 +170,11 @@ class DataSource { /// detection with whatever is set here. final VideoFormat? formatHint; + /// HTTP headers used for the request to the [uri]. + /// Only for [DataSourceType.network] videos. + /// Always empty for other video types. + Map httpHeaders; + /// The name of the asset. Only set for [DataSourceType.asset] videos. final String? asset; diff --git a/packages/video_player/video_player_platform_interface/pubspec.yaml b/packages/video_player/video_player_platform_interface/pubspec.yaml index c85f483d041f..98e1c95a8e8f 100644 --- a/packages/video_player/video_player_platform_interface/pubspec.yaml +++ b/packages/video_player/video_player_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the video_player plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 4.0.0 +version: 4.1.0 dependencies: flutter: diff --git a/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart b/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart index 00ec64305a31..33a5b34b615d 100644 --- a/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart +++ b/packages/video_player/video_player_platform_interface/test/method_channel_video_player_test.dart @@ -141,8 +141,26 @@ void main() { formatHint: VideoFormat.dash, )); expect(log.log.last, 'create'); + expect(log.createMessage?.asset, null); expect(log.createMessage?.uri, 'someUri'); + expect(log.createMessage?.packageName, null); expect(log.createMessage?.formatHint, 'dash'); + expect(log.createMessage?.httpHeaders, {}); + expect(textureId, 3); + }); + + test('create with network (some headers)', () async { + final int? textureId = await player.create(DataSource( + sourceType: DataSourceType.network, + uri: 'someUri', + httpHeaders: {'Authorization': 'Bearer token'}, + )); + expect(log.log.last, 'create'); + expect(log.createMessage?.asset, null); + expect(log.createMessage?.uri, 'someUri'); + expect(log.createMessage?.packageName, null); + expect(log.createMessage?.formatHint, null); + expect(log.createMessage?.httpHeaders, {'Authorization': 'Bearer token'}); expect(textureId, 3); }); From ce1cf17352f1299ded6bf477d57a3646edccdbbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl?= <32639467+danielroek@users.noreply.github.com> Date: Wed, 24 Mar 2021 17:45:17 +0100 Subject: [PATCH 0292/1565] [quick_actions] example fix (#3745) --- packages/quick_actions/quick_actions/CHANGELOG.md | 4 ++++ packages/quick_actions/quick_actions/example/lib/main.dart | 6 ++++-- packages/quick_actions/quick_actions/pubspec.yaml | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/quick_actions/quick_actions/CHANGELOG.md b/packages/quick_actions/quick_actions/CHANGELOG.md index 276ddfbf24c4..5f192825cacf 100644 --- a/packages/quick_actions/quick_actions/CHANGELOG.md +++ b/packages/quick_actions/quick_actions/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.0+1 + +* Updated example app implementation. + ## 0.5.0 * Migrate to null safety. diff --git a/packages/quick_actions/quick_actions/example/lib/main.dart b/packages/quick_actions/quick_actions/example/lib/main.dart index 3ff6528f3565..8e47d16683dd 100644 --- a/packages/quick_actions/quick_actions/example/lib/main.dart +++ b/packages/quick_actions/quick_actions/example/lib/main.dart @@ -32,7 +32,7 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { - String shortcut = "no action set"; + String shortcut = 'no action set'; @override void initState() { @@ -63,7 +63,9 @@ class _MyHomePageState extends State { icon: 'ic_launcher'), ]).then((value) { setState(() { - shortcut = "actions ready"; + if (shortcut == 'no action set') { + shortcut = 'actions ready'; + } }); }); } diff --git a/packages/quick_actions/quick_actions/pubspec.yaml b/packages/quick_actions/quick_actions/pubspec.yaml index ed6555833b83..71accce09fcf 100644 --- a/packages/quick_actions/quick_actions/pubspec.yaml +++ b/packages/quick_actions/quick_actions/pubspec.yaml @@ -2,7 +2,7 @@ name: quick_actions description: Flutter plugin for creating shortcuts on home screen, also known as Quick Actions on iOS and App Shortcuts on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/quick_actions -version: 0.5.0 +version: 0.5.0+1 flutter: plugin: From 7a3dd3132eb5ae0c30420cc9cdb0d23fb30d6560 Mon Sep 17 00:00:00 2001 From: Tyler Reece Date: Wed, 24 Mar 2021 15:15:03 -0400 Subject: [PATCH 0293/1565] Updated README.md typo (#2606) --- packages/in_app_purchase/example/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/in_app_purchase/example/README.md b/packages/in_app_purchase/example/README.md index 6dd5b38d7003..ef32964f141d 100644 --- a/packages/in_app_purchase/example/README.md +++ b/packages/in_app_purchase/example/README.md @@ -16,7 +16,7 @@ documentation on how to do this, and we've also included a high level guide below. * [In-App Purchase (App Store)](https://developer.apple.com/in-app-purchase/) -* [Google Play Biling Overview](https://developer.android.com/google/play/billing/billing_overview) +* [Google Play Billing Overview](https://developer.android.com/google/play/billing/billing_overview) ### Android @@ -86,4 +86,4 @@ below. service (including iTunes!) with the test account will permanently invalidate it. Sign in to the test account in the example app following the steps in the [*In-App Purchase Programming - Guide*](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/ShowUI.html#//apple_ref/doc/uid/TP40008267-CH3-SW11). \ No newline at end of file + Guide*](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/ShowUI.html#//apple_ref/doc/uid/TP40008267-CH3-SW11). From 2904cbb45fa6de2584e859446643ed8c89d4e84f Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Wed, 24 Mar 2021 20:20:04 +0100 Subject: [PATCH 0294/1565] [flutter_plugin_tools] Also look for Java tests in plugin path (#3742) --- .../flutter/plugins/camera/DartMessenger.java | 38 ++++---- .../plugins/camera/MethodCallHandlerImpl.java | 6 +- .../plugins/camera/DartMessengerTest.java | 30 ++++++- script/tool/lib/src/java_test_command.dart | 9 +- script/tool/test/java_test_command_test.dart | 86 +++++++++++++++++++ 5 files changed, 145 insertions(+), 24 deletions(-) create mode 100644 script/tool/test/java_test_command_test.dart diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java index 164a529ffa8b..aaac1361eb3d 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/DartMessenger.java @@ -5,8 +5,8 @@ package io.flutter.plugins.camera; import android.os.Handler; -import android.os.Looper; import android.text.TextUtils; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import io.flutter.embedding.engine.systemchannels.PlatformChannel; import io.flutter.plugin.common.BinaryMessenger; @@ -17,6 +17,7 @@ import java.util.Map; class DartMessenger { + @NonNull private final Handler handler; @Nullable private MethodChannel cameraChannel; @Nullable private MethodChannel deviceChannel; @@ -41,9 +42,10 @@ enum CameraEventType { } } - DartMessenger(BinaryMessenger messenger, long cameraId) { + DartMessenger(BinaryMessenger messenger, long cameraId, @NonNull Handler handler) { cameraChannel = new MethodChannel(messenger, "flutter.io/cameraPlugin/camera" + cameraId); deviceChannel = new MethodChannel(messenger, "flutter.io/cameraPlugin/device"); + this.handler = handler; } void sendDeviceOrientationChangeEvent(PlatformChannel.DeviceOrientation orientation) { @@ -106,14 +108,14 @@ void send(CameraEventType eventType, Map args) { if (cameraChannel == null) { return; } - new Handler(Looper.getMainLooper()) - .post( - new Runnable() { - @Override - public void run() { - cameraChannel.invokeMethod(eventType.method, args); - } - }); + + handler.post( + new Runnable() { + @Override + public void run() { + cameraChannel.invokeMethod(eventType.method, args); + } + }); } void send(DeviceEventType eventType) { @@ -124,13 +126,13 @@ void send(DeviceEventType eventType, Map args) { if (deviceChannel == null) { return; } - new Handler(Looper.getMainLooper()) - .post( - new Runnable() { - @Override - public void run() { - deviceChannel.invokeMethod(eventType.method, args); - } - }); + + handler.post( + new Runnable() { + @Override + public void run() { + deviceChannel.invokeMethod(eventType.method, args); + } + }); } } diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java index 040225ed5ff3..50bca6349217 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java @@ -6,6 +6,8 @@ import android.app.Activity; import android.hardware.camera2.CameraAccessException; +import android.os.Handler; +import android.os.Looper; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import io.flutter.embedding.engine.systemchannels.PlatformChannel; @@ -353,7 +355,9 @@ private void instantiateCamera(MethodCall call, Result result) throws CameraAcce boolean enableAudio = call.argument("enableAudio"); TextureRegistry.SurfaceTextureEntry flutterSurfaceTexture = textureRegistry.createSurfaceTexture(); - DartMessenger dartMessenger = new DartMessenger(messenger, flutterSurfaceTexture.id()); + DartMessenger dartMessenger = + new DartMessenger( + messenger, flutterSurfaceTexture.id(), new Handler(Looper.getMainLooper())); camera = new Camera( activity, diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java index ed6fd56a3c34..25f5df9e9db9 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java @@ -6,7 +6,11 @@ import static junit.framework.TestCase.assertNull; import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import android.os.Handler; import androidx.annotation.NonNull; import io.flutter.embedding.engine.systemchannels.PlatformChannel; import io.flutter.plugin.common.BinaryMessenger; @@ -19,6 +23,8 @@ import java.util.List; import org.junit.Before; import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; public class DartMessengerTest { /** A {@link BinaryMessenger} implementation that does nothing but save its messages. */ @@ -43,20 +49,24 @@ List getMessages() { } } + private Handler mockHandler; private DartMessenger dartMessenger; private FakeBinaryMessenger fakeBinaryMessenger; @Before public void setUp() { + mockHandler = mock(Handler.class); fakeBinaryMessenger = new FakeBinaryMessenger(); - dartMessenger = new DartMessenger(fakeBinaryMessenger, 0); + dartMessenger = new DartMessenger(fakeBinaryMessenger, 0, mockHandler); } @Test public void sendCameraErrorEvent_includesErrorDescriptions() { - dartMessenger.sendCameraErrorEvent("error description"); + doAnswer(createPostHandlerAnswer()).when(mockHandler).post(any(Runnable.class)); + dartMessenger.sendCameraErrorEvent("error description"); List sentMessages = fakeBinaryMessenger.getMessages(); + assertEquals(1, sentMessages.size()); MethodCall call = decodeSentMessage(sentMessages.get(0)); assertEquals("error", call.method); @@ -65,6 +75,7 @@ public void sendCameraErrorEvent_includesErrorDescriptions() { @Test public void sendCameraInitializedEvent_includesPreviewSize() { + doAnswer(createPostHandlerAnswer()).when(mockHandler).post(any(Runnable.class)); dartMessenger.sendCameraInitializedEvent(0, 0, ExposureMode.auto, FocusMode.auto, true, true); List sentMessages = fakeBinaryMessenger.getMessages(); @@ -81,6 +92,7 @@ public void sendCameraInitializedEvent_includesPreviewSize() { @Test public void sendCameraClosingEvent() { + doAnswer(createPostHandlerAnswer()).when(mockHandler).post(any(Runnable.class)); dartMessenger.sendCameraClosingEvent(); List sentMessages = fakeBinaryMessenger.getMessages(); @@ -92,6 +104,7 @@ public void sendCameraClosingEvent() { @Test public void sendDeviceOrientationChangedEvent() { + doAnswer(createPostHandlerAnswer()).when(mockHandler).post(any(Runnable.class)); dartMessenger.sendDeviceOrientationChangeEvent(PlatformChannel.DeviceOrientation.PORTRAIT_UP); List sentMessages = fakeBinaryMessenger.getMessages(); @@ -101,6 +114,19 @@ public void sendDeviceOrientationChangedEvent() { assertEquals(call.argument("orientation"), "portraitUp"); } + private static Answer createPostHandlerAnswer() { + return new Answer() { + @Override + public Boolean answer(InvocationOnMock invocation) throws Throwable { + Runnable runnable = invocation.getArgument(0, Runnable.class); + if (runnable != null) { + runnable.run(); + } + return true; + } + }; + } + private MethodCall decodeSentMessage(ByteBuffer sentMessage) { sentMessage.position(0); diff --git a/script/tool/lib/src/java_test_command.dart b/script/tool/lib/src/java_test_command.dart index 45042c3c7006..4b6a561b9e6d 100644 --- a/script/tool/lib/src/java_test_command.dart +++ b/script/tool/lib/src/java_test_command.dart @@ -32,9 +32,12 @@ class JavaTestCommand extends PluginCommand { final Stream examplesWithTests = getExamples().where( (Directory d) => isFlutterPackage(d, fileSystem) && - fileSystem - .directory(p.join(d.path, 'android', 'app', 'src', 'test')) - .existsSync()); + (fileSystem + .directory(p.join(d.path, 'android', 'app', 'src', 'test')) + .existsSync() || + fileSystem + .directory(p.join(d.path, '..', 'android', 'src', 'test')) + .existsSync())); final List failingPackages = []; final List missingFlutterBuild = []; diff --git a/script/tool/test/java_test_command_test.dart b/script/tool/test/java_test_command_test.dart new file mode 100644 index 000000000000..b036d7ec0c6f --- /dev/null +++ b/script/tool/test/java_test_command_test.dart @@ -0,0 +1,86 @@ +// Copyright 2013 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:args/command_runner.dart'; +import 'package:file/file.dart'; +import 'package:flutter_plugin_tools/src/java_test_command.dart'; +import 'package:path/path.dart' as p; +import 'package:test/test.dart'; + +import 'util.dart'; + +void main() { + group('$JavaTestCommand', () { + CommandRunner runner; + final RecordingProcessRunner processRunner = RecordingProcessRunner(); + + setUp(() { + initializeFakePackages(); + final JavaTestCommand command = JavaTestCommand( + mockPackagesDir, mockFileSystem, + processRunner: processRunner); + + runner = + CommandRunner('java_test_test', 'Test for $JavaTestCommand'); + runner.addCommand(command); + }); + + tearDown(() { + cleanupPackages(); + processRunner.recordedCalls.clear(); + }); + + test('Should run Java tests in Android implementation folder', () async { + final Directory plugin = createFakePlugin( + 'plugin1', + isAndroidPlugin: true, + isFlutter: true, + withSingleExample: true, + withExtraFiles: >[ + ['example/android', 'gradlew'], + ['android/src/test', 'example_test.java'], + ], + ); + + await runner.run(['java-test']); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + p.join(plugin.path, 'example/android/gradlew'), + ['testDebugUnitTest', '--info'], + p.join(plugin.path, 'example/android'), + ), + ]), + ); + }); + + test('Should run Java tests in example folder', () async { + final Directory plugin = createFakePlugin( + 'plugin1', + isAndroidPlugin: true, + isFlutter: true, + withSingleExample: true, + withExtraFiles: >[ + ['example/android', 'gradlew'], + ['example/android/app/src/test', 'example_test.java'], + ], + ); + + await runner.run(['java-test']); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + p.join(plugin.path, 'example/android/gradlew'), + ['testDebugUnitTest', '--info'], + p.join(plugin.path, 'example/android'), + ), + ]), + ); + }); + }); +} From 12ea8f2770ab0d091cfa549723680fc648dfe9b3 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Wed, 24 Mar 2021 15:06:49 -0700 Subject: [PATCH 0295/1565] [all] remove podfile in gitignore and update all podfiles (#3747) --- .gitignore | 1 - packages/battery/battery/example/ios/Podfile | 38 +++++++++++++++++ packages/camera/camera/example/ios/Podfile | 38 +++++++++++++++++ .../connectivity/example/ios/Podfile | 38 +++++++++++++++++ .../device_info/example/ios/Podfile | 38 +++++++++++++++++ .../google_maps_flutter/example/ios/Podfile | 38 +++++++++++++++++ .../google_sign_in/example/ios/Podfile | 38 +++++++++++++++++ packages/integration_test/example/ios/Podfile | 38 +++++++++++++++++ .../ios_platform_images/example/ios/Podfile | 41 +++++++++++++++++++ packages/local_auth/example/ios/Podfile | 38 +++++++++++++++++ packages/package_info/example/ios/Podfile | 38 +++++++++++++++++ .../path_provider/example/ios/Podfile | 38 +++++++++++++++++ .../quick_actions/example/ios/Podfile | 38 +++++++++++++++++ packages/sensors/example/ios/Podfile | 38 +++++++++++++++++ packages/share/example/ios/Podfile | 38 +++++++++++++++++ .../shared_preferences/example/ios/Podfile | 38 +++++++++++++++++ .../url_launcher/example/ios/Podfile | 38 +++++++++++++++++ .../video_player/example/ios/Podfile | 38 +++++++++++++++++ .../wifi_info_flutter/example/ios/Podfile | 38 +++++++++++++++++ 19 files changed, 687 insertions(+), 1 deletion(-) create mode 100644 packages/battery/battery/example/ios/Podfile create mode 100644 packages/camera/camera/example/ios/Podfile create mode 100644 packages/connectivity/connectivity/example/ios/Podfile create mode 100644 packages/device_info/device_info/example/ios/Podfile create mode 100644 packages/google_maps_flutter/google_maps_flutter/example/ios/Podfile create mode 100644 packages/google_sign_in/google_sign_in/example/ios/Podfile create mode 100644 packages/integration_test/example/ios/Podfile create mode 100644 packages/ios_platform_images/example/ios/Podfile create mode 100644 packages/local_auth/example/ios/Podfile create mode 100644 packages/package_info/example/ios/Podfile create mode 100644 packages/path_provider/path_provider/example/ios/Podfile create mode 100644 packages/quick_actions/quick_actions/example/ios/Podfile create mode 100644 packages/sensors/example/ios/Podfile create mode 100644 packages/share/example/ios/Podfile create mode 100644 packages/shared_preferences/shared_preferences/example/ios/Podfile create mode 100644 packages/url_launcher/url_launcher/example/ios/Podfile create mode 100644 packages/video_player/video_player/example/ios/Podfile create mode 100644 packages/wifi_info_flutter/wifi_info_flutter/example/ios/Podfile diff --git a/.gitignore b/.gitignore index 823f9031d960..f4fa0b9b7795 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,6 @@ flutter_export_environment.sh examples/all_plugins/pubspec.yaml -Podfile Podfile.lock Pods/ .symlinks/ diff --git a/packages/battery/battery/example/ios/Podfile b/packages/battery/battery/example/ios/Podfile new file mode 100644 index 000000000000..f7d6a5e68c3a --- /dev/null +++ b/packages/battery/battery/example/ios/Podfile @@ -0,0 +1,38 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/camera/camera/example/ios/Podfile b/packages/camera/camera/example/ios/Podfile new file mode 100644 index 000000000000..f7d6a5e68c3a --- /dev/null +++ b/packages/camera/camera/example/ios/Podfile @@ -0,0 +1,38 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/connectivity/connectivity/example/ios/Podfile b/packages/connectivity/connectivity/example/ios/Podfile new file mode 100644 index 000000000000..f7d6a5e68c3a --- /dev/null +++ b/packages/connectivity/connectivity/example/ios/Podfile @@ -0,0 +1,38 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/device_info/device_info/example/ios/Podfile b/packages/device_info/device_info/example/ios/Podfile new file mode 100644 index 000000000000..f7d6a5e68c3a --- /dev/null +++ b/packages/device_info/device_info/example/ios/Podfile @@ -0,0 +1,38 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/google_maps_flutter/google_maps_flutter/example/ios/Podfile b/packages/google_maps_flutter/google_maps_flutter/example/ios/Podfile new file mode 100644 index 000000000000..f7d6a5e68c3a --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter/example/ios/Podfile @@ -0,0 +1,38 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/google_sign_in/google_sign_in/example/ios/Podfile b/packages/google_sign_in/google_sign_in/example/ios/Podfile new file mode 100644 index 000000000000..f7d6a5e68c3a --- /dev/null +++ b/packages/google_sign_in/google_sign_in/example/ios/Podfile @@ -0,0 +1,38 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/integration_test/example/ios/Podfile b/packages/integration_test/example/ios/Podfile new file mode 100644 index 000000000000..f7d6a5e68c3a --- /dev/null +++ b/packages/integration_test/example/ios/Podfile @@ -0,0 +1,38 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/ios_platform_images/example/ios/Podfile b/packages/ios_platform_images/example/ios/Podfile new file mode 100644 index 000000000000..1e8c3c90a55e --- /dev/null +++ b/packages/ios_platform_images/example/ios/Podfile @@ -0,0 +1,41 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/local_auth/example/ios/Podfile b/packages/local_auth/example/ios/Podfile new file mode 100644 index 000000000000..f7d6a5e68c3a --- /dev/null +++ b/packages/local_auth/example/ios/Podfile @@ -0,0 +1,38 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/package_info/example/ios/Podfile b/packages/package_info/example/ios/Podfile new file mode 100644 index 000000000000..f7d6a5e68c3a --- /dev/null +++ b/packages/package_info/example/ios/Podfile @@ -0,0 +1,38 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/path_provider/path_provider/example/ios/Podfile b/packages/path_provider/path_provider/example/ios/Podfile new file mode 100644 index 000000000000..f7d6a5e68c3a --- /dev/null +++ b/packages/path_provider/path_provider/example/ios/Podfile @@ -0,0 +1,38 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/quick_actions/quick_actions/example/ios/Podfile b/packages/quick_actions/quick_actions/example/ios/Podfile new file mode 100644 index 000000000000..f7d6a5e68c3a --- /dev/null +++ b/packages/quick_actions/quick_actions/example/ios/Podfile @@ -0,0 +1,38 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/sensors/example/ios/Podfile b/packages/sensors/example/ios/Podfile new file mode 100644 index 000000000000..f7d6a5e68c3a --- /dev/null +++ b/packages/sensors/example/ios/Podfile @@ -0,0 +1,38 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/share/example/ios/Podfile b/packages/share/example/ios/Podfile new file mode 100644 index 000000000000..f7d6a5e68c3a --- /dev/null +++ b/packages/share/example/ios/Podfile @@ -0,0 +1,38 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/shared_preferences/shared_preferences/example/ios/Podfile b/packages/shared_preferences/shared_preferences/example/ios/Podfile new file mode 100644 index 000000000000..f7d6a5e68c3a --- /dev/null +++ b/packages/shared_preferences/shared_preferences/example/ios/Podfile @@ -0,0 +1,38 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/url_launcher/url_launcher/example/ios/Podfile b/packages/url_launcher/url_launcher/example/ios/Podfile new file mode 100644 index 000000000000..f7d6a5e68c3a --- /dev/null +++ b/packages/url_launcher/url_launcher/example/ios/Podfile @@ -0,0 +1,38 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/video_player/video_player/example/ios/Podfile b/packages/video_player/video_player/example/ios/Podfile new file mode 100644 index 000000000000..f7d6a5e68c3a --- /dev/null +++ b/packages/video_player/video_player/example/ios/Podfile @@ -0,0 +1,38 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Podfile b/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Podfile new file mode 100644 index 000000000000..f7d6a5e68c3a --- /dev/null +++ b/packages/wifi_info_flutter/wifi_info_flutter/example/ios/Podfile @@ -0,0 +1,38 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end From 98c79a9c7fcf0393969ee97aaf11efde1ad154b4 Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Wed, 24 Mar 2021 15:56:40 -0700 Subject: [PATCH 0296/1565] [ci] Do not use empty exclude directories in analyze_command. (#3748) * Add CUSTOM_ANALYSIS_PLUGINS back with all the plugins that now have a custom analysis_options.yaml --- script/incremental_build.sh | 33 +++++++++++++++++++++- script/tool/lib/src/analyze_command.dart | 6 ++-- script/tool/test/analyze_command_test.dart | 15 ++++++++++ 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/script/incremental_build.sh b/script/incremental_build.sh index c14197c85ae7..ade89afe4ca1 100755 --- a/script/incremental_build.sh +++ b/script/incremental_build.sh @@ -19,8 +19,39 @@ ALL_EXCLUDED=("") # because we adopted stricter analysis rules recently and needed to exclude # already failing packages to start linting the repo as a whole. # -# TODO(mklim): Remove everything from this list. https://github.com/flutter/flutter/issues/45440 +# Finding all: `find packages -name analysis_options.yaml | sort | cut -d/ -f2` +# +# TODO(ecosystem): Remove everything from this list. https://github.com/flutter/flutter/issues/76229 CUSTOM_ANALYSIS_PLUGINS=( + android_alarm_manager + android_intent + battery + camera + connectivity + cross_file + device_info + e2e + espresso + file_selector + flutter_plugin_android_lifecycle + google_maps_flutter + google_sign_in + image_picker + in_app_purchase + integration_test + ios_platform_images + local_auth + package_info + path_provider + plugin_platform_interface + quick_actions + sensors + share + shared_preferences + url_launcher + video_player + webview_flutter + wifi_info_flutter ) # Comma-separated string of the list above diff --git a/script/tool/lib/src/analyze_command.dart b/script/tool/lib/src/analyze_command.dart index b2586c4b0fcf..9489303f5665 100644 --- a/script/tool/lib/src/analyze_command.dart +++ b/script/tool/lib/src/analyze_command.dart @@ -42,10 +42,12 @@ class AnalyzeCommand extends PluginCommand { continue; } - final bool whitelisted = argResults[_customAnalysisFlag].any( + final bool allowed = argResults[_customAnalysisFlag].any( (String directory) => + directory != null && + directory.isNotEmpty && p.isWithin(p.join(packagesDir.path, directory), file.path)); - if (whitelisted) { + if (allowed) { continue; } diff --git a/script/tool/test/analyze_command_test.dart b/script/tool/test/analyze_command_test.dart index 7b4ef81e0fc2..636d4794a484 100644 --- a/script/tool/test/analyze_command_test.dart +++ b/script/tool/test/analyze_command_test.dart @@ -93,5 +93,20 @@ void main() { pluginDir.path), ])); }); + + // See: https://github.com/flutter/flutter/issues/78994 + test('takes an empty allow list', () async { + await createFakePlugin('foo', withExtraFiles: >[ + ['analysis_options.yaml'] + ]); + + final MockProcess mockProcess = MockProcess(); + mockProcess.exitCodeCompleter.complete(0); + processRunner.processToReturn = mockProcess; + + await expectLater( + () => runner.run(['analyze', '--custom-analysis', '']), + throwsA(const TypeMatcher())); + }); }); } From e73402d873dc3fb26fe44643906dcc2157c3b49c Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Wed, 24 Mar 2021 16:19:09 -0700 Subject: [PATCH 0297/1565] [in_app_purchase] create sub folder (#3744) --- .../in_app_purchase/analysis_options.yaml | 1 - .../example/in_app_purchase_example.iml | 18 ----------- .../in_app_purchase_example_android.iml | 27 ---------------- .../{ => in_app_purchase}/AUTHORS | 0 .../{ => in_app_purchase}/CHANGELOG.md | 0 .../{ => in_app_purchase}/LICENSE | 0 .../{ => in_app_purchase}/README.md | 0 .../in_app_purchase/analysis_options.yaml | 1 + .../android/build.gradle | 0 .../android/gradle.properties | 0 .../gradle/wrapper/gradle-wrapper.properties | 0 .../android/settings.gradle | 0 .../android/src/main/AndroidManifest.xml | 0 .../inapppurchase/BillingClientFactory.java | 0 .../BillingClientFactoryImpl.java | 0 .../inapppurchase/InAppPurchasePlugin.java | 0 .../inapppurchase/MethodCallHandlerImpl.java | 0 .../inapppurchase/PluginPurchaseListener.java | 0 .../plugins/inapppurchase/Translator.java | 0 .../{ => in_app_purchase}/build.yaml | 0 .../{ => in_app_purchase}/example/.metadata | 0 .../{ => in_app_purchase}/example/README.md | 0 .../example/android/app/build.gradle | 0 .../gradle/wrapper/gradle-wrapper.properties | 0 .../android/app/src/main/AndroidManifest.xml | 0 .../EmbeddingV1Activity.java | 0 .../EmbeddingV1ActivityTest.java | 0 .../FlutterActivityTest.java | 0 .../main/res/drawable/launch_background.xml | 0 .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../app/src/main/res/values/styles.xml | 0 .../InAppPurchasePluginTest.java | 0 .../inapppurchase/MethodCallHandlerTest.java | 0 .../plugins/inapppurchase/TranslatorTest.java | 0 .../org.mockito.plugins.MockMaker | 0 .../example/android/build.gradle | 0 .../example/android/gradle.properties | 0 .../gradle/wrapper/gradle-wrapper.properties | 0 .../android/keystore.example.properties | 0 .../example/android/settings.gradle | 0 .../ios/Flutter/AppFrameworkInfo.plist | 0 .../example/ios/Flutter/Debug.xcconfig | 0 .../example/ios/Flutter/Release.xcconfig | 0 .../{ => in_app_purchase}/example/ios/Podfile | 0 .../ios/Runner.xcodeproj/project.pbxproj | 0 .../contents.xcworkspacedata | 0 .../xcshareddata/xcschemes/Runner.xcscheme | 0 .../contents.xcworkspacedata | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../example/ios/Runner/AppDelegate.h | 0 .../example/ios/Runner/AppDelegate.m | 0 .../AppIcon.appiconset/Contents.json | 0 .../Icon-App-1024x1024@1x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin .../Icon-App-83.5x83.5@2x.png | Bin .../LaunchImage.imageset/Contents.json | 0 .../LaunchImage.imageset/LaunchImage.png | Bin .../LaunchImage.imageset/LaunchImage@2x.png | Bin .../LaunchImage.imageset/LaunchImage@3x.png | Bin .../LaunchImage.imageset/README.md | 0 .../Runner/Base.lproj/LaunchScreen.storyboard | 0 .../ios/Runner/Base.lproj/Main.storyboard | 0 .../example/ios/Runner/Info.plist | 0 .../example/ios/Runner/main.m | 0 .../in_app_purchase_pluginTests/Info.plist | 0 .../example/lib/consumable_store.dart | 0 .../example/lib/main.dart | 0 .../example/pubspec.yaml | 0 .../test_driver/test/integration_test.dart | 0 .../in_app_purchase_test.dart | 0 .../{ => in_app_purchase}/ios/Assets/.gitkeep | 0 .../ios/Classes/FIAObjectTranslator.h | 0 .../ios/Classes/FIAObjectTranslator.m | 0 .../ios/Classes/FIAPReceiptManager.h | 0 .../ios/Classes/FIAPReceiptManager.m | 0 .../ios/Classes/FIAPRequestHandler.h | 0 .../ios/Classes/FIAPRequestHandler.m | 0 .../ios/Classes/FIAPaymentQueueHandler.h | 0 .../ios/Classes/FIAPaymentQueueHandler.m | 0 .../ios/Classes/InAppPurchasePlugin.h | 0 .../ios/Classes/InAppPurchasePlugin.m | 0 .../ios/Tests/InAppPurchasePluginTest.m | 0 .../ios/Tests/PaymentQueueTest.m | 0 .../ios/Tests/ProductRequestHandlerTest.m | 0 .../{ => in_app_purchase}/ios/Tests/Stubs.h | 0 .../{ => in_app_purchase}/ios/Tests/Stubs.m | 0 .../ios/Tests/TranslatorTest.m | 0 .../ios/in_app_purchase.podspec | 0 .../lib/billing_client_wrappers.dart | 0 .../lib/in_app_purchase.dart | 0 .../lib/src/billing_client_wrappers/README.md | 0 .../billing_client_wrapper.dart | 0 .../enum_converters.dart | 0 .../enum_converters.g.dart | 0 .../purchase_wrapper.dart | 0 .../purchase_wrapper.g.dart | 0 .../sku_details_wrapper.dart | 0 .../sku_details_wrapper.g.dart | 0 .../lib/src/channel.dart | 0 .../lib/src/in_app_purchase/README.md | 0 .../in_app_purchase/app_store_connection.dart | 0 .../google_play_connection.dart | 0 .../in_app_purchase_connection.dart | 0 .../src/in_app_purchase/product_details.dart | 0 .../src/in_app_purchase/purchase_details.dart | 0 .../lib/src/store_kit_wrappers/README.md | 0 .../store_kit_wrappers/enum_converters.dart | 0 .../store_kit_wrappers/enum_converters.g.dart | 0 .../sk_payment_queue_wrapper.dart | 0 .../sk_payment_queue_wrapper.g.dart | 0 .../sk_payment_transaction_wrappers.dart | 0 .../sk_payment_transaction_wrappers.g.dart | 0 .../sk_product_wrapper.dart | 0 .../sk_product_wrapper.g.dart | 0 .../sk_receipt_manager.dart | 0 .../store_kit_wrappers/sk_request_maker.dart | 0 .../lib/store_kit_wrappers.dart | 0 .../{ => in_app_purchase}/pubspec.yaml | 0 .../billing_client_wrapper_test.dart | 0 .../purchase_wrapper_test.dart | 0 .../sku_details_wrapper_test.dart | 0 .../app_store_connection_test.dart | 0 .../google_play_connection_test.dart | 0 .../sk_methodchannel_apis_test.dart | 0 .../store_kit_wrappers/sk_product_test.dart | 0 .../sk_test_stub_objects.dart | 0 .../test/stub_in_app_purchase_platform.dart | 0 .../in_app_purchase_android.iml | 30 ------------------ 144 files changed, 1 insertion(+), 76 deletions(-) delete mode 100644 packages/in_app_purchase/analysis_options.yaml delete mode 100644 packages/in_app_purchase/example/in_app_purchase_example.iml delete mode 100644 packages/in_app_purchase/example/in_app_purchase_example_android.iml rename packages/in_app_purchase/{ => in_app_purchase}/AUTHORS (100%) rename packages/in_app_purchase/{ => in_app_purchase}/CHANGELOG.md (100%) rename packages/in_app_purchase/{ => in_app_purchase}/LICENSE (100%) rename packages/in_app_purchase/{ => in_app_purchase}/README.md (100%) create mode 100644 packages/in_app_purchase/in_app_purchase/analysis_options.yaml rename packages/in_app_purchase/{ => in_app_purchase}/android/build.gradle (100%) rename packages/in_app_purchase/{ => in_app_purchase}/android/gradle.properties (100%) rename packages/in_app_purchase/{ => in_app_purchase}/android/gradle/wrapper/gradle-wrapper.properties (100%) rename packages/in_app_purchase/{ => in_app_purchase}/android/settings.gradle (100%) rename packages/in_app_purchase/{ => in_app_purchase}/android/src/main/AndroidManifest.xml (100%) rename packages/in_app_purchase/{ => in_app_purchase}/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactory.java (100%) rename packages/in_app_purchase/{ => in_app_purchase}/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactoryImpl.java (100%) rename packages/in_app_purchase/{ => in_app_purchase}/android/src/main/java/io/flutter/plugins/inapppurchase/InAppPurchasePlugin.java (100%) rename packages/in_app_purchase/{ => in_app_purchase}/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java (100%) rename packages/in_app_purchase/{ => in_app_purchase}/android/src/main/java/io/flutter/plugins/inapppurchase/PluginPurchaseListener.java (100%) rename packages/in_app_purchase/{ => in_app_purchase}/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java (100%) rename packages/in_app_purchase/{ => in_app_purchase}/build.yaml (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/.metadata (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/README.md (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/app/build.gradle (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/app/gradle/wrapper/gradle-wrapper.properties (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/app/src/main/AndroidManifest.xml (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1Activity.java (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1ActivityTest.java (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/FlutterActivityTest.java (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/app/src/main/res/drawable/launch_background.xml (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/app/src/main/res/values/styles.xml (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/app/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/build.gradle (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/gradle.properties (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/gradle/wrapper/gradle-wrapper.properties (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/keystore.example.properties (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/android/settings.gradle (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Flutter/AppFrameworkInfo.plist (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Flutter/Debug.xcconfig (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Flutter/Release.xcconfig (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Podfile (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner.xcodeproj/project.pbxproj (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner.xcworkspace/contents.xcworkspacedata (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/AppDelegate.h (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/AppDelegate.m (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Base.lproj/LaunchScreen.storyboard (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Base.lproj/Main.storyboard (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/Info.plist (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/Runner/main.m (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/ios/in_app_purchase_pluginTests/Info.plist (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/lib/consumable_store.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/lib/main.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/pubspec.yaml (100%) rename packages/in_app_purchase/{ => in_app_purchase}/example/test_driver/test/integration_test.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/integration_test/in_app_purchase_test.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/ios/Assets/.gitkeep (100%) rename packages/in_app_purchase/{ => in_app_purchase}/ios/Classes/FIAObjectTranslator.h (100%) rename packages/in_app_purchase/{ => in_app_purchase}/ios/Classes/FIAObjectTranslator.m (100%) rename packages/in_app_purchase/{ => in_app_purchase}/ios/Classes/FIAPReceiptManager.h (100%) rename packages/in_app_purchase/{ => in_app_purchase}/ios/Classes/FIAPReceiptManager.m (100%) rename packages/in_app_purchase/{ => in_app_purchase}/ios/Classes/FIAPRequestHandler.h (100%) rename packages/in_app_purchase/{ => in_app_purchase}/ios/Classes/FIAPRequestHandler.m (100%) rename packages/in_app_purchase/{ => in_app_purchase}/ios/Classes/FIAPaymentQueueHandler.h (100%) rename packages/in_app_purchase/{ => in_app_purchase}/ios/Classes/FIAPaymentQueueHandler.m (100%) rename packages/in_app_purchase/{ => in_app_purchase}/ios/Classes/InAppPurchasePlugin.h (100%) rename packages/in_app_purchase/{ => in_app_purchase}/ios/Classes/InAppPurchasePlugin.m (100%) rename packages/in_app_purchase/{ => in_app_purchase}/ios/Tests/InAppPurchasePluginTest.m (100%) rename packages/in_app_purchase/{ => in_app_purchase}/ios/Tests/PaymentQueueTest.m (100%) rename packages/in_app_purchase/{ => in_app_purchase}/ios/Tests/ProductRequestHandlerTest.m (100%) rename packages/in_app_purchase/{ => in_app_purchase}/ios/Tests/Stubs.h (100%) rename packages/in_app_purchase/{ => in_app_purchase}/ios/Tests/Stubs.m (100%) rename packages/in_app_purchase/{ => in_app_purchase}/ios/Tests/TranslatorTest.m (100%) rename packages/in_app_purchase/{ => in_app_purchase}/ios/in_app_purchase.podspec (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/billing_client_wrappers.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/in_app_purchase.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/billing_client_wrappers/README.md (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/billing_client_wrappers/billing_client_wrapper.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/billing_client_wrappers/enum_converters.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/billing_client_wrappers/enum_converters.g.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/billing_client_wrappers/purchase_wrapper.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/billing_client_wrappers/purchase_wrapper.g.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/billing_client_wrappers/sku_details_wrapper.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/billing_client_wrappers/sku_details_wrapper.g.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/channel.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/in_app_purchase/README.md (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/in_app_purchase/app_store_connection.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/in_app_purchase/google_play_connection.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/in_app_purchase/in_app_purchase_connection.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/in_app_purchase/product_details.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/in_app_purchase/purchase_details.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/store_kit_wrappers/README.md (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/store_kit_wrappers/enum_converters.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/store_kit_wrappers/enum_converters.g.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.g.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.g.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/store_kit_wrappers/sk_product_wrapper.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/store_kit_wrappers/sk_product_wrapper.g.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/store_kit_wrappers/sk_receipt_manager.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/src/store_kit_wrappers/sk_request_maker.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/lib/store_kit_wrappers.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/pubspec.yaml (100%) rename packages/in_app_purchase/{ => in_app_purchase}/test/billing_client_wrappers/billing_client_wrapper_test.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/test/billing_client_wrappers/purchase_wrapper_test.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/test/billing_client_wrappers/sku_details_wrapper_test.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/test/in_app_purchase_connection/app_store_connection_test.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/test/in_app_purchase_connection/google_play_connection_test.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/test/store_kit_wrappers/sk_methodchannel_apis_test.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/test/store_kit_wrappers/sk_product_test.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/test/store_kit_wrappers/sk_test_stub_objects.dart (100%) rename packages/in_app_purchase/{ => in_app_purchase}/test/stub_in_app_purchase_platform.dart (100%) delete mode 100644 packages/in_app_purchase/in_app_purchase_android.iml diff --git a/packages/in_app_purchase/analysis_options.yaml b/packages/in_app_purchase/analysis_options.yaml deleted file mode 100644 index cda4f6e153e6..000000000000 --- a/packages/in_app_purchase/analysis_options.yaml +++ /dev/null @@ -1 +0,0 @@ -include: ../../analysis_options_legacy.yaml diff --git a/packages/in_app_purchase/example/in_app_purchase_example.iml b/packages/in_app_purchase/example/in_app_purchase_example.iml deleted file mode 100644 index e5c837191e06..000000000000 --- a/packages/in_app_purchase/example/in_app_purchase_example.iml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/in_app_purchase/example/in_app_purchase_example_android.iml b/packages/in_app_purchase/example/in_app_purchase_example_android.iml deleted file mode 100644 index b050030a1b87..000000000000 --- a/packages/in_app_purchase/example/in_app_purchase_example_android.iml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/packages/in_app_purchase/AUTHORS b/packages/in_app_purchase/in_app_purchase/AUTHORS similarity index 100% rename from packages/in_app_purchase/AUTHORS rename to packages/in_app_purchase/in_app_purchase/AUTHORS diff --git a/packages/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase/CHANGELOG.md similarity index 100% rename from packages/in_app_purchase/CHANGELOG.md rename to packages/in_app_purchase/in_app_purchase/CHANGELOG.md diff --git a/packages/in_app_purchase/LICENSE b/packages/in_app_purchase/in_app_purchase/LICENSE similarity index 100% rename from packages/in_app_purchase/LICENSE rename to packages/in_app_purchase/in_app_purchase/LICENSE diff --git a/packages/in_app_purchase/README.md b/packages/in_app_purchase/in_app_purchase/README.md similarity index 100% rename from packages/in_app_purchase/README.md rename to packages/in_app_purchase/in_app_purchase/README.md diff --git a/packages/in_app_purchase/in_app_purchase/analysis_options.yaml b/packages/in_app_purchase/in_app_purchase/analysis_options.yaml new file mode 100644 index 000000000000..5aeb4e7c5e21 --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase/analysis_options.yaml @@ -0,0 +1 @@ +include: ../../../analysis_options_legacy.yaml diff --git a/packages/in_app_purchase/android/build.gradle b/packages/in_app_purchase/in_app_purchase/android/build.gradle similarity index 100% rename from packages/in_app_purchase/android/build.gradle rename to packages/in_app_purchase/in_app_purchase/android/build.gradle diff --git a/packages/in_app_purchase/android/gradle.properties b/packages/in_app_purchase/in_app_purchase/android/gradle.properties similarity index 100% rename from packages/in_app_purchase/android/gradle.properties rename to packages/in_app_purchase/in_app_purchase/android/gradle.properties diff --git a/packages/in_app_purchase/android/gradle/wrapper/gradle-wrapper.properties b/packages/in_app_purchase/in_app_purchase/android/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from packages/in_app_purchase/android/gradle/wrapper/gradle-wrapper.properties rename to packages/in_app_purchase/in_app_purchase/android/gradle/wrapper/gradle-wrapper.properties diff --git a/packages/in_app_purchase/android/settings.gradle b/packages/in_app_purchase/in_app_purchase/android/settings.gradle similarity index 100% rename from packages/in_app_purchase/android/settings.gradle rename to packages/in_app_purchase/in_app_purchase/android/settings.gradle diff --git a/packages/in_app_purchase/android/src/main/AndroidManifest.xml b/packages/in_app_purchase/in_app_purchase/android/src/main/AndroidManifest.xml similarity index 100% rename from packages/in_app_purchase/android/src/main/AndroidManifest.xml rename to packages/in_app_purchase/in_app_purchase/android/src/main/AndroidManifest.xml diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactory.java b/packages/in_app_purchase/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactory.java similarity index 100% rename from packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactory.java rename to packages/in_app_purchase/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactory.java diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactoryImpl.java b/packages/in_app_purchase/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactoryImpl.java similarity index 100% rename from packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactoryImpl.java rename to packages/in_app_purchase/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/BillingClientFactoryImpl.java diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/InAppPurchasePlugin.java b/packages/in_app_purchase/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/InAppPurchasePlugin.java similarity index 100% rename from packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/InAppPurchasePlugin.java rename to packages/in_app_purchase/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/InAppPurchasePlugin.java diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java b/packages/in_app_purchase/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java similarity index 100% rename from packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java rename to packages/in_app_purchase/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/PluginPurchaseListener.java b/packages/in_app_purchase/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/PluginPurchaseListener.java similarity index 100% rename from packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/PluginPurchaseListener.java rename to packages/in_app_purchase/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/PluginPurchaseListener.java diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java b/packages/in_app_purchase/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java similarity index 100% rename from packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java rename to packages/in_app_purchase/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/Translator.java diff --git a/packages/in_app_purchase/build.yaml b/packages/in_app_purchase/in_app_purchase/build.yaml similarity index 100% rename from packages/in_app_purchase/build.yaml rename to packages/in_app_purchase/in_app_purchase/build.yaml diff --git a/packages/in_app_purchase/example/.metadata b/packages/in_app_purchase/in_app_purchase/example/.metadata similarity index 100% rename from packages/in_app_purchase/example/.metadata rename to packages/in_app_purchase/in_app_purchase/example/.metadata diff --git a/packages/in_app_purchase/example/README.md b/packages/in_app_purchase/in_app_purchase/example/README.md similarity index 100% rename from packages/in_app_purchase/example/README.md rename to packages/in_app_purchase/in_app_purchase/example/README.md diff --git a/packages/in_app_purchase/example/android/app/build.gradle b/packages/in_app_purchase/in_app_purchase/example/android/app/build.gradle similarity index 100% rename from packages/in_app_purchase/example/android/app/build.gradle rename to packages/in_app_purchase/in_app_purchase/example/android/app/build.gradle diff --git a/packages/in_app_purchase/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/in_app_purchase/in_app_purchase/example/android/app/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from packages/in_app_purchase/example/android/app/gradle/wrapper/gradle-wrapper.properties rename to packages/in_app_purchase/in_app_purchase/example/android/app/gradle/wrapper/gradle-wrapper.properties diff --git a/packages/in_app_purchase/example/android/app/src/main/AndroidManifest.xml b/packages/in_app_purchase/in_app_purchase/example/android/app/src/main/AndroidManifest.xml similarity index 100% rename from packages/in_app_purchase/example/android/app/src/main/AndroidManifest.xml rename to packages/in_app_purchase/in_app_purchase/example/android/app/src/main/AndroidManifest.xml diff --git a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1Activity.java b/packages/in_app_purchase/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1Activity.java similarity index 100% rename from packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1Activity.java rename to packages/in_app_purchase/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1Activity.java diff --git a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1ActivityTest.java b/packages/in_app_purchase/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1ActivityTest.java similarity index 100% rename from packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1ActivityTest.java rename to packages/in_app_purchase/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/EmbeddingV1ActivityTest.java diff --git a/packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/FlutterActivityTest.java b/packages/in_app_purchase/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/FlutterActivityTest.java similarity index 100% rename from packages/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/FlutterActivityTest.java rename to packages/in_app_purchase/in_app_purchase/example/android/app/src/main/java/io/flutter/plugins/inapppurchaseexample/FlutterActivityTest.java diff --git a/packages/in_app_purchase/example/android/app/src/main/res/drawable/launch_background.xml b/packages/in_app_purchase/in_app_purchase/example/android/app/src/main/res/drawable/launch_background.xml similarity index 100% rename from packages/in_app_purchase/example/android/app/src/main/res/drawable/launch_background.xml rename to packages/in_app_purchase/in_app_purchase/example/android/app/src/main/res/drawable/launch_background.xml diff --git a/packages/in_app_purchase/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/packages/in_app_purchase/in_app_purchase/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from packages/in_app_purchase/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png rename to packages/in_app_purchase/in_app_purchase/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/packages/in_app_purchase/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/packages/in_app_purchase/in_app_purchase/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from packages/in_app_purchase/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png rename to packages/in_app_purchase/in_app_purchase/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/packages/in_app_purchase/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/packages/in_app_purchase/in_app_purchase/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from packages/in_app_purchase/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to packages/in_app_purchase/in_app_purchase/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/packages/in_app_purchase/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/packages/in_app_purchase/in_app_purchase/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from packages/in_app_purchase/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to packages/in_app_purchase/in_app_purchase/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/packages/in_app_purchase/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/packages/in_app_purchase/in_app_purchase/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from packages/in_app_purchase/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to packages/in_app_purchase/in_app_purchase/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/packages/in_app_purchase/example/android/app/src/main/res/values/styles.xml b/packages/in_app_purchase/in_app_purchase/example/android/app/src/main/res/values/styles.xml similarity index 100% rename from packages/in_app_purchase/example/android/app/src/main/res/values/styles.xml rename to packages/in_app_purchase/in_app_purchase/example/android/app/src/main/res/values/styles.xml diff --git a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java b/packages/in_app_purchase/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java similarity index 100% rename from packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java rename to packages/in_app_purchase/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java diff --git a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java b/packages/in_app_purchase/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java similarity index 100% rename from packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java rename to packages/in_app_purchase/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java diff --git a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java b/packages/in_app_purchase/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java similarity index 100% rename from packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java rename to packages/in_app_purchase/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java diff --git a/packages/in_app_purchase/example/android/app/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/packages/in_app_purchase/in_app_purchase/example/android/app/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker similarity index 100% rename from packages/in_app_purchase/example/android/app/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker rename to packages/in_app_purchase/in_app_purchase/example/android/app/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/packages/in_app_purchase/example/android/build.gradle b/packages/in_app_purchase/in_app_purchase/example/android/build.gradle similarity index 100% rename from packages/in_app_purchase/example/android/build.gradle rename to packages/in_app_purchase/in_app_purchase/example/android/build.gradle diff --git a/packages/in_app_purchase/example/android/gradle.properties b/packages/in_app_purchase/in_app_purchase/example/android/gradle.properties similarity index 100% rename from packages/in_app_purchase/example/android/gradle.properties rename to packages/in_app_purchase/in_app_purchase/example/android/gradle.properties diff --git a/packages/in_app_purchase/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/in_app_purchase/in_app_purchase/example/android/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from packages/in_app_purchase/example/android/gradle/wrapper/gradle-wrapper.properties rename to packages/in_app_purchase/in_app_purchase/example/android/gradle/wrapper/gradle-wrapper.properties diff --git a/packages/in_app_purchase/example/android/keystore.example.properties b/packages/in_app_purchase/in_app_purchase/example/android/keystore.example.properties similarity index 100% rename from packages/in_app_purchase/example/android/keystore.example.properties rename to packages/in_app_purchase/in_app_purchase/example/android/keystore.example.properties diff --git a/packages/in_app_purchase/example/android/settings.gradle b/packages/in_app_purchase/in_app_purchase/example/android/settings.gradle similarity index 100% rename from packages/in_app_purchase/example/android/settings.gradle rename to packages/in_app_purchase/in_app_purchase/example/android/settings.gradle diff --git a/packages/in_app_purchase/example/ios/Flutter/AppFrameworkInfo.plist b/packages/in_app_purchase/in_app_purchase/example/ios/Flutter/AppFrameworkInfo.plist similarity index 100% rename from packages/in_app_purchase/example/ios/Flutter/AppFrameworkInfo.plist rename to packages/in_app_purchase/in_app_purchase/example/ios/Flutter/AppFrameworkInfo.plist diff --git a/packages/in_app_purchase/example/ios/Flutter/Debug.xcconfig b/packages/in_app_purchase/in_app_purchase/example/ios/Flutter/Debug.xcconfig similarity index 100% rename from packages/in_app_purchase/example/ios/Flutter/Debug.xcconfig rename to packages/in_app_purchase/in_app_purchase/example/ios/Flutter/Debug.xcconfig diff --git a/packages/in_app_purchase/example/ios/Flutter/Release.xcconfig b/packages/in_app_purchase/in_app_purchase/example/ios/Flutter/Release.xcconfig similarity index 100% rename from packages/in_app_purchase/example/ios/Flutter/Release.xcconfig rename to packages/in_app_purchase/in_app_purchase/example/ios/Flutter/Release.xcconfig diff --git a/packages/in_app_purchase/example/ios/Podfile b/packages/in_app_purchase/in_app_purchase/example/ios/Podfile similarity index 100% rename from packages/in_app_purchase/example/ios/Podfile rename to packages/in_app_purchase/in_app_purchase/example/ios/Podfile diff --git a/packages/in_app_purchase/example/ios/Runner.xcodeproj/project.pbxproj b/packages/in_app_purchase/in_app_purchase/example/ios/Runner.xcodeproj/project.pbxproj similarity index 100% rename from packages/in_app_purchase/example/ios/Runner.xcodeproj/project.pbxproj rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner.xcodeproj/project.pbxproj diff --git a/packages/in_app_purchase/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/in_app_purchase/in_app_purchase/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from packages/in_app_purchase/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/packages/in_app_purchase/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/in_app_purchase/in_app_purchase/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme similarity index 100% rename from packages/in_app_purchase/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme diff --git a/packages/in_app_purchase/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/in_app_purchase/in_app_purchase/example/ios/Runner.xcworkspace/contents.xcworkspacedata similarity index 100% rename from packages/in_app_purchase/example/ios/Runner.xcworkspace/contents.xcworkspacedata rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner.xcworkspace/contents.xcworkspacedata diff --git a/packages/in_app_purchase/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/in_app_purchase/in_app_purchase/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from packages/in_app_purchase/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/packages/in_app_purchase/example/ios/Runner/AppDelegate.h b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/AppDelegate.h similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/AppDelegate.h rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/AppDelegate.h diff --git a/packages/in_app_purchase/example/ios/Runner/AppDelegate.m b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/AppDelegate.m similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/AppDelegate.m rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/AppDelegate.m diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png diff --git a/packages/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md diff --git a/packages/in_app_purchase/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Base.lproj/LaunchScreen.storyboard rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Base.lproj/LaunchScreen.storyboard diff --git a/packages/in_app_purchase/example/ios/Runner/Base.lproj/Main.storyboard b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Base.lproj/Main.storyboard similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Base.lproj/Main.storyboard rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Base.lproj/Main.storyboard diff --git a/packages/in_app_purchase/example/ios/Runner/Info.plist b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/Info.plist similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/Info.plist rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/Info.plist diff --git a/packages/in_app_purchase/example/ios/Runner/main.m b/packages/in_app_purchase/in_app_purchase/example/ios/Runner/main.m similarity index 100% rename from packages/in_app_purchase/example/ios/Runner/main.m rename to packages/in_app_purchase/in_app_purchase/example/ios/Runner/main.m diff --git a/packages/in_app_purchase/example/ios/in_app_purchase_pluginTests/Info.plist b/packages/in_app_purchase/in_app_purchase/example/ios/in_app_purchase_pluginTests/Info.plist similarity index 100% rename from packages/in_app_purchase/example/ios/in_app_purchase_pluginTests/Info.plist rename to packages/in_app_purchase/in_app_purchase/example/ios/in_app_purchase_pluginTests/Info.plist diff --git a/packages/in_app_purchase/example/lib/consumable_store.dart b/packages/in_app_purchase/in_app_purchase/example/lib/consumable_store.dart similarity index 100% rename from packages/in_app_purchase/example/lib/consumable_store.dart rename to packages/in_app_purchase/in_app_purchase/example/lib/consumable_store.dart diff --git a/packages/in_app_purchase/example/lib/main.dart b/packages/in_app_purchase/in_app_purchase/example/lib/main.dart similarity index 100% rename from packages/in_app_purchase/example/lib/main.dart rename to packages/in_app_purchase/in_app_purchase/example/lib/main.dart diff --git a/packages/in_app_purchase/example/pubspec.yaml b/packages/in_app_purchase/in_app_purchase/example/pubspec.yaml similarity index 100% rename from packages/in_app_purchase/example/pubspec.yaml rename to packages/in_app_purchase/in_app_purchase/example/pubspec.yaml diff --git a/packages/in_app_purchase/example/test_driver/test/integration_test.dart b/packages/in_app_purchase/in_app_purchase/example/test_driver/test/integration_test.dart similarity index 100% rename from packages/in_app_purchase/example/test_driver/test/integration_test.dart rename to packages/in_app_purchase/in_app_purchase/example/test_driver/test/integration_test.dart diff --git a/packages/in_app_purchase/integration_test/in_app_purchase_test.dart b/packages/in_app_purchase/in_app_purchase/integration_test/in_app_purchase_test.dart similarity index 100% rename from packages/in_app_purchase/integration_test/in_app_purchase_test.dart rename to packages/in_app_purchase/in_app_purchase/integration_test/in_app_purchase_test.dart diff --git a/packages/in_app_purchase/ios/Assets/.gitkeep b/packages/in_app_purchase/in_app_purchase/ios/Assets/.gitkeep similarity index 100% rename from packages/in_app_purchase/ios/Assets/.gitkeep rename to packages/in_app_purchase/in_app_purchase/ios/Assets/.gitkeep diff --git a/packages/in_app_purchase/ios/Classes/FIAObjectTranslator.h b/packages/in_app_purchase/in_app_purchase/ios/Classes/FIAObjectTranslator.h similarity index 100% rename from packages/in_app_purchase/ios/Classes/FIAObjectTranslator.h rename to packages/in_app_purchase/in_app_purchase/ios/Classes/FIAObjectTranslator.h diff --git a/packages/in_app_purchase/ios/Classes/FIAObjectTranslator.m b/packages/in_app_purchase/in_app_purchase/ios/Classes/FIAObjectTranslator.m similarity index 100% rename from packages/in_app_purchase/ios/Classes/FIAObjectTranslator.m rename to packages/in_app_purchase/in_app_purchase/ios/Classes/FIAObjectTranslator.m diff --git a/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.h b/packages/in_app_purchase/in_app_purchase/ios/Classes/FIAPReceiptManager.h similarity index 100% rename from packages/in_app_purchase/ios/Classes/FIAPReceiptManager.h rename to packages/in_app_purchase/in_app_purchase/ios/Classes/FIAPReceiptManager.h diff --git a/packages/in_app_purchase/ios/Classes/FIAPReceiptManager.m b/packages/in_app_purchase/in_app_purchase/ios/Classes/FIAPReceiptManager.m similarity index 100% rename from packages/in_app_purchase/ios/Classes/FIAPReceiptManager.m rename to packages/in_app_purchase/in_app_purchase/ios/Classes/FIAPReceiptManager.m diff --git a/packages/in_app_purchase/ios/Classes/FIAPRequestHandler.h b/packages/in_app_purchase/in_app_purchase/ios/Classes/FIAPRequestHandler.h similarity index 100% rename from packages/in_app_purchase/ios/Classes/FIAPRequestHandler.h rename to packages/in_app_purchase/in_app_purchase/ios/Classes/FIAPRequestHandler.h diff --git a/packages/in_app_purchase/ios/Classes/FIAPRequestHandler.m b/packages/in_app_purchase/in_app_purchase/ios/Classes/FIAPRequestHandler.m similarity index 100% rename from packages/in_app_purchase/ios/Classes/FIAPRequestHandler.m rename to packages/in_app_purchase/in_app_purchase/ios/Classes/FIAPRequestHandler.m diff --git a/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.h b/packages/in_app_purchase/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.h similarity index 100% rename from packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.h rename to packages/in_app_purchase/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.h diff --git a/packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.m b/packages/in_app_purchase/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.m similarity index 100% rename from packages/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.m rename to packages/in_app_purchase/in_app_purchase/ios/Classes/FIAPaymentQueueHandler.m diff --git a/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.h b/packages/in_app_purchase/in_app_purchase/ios/Classes/InAppPurchasePlugin.h similarity index 100% rename from packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.h rename to packages/in_app_purchase/in_app_purchase/ios/Classes/InAppPurchasePlugin.h diff --git a/packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m b/packages/in_app_purchase/in_app_purchase/ios/Classes/InAppPurchasePlugin.m similarity index 100% rename from packages/in_app_purchase/ios/Classes/InAppPurchasePlugin.m rename to packages/in_app_purchase/in_app_purchase/ios/Classes/InAppPurchasePlugin.m diff --git a/packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m b/packages/in_app_purchase/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m similarity index 100% rename from packages/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m rename to packages/in_app_purchase/in_app_purchase/ios/Tests/InAppPurchasePluginTest.m diff --git a/packages/in_app_purchase/ios/Tests/PaymentQueueTest.m b/packages/in_app_purchase/in_app_purchase/ios/Tests/PaymentQueueTest.m similarity index 100% rename from packages/in_app_purchase/ios/Tests/PaymentQueueTest.m rename to packages/in_app_purchase/in_app_purchase/ios/Tests/PaymentQueueTest.m diff --git a/packages/in_app_purchase/ios/Tests/ProductRequestHandlerTest.m b/packages/in_app_purchase/in_app_purchase/ios/Tests/ProductRequestHandlerTest.m similarity index 100% rename from packages/in_app_purchase/ios/Tests/ProductRequestHandlerTest.m rename to packages/in_app_purchase/in_app_purchase/ios/Tests/ProductRequestHandlerTest.m diff --git a/packages/in_app_purchase/ios/Tests/Stubs.h b/packages/in_app_purchase/in_app_purchase/ios/Tests/Stubs.h similarity index 100% rename from packages/in_app_purchase/ios/Tests/Stubs.h rename to packages/in_app_purchase/in_app_purchase/ios/Tests/Stubs.h diff --git a/packages/in_app_purchase/ios/Tests/Stubs.m b/packages/in_app_purchase/in_app_purchase/ios/Tests/Stubs.m similarity index 100% rename from packages/in_app_purchase/ios/Tests/Stubs.m rename to packages/in_app_purchase/in_app_purchase/ios/Tests/Stubs.m diff --git a/packages/in_app_purchase/ios/Tests/TranslatorTest.m b/packages/in_app_purchase/in_app_purchase/ios/Tests/TranslatorTest.m similarity index 100% rename from packages/in_app_purchase/ios/Tests/TranslatorTest.m rename to packages/in_app_purchase/in_app_purchase/ios/Tests/TranslatorTest.m diff --git a/packages/in_app_purchase/ios/in_app_purchase.podspec b/packages/in_app_purchase/in_app_purchase/ios/in_app_purchase.podspec similarity index 100% rename from packages/in_app_purchase/ios/in_app_purchase.podspec rename to packages/in_app_purchase/in_app_purchase/ios/in_app_purchase.podspec diff --git a/packages/in_app_purchase/lib/billing_client_wrappers.dart b/packages/in_app_purchase/in_app_purchase/lib/billing_client_wrappers.dart similarity index 100% rename from packages/in_app_purchase/lib/billing_client_wrappers.dart rename to packages/in_app_purchase/in_app_purchase/lib/billing_client_wrappers.dart diff --git a/packages/in_app_purchase/lib/in_app_purchase.dart b/packages/in_app_purchase/in_app_purchase/lib/in_app_purchase.dart similarity index 100% rename from packages/in_app_purchase/lib/in_app_purchase.dart rename to packages/in_app_purchase/in_app_purchase/lib/in_app_purchase.dart diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/README.md b/packages/in_app_purchase/in_app_purchase/lib/src/billing_client_wrappers/README.md similarity index 100% rename from packages/in_app_purchase/lib/src/billing_client_wrappers/README.md rename to packages/in_app_purchase/in_app_purchase/lib/src/billing_client_wrappers/README.md diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart b/packages/in_app_purchase/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart similarity index 100% rename from packages/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/billing_client_wrappers/billing_client_wrapper.dart diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart b/packages/in_app_purchase/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart similarity index 100% rename from packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.dart diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.g.dart b/packages/in_app_purchase/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.g.dart similarity index 100% rename from packages/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.g.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/billing_client_wrappers/enum_converters.g.dart diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart b/packages/in_app_purchase/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart similarity index 100% rename from packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.dart diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.g.dart b/packages/in_app_purchase/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.g.dart similarity index 100% rename from packages/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.g.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/billing_client_wrappers/purchase_wrapper.g.dart diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart b/packages/in_app_purchase/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart similarity index 100% rename from packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.dart diff --git a/packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.g.dart b/packages/in_app_purchase/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.g.dart similarity index 100% rename from packages/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.g.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/billing_client_wrappers/sku_details_wrapper.g.dart diff --git a/packages/in_app_purchase/lib/src/channel.dart b/packages/in_app_purchase/in_app_purchase/lib/src/channel.dart similarity index 100% rename from packages/in_app_purchase/lib/src/channel.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/channel.dart diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/README.md b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/README.md similarity index 100% rename from packages/in_app_purchase/lib/src/in_app_purchase/README.md rename to packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/README.md diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart similarity index 100% rename from packages/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart similarity index 100% rename from packages/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/google_play_connection.dart diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart similarity index 100% rename from packages/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/product_details.dart b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart similarity index 100% rename from packages/in_app_purchase/lib/src/in_app_purchase/product_details.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart diff --git a/packages/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart similarity index 100% rename from packages/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/purchase_details.dart diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/README.md b/packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/README.md similarity index 100% rename from packages/in_app_purchase/lib/src/store_kit_wrappers/README.md rename to packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/README.md diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.dart b/packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.dart similarity index 100% rename from packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.dart diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.g.dart b/packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.g.dart similarity index 100% rename from packages/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.g.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/enum_converters.g.dart diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart b/packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart similarity index 100% rename from packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.dart diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.g.dart b/packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.g.dart similarity index 100% rename from packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.g.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_queue_wrapper.g.dart diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.dart b/packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.dart similarity index 100% rename from packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.dart diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.g.dart b/packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.g.dart similarity index 100% rename from packages/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.g.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/sk_payment_transaction_wrappers.g.dart diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.dart b/packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.dart similarity index 100% rename from packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.dart diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.g.dart b/packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.g.dart similarity index 100% rename from packages/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.g.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/sk_product_wrapper.g.dart diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_receipt_manager.dart b/packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/sk_receipt_manager.dart similarity index 100% rename from packages/in_app_purchase/lib/src/store_kit_wrappers/sk_receipt_manager.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/sk_receipt_manager.dart diff --git a/packages/in_app_purchase/lib/src/store_kit_wrappers/sk_request_maker.dart b/packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/sk_request_maker.dart similarity index 100% rename from packages/in_app_purchase/lib/src/store_kit_wrappers/sk_request_maker.dart rename to packages/in_app_purchase/in_app_purchase/lib/src/store_kit_wrappers/sk_request_maker.dart diff --git a/packages/in_app_purchase/lib/store_kit_wrappers.dart b/packages/in_app_purchase/in_app_purchase/lib/store_kit_wrappers.dart similarity index 100% rename from packages/in_app_purchase/lib/store_kit_wrappers.dart rename to packages/in_app_purchase/in_app_purchase/lib/store_kit_wrappers.dart diff --git a/packages/in_app_purchase/pubspec.yaml b/packages/in_app_purchase/in_app_purchase/pubspec.yaml similarity index 100% rename from packages/in_app_purchase/pubspec.yaml rename to packages/in_app_purchase/in_app_purchase/pubspec.yaml diff --git a/packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart b/packages/in_app_purchase/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart similarity index 100% rename from packages/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart rename to packages/in_app_purchase/in_app_purchase/test/billing_client_wrappers/billing_client_wrapper_test.dart diff --git a/packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart b/packages/in_app_purchase/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart similarity index 100% rename from packages/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart rename to packages/in_app_purchase/in_app_purchase/test/billing_client_wrappers/purchase_wrapper_test.dart diff --git a/packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart b/packages/in_app_purchase/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart similarity index 100% rename from packages/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart rename to packages/in_app_purchase/in_app_purchase/test/billing_client_wrappers/sku_details_wrapper_test.dart diff --git a/packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart b/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart similarity index 100% rename from packages/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart rename to packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart diff --git a/packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart b/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart similarity index 100% rename from packages/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart rename to packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/google_play_connection_test.dart diff --git a/packages/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart b/packages/in_app_purchase/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart similarity index 100% rename from packages/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart rename to packages/in_app_purchase/in_app_purchase/test/store_kit_wrappers/sk_methodchannel_apis_test.dart diff --git a/packages/in_app_purchase/test/store_kit_wrappers/sk_product_test.dart b/packages/in_app_purchase/in_app_purchase/test/store_kit_wrappers/sk_product_test.dart similarity index 100% rename from packages/in_app_purchase/test/store_kit_wrappers/sk_product_test.dart rename to packages/in_app_purchase/in_app_purchase/test/store_kit_wrappers/sk_product_test.dart diff --git a/packages/in_app_purchase/test/store_kit_wrappers/sk_test_stub_objects.dart b/packages/in_app_purchase/in_app_purchase/test/store_kit_wrappers/sk_test_stub_objects.dart similarity index 100% rename from packages/in_app_purchase/test/store_kit_wrappers/sk_test_stub_objects.dart rename to packages/in_app_purchase/in_app_purchase/test/store_kit_wrappers/sk_test_stub_objects.dart diff --git a/packages/in_app_purchase/test/stub_in_app_purchase_platform.dart b/packages/in_app_purchase/in_app_purchase/test/stub_in_app_purchase_platform.dart similarity index 100% rename from packages/in_app_purchase/test/stub_in_app_purchase_platform.dart rename to packages/in_app_purchase/in_app_purchase/test/stub_in_app_purchase_platform.dart diff --git a/packages/in_app_purchase/in_app_purchase_android.iml b/packages/in_app_purchase/in_app_purchase_android.iml deleted file mode 100644 index ac5d744d7acc..000000000000 --- a/packages/in_app_purchase/in_app_purchase_android.iml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - From 3f3f8342c105a856089b92120f16afcd104c5d25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl?= <32639467+danielroek@users.noreply.github.com> Date: Thu, 25 Mar 2021 10:09:03 +0100 Subject: [PATCH 0298/1565] [quick_actions] 3/3 Quick actions federated migration (#3736) --- AUTHORS | 1 + .../quick_actions/quick_actions/CHANGELOG.md | 4 + .../integration_test/quick_actions_test.dart | 2 +- .../quick_actions/lib/quick_actions.dart | 82 ++---------- .../quick_actions/quick_actions/pubspec.yaml | 11 +- .../test/quick_actions_test.dart | 119 +++++++----------- 6 files changed, 68 insertions(+), 151 deletions(-) diff --git a/AUTHORS b/AUTHORS index 493a0b4ef9c2..0ca697b6a756 100644 --- a/AUTHORS +++ b/AUTHORS @@ -64,3 +64,4 @@ Aleksandr Yurkovskiy Anton Borries Alex Li Rahul Raj <64.rahulraj@gmail.com> +Daniel Roek diff --git a/packages/quick_actions/quick_actions/CHANGELOG.md b/packages/quick_actions/quick_actions/CHANGELOG.md index 5f192825cacf..3fd0c7e28256 100644 --- a/packages/quick_actions/quick_actions/CHANGELOG.md +++ b/packages/quick_actions/quick_actions/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.0 + +* Migrate to federated architecture. + ## 0.5.0+1 * Updated example app implementation. diff --git a/packages/quick_actions/quick_actions/example/integration_test/quick_actions_test.dart b/packages/quick_actions/quick_actions/example/integration_test/quick_actions_test.dart index 4b0ec7584243..cfe3eb0db656 100644 --- a/packages/quick_actions/quick_actions/example/integration_test/quick_actions_test.dart +++ b/packages/quick_actions/quick_actions/example/integration_test/quick_actions_test.dart @@ -12,7 +12,7 @@ void main() { testWidgets('Can set shortcuts', (WidgetTester tester) async { final QuickActions quickActions = QuickActions(); - quickActions.initialize(null); + await quickActions.initialize(null); const ShortcutItem shortCutItem = ShortcutItem( type: 'action_one', diff --git a/packages/quick_actions/quick_actions/lib/quick_actions.dart b/packages/quick_actions/quick_actions/lib/quick_actions.dart index 23dd15302d57..f90a44e0443d 100644 --- a/packages/quick_actions/quick_actions/lib/quick_actions.dart +++ b/packages/quick_actions/quick_actions/lib/quick_actions.dart @@ -4,90 +4,24 @@ import 'dart:async'; -import 'package:flutter/services.dart'; -import 'package:meta/meta.dart'; +import 'package:quick_actions_platform_interface/platform_interface/quick_actions_platform.dart'; +import 'package:quick_actions_platform_interface/types/types.dart'; -const MethodChannel _kChannel = - MethodChannel('plugins.flutter.io/quick_actions'); - -/// Handler for a quick action launch event. -/// -/// The argument [type] corresponds to the [ShortcutItem]'s field. -typedef void QuickActionHandler(String type); - -/// Home screen quick-action shortcut item. -class ShortcutItem { - /// Constructs an instance with the given [type], [localizedTitle], and - /// [icon]. - /// - /// Only [icon] should be nullable. It will remain `null` if unset. - const ShortcutItem({ - required this.type, - required this.localizedTitle, - this.icon, - }); - - /// The identifier of this item; should be unique within the app. - final String type; - - /// Localized title of the item. - final String localizedTitle; - - /// Name of native resource (xcassets etc; NOT a Flutter asset) to be - /// displayed as the icon for this item. - final String? icon; -} +export 'package:quick_actions_platform_interface/types/types.dart'; /// Quick actions plugin. class QuickActions { - /// Gets an instance of the plugin with the default methodChannel. - /// - /// [initialize] should be called before using any other methods. - factory QuickActions() => _instance; - - /// This is a test-only constructor. Do not call this, it can break at any - /// time. - @visibleForTesting - QuickActions.withMethodChannel(this.channel); - - static final QuickActions _instance = - QuickActions.withMethodChannel(_kChannel); - - /// This is a test-only accessor. Do not call this, it can break at any time. - @visibleForTesting - final MethodChannel channel; - /// Initializes this plugin. /// /// Call this once before any further interaction with the the plugin. - void initialize(QuickActionHandler handler) async { - channel.setMethodCallHandler((MethodCall call) async { - assert(call.method == 'launch'); - handler(call.arguments); - }); - final String? action = - await channel.invokeMethod('getLaunchAction'); - if (action != null) { - handler(action); - } - } + Future initialize(QuickActionHandler handler) async => + QuickActionsPlatform.instance.initialize(handler); /// Sets the [ShortcutItem]s to become the app's quick actions. - Future setShortcutItems(List items) async { - final List> itemsList = - items.map(_serializeItem).toList(); - await channel.invokeMethod('setShortcutItems', itemsList); - } + Future setShortcutItems(List items) async => + QuickActionsPlatform.instance.setShortcutItems(items); /// Removes all [ShortcutItem]s registered for the app. Future clearShortcutItems() => - channel.invokeMethod('clearShortcutItems'); - - Map _serializeItem(ShortcutItem item) { - return { - 'type': item.type, - 'localizedTitle': item.localizedTitle, - 'icon': item.icon, - }; - } + QuickActionsPlatform.instance.clearShortcutItems(); } diff --git a/packages/quick_actions/quick_actions/pubspec.yaml b/packages/quick_actions/quick_actions/pubspec.yaml index 71accce09fcf..f6622525d458 100644 --- a/packages/quick_actions/quick_actions/pubspec.yaml +++ b/packages/quick_actions/quick_actions/pubspec.yaml @@ -2,7 +2,7 @@ name: quick_actions description: Flutter plugin for creating shortcuts on home screen, also known as Quick Actions on iOS and App Shortcuts on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/quick_actions -version: 0.5.0+1 +version: 0.6.0 flutter: plugin: @@ -17,15 +17,18 @@ dependencies: flutter: sdk: flutter meta: ^1.3.0 + quick_actions_platform_interface: ^1.0.0 dev_dependencies: - test: ^1.16.3 flutter_test: sdk: flutter integration_test: sdk: flutter - pedantic: ^1.10.0 + mockito: ^5.0.0-nullsafety.7 + pedantic: ^1.11.0 + plugin_platform_interface: ^2.0.0 + environment: - sdk: ">=2.12.0-259.9.beta <3.0.0" + sdk: ">=2.12.0 <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/quick_actions/quick_actions/test/quick_actions_test.dart b/packages/quick_actions/quick_actions/test/quick_actions_test.dart index ccb593f149fb..b8d7695735b6 100644 --- a/packages/quick_actions/quick_actions/test/quick_actions_test.dart +++ b/packages/quick_actions/quick_actions/test/quick_actions_test.dart @@ -2,90 +2,65 @@ // 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 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'package:quick_actions/quick_actions.dart'; +import 'package:quick_actions_platform_interface/platform_interface/quick_actions_platform.dart'; +import 'package:quick_actions_platform_interface/quick_actions_platform_interface.dart'; +import 'package:quick_actions_platform_interface/types/shortcut_item.dart'; void main() { - TestWidgetsFlutterBinding.ensureInitialized(); + group('$QuickActions', () { + setUp(() { + QuickActionsPlatform.instance = MockQuickActionsPlatform(); + }); - late QuickActions quickActions; - final List log = []; + test('initialize() PlatformInterface', () async { + QuickActions quickActions = QuickActions(); + QuickActionHandler handler = (type) {}; - setUp(() { - quickActions = QuickActions(); - quickActions.channel.setMockMethodCallHandler( - (MethodCall methodCall) async { - log.add(methodCall); - return 'non empty response'; - }, - ); - }); + await quickActions.initialize(handler); + verify(QuickActionsPlatform.instance.initialize(handler)).called(1); + }); - test('setShortcutItems with demo data', () async { - const String type = 'type'; - const String localizedTitle = 'localizedTitle'; - const String icon = 'icon'; - await quickActions.setShortcutItems( - const [ - ShortcutItem(type: type, localizedTitle: localizedTitle, icon: icon) - ], - ); - expect( - log, - [ - isMethodCall( - 'setShortcutItems', - arguments: >[ - { - 'type': type, - 'localizedTitle': localizedTitle, - 'icon': icon, - } - ], - ), - ], - ); - log.clear(); - }); + test('setShortcutItems() PlatformInterface', () { + QuickActions quickActions = QuickActions(); + QuickActionHandler handler = (type) {}; + quickActions.initialize(handler); + quickActions.setShortcutItems([]); - test('clearShortcutItems', () { - quickActions.clearShortcutItems(); - expect( - log, - [ - isMethodCall('clearShortcutItems', arguments: null), - ], - ); - log.clear(); - }); + verify(QuickActionsPlatform.instance.initialize(handler)).called(1); + verify(QuickActionsPlatform.instance.setShortcutItems([])).called(1); + }); - test('initialize', () async { - final Completer quickActionsHandler = Completer(); - quickActions.initialize((_) => quickActionsHandler.complete(true)); - expect( - log, - [ - isMethodCall('getLaunchAction', arguments: null), - ], - ); - log.clear(); + test('clearShortcutItems() PlatformInterface', () { + QuickActions quickActions = QuickActions(); + QuickActionHandler handler = (type) {}; - expect(quickActionsHandler.future, completion(isTrue)); + quickActions.initialize(handler); + quickActions.clearShortcutItems(); + + verify(QuickActionsPlatform.instance.initialize(handler)).called(1); + verify(QuickActionsPlatform.instance.clearShortcutItems()).called(1); + }); }); +} - test('Shortcut item can be constructed', () { - const String type = 'type'; - const String localizedTitle = 'title'; - const String icon = 'foo'; +class MockQuickActionsPlatform extends Mock + with MockPlatformInterfaceMixin + implements QuickActionsPlatform { + @override + Future clearShortcutItems() async => + super.noSuchMethod(Invocation.method(#clearShortcutItems, [])); - const ShortcutItem item = - ShortcutItem(type: type, localizedTitle: localizedTitle, icon: icon); + @override + Future initialize(QuickActionHandler? handler) async => + super.noSuchMethod(Invocation.method(#initialize, [handler])); - expect(item.type, type); - expect(item.localizedTitle, localizedTitle); - expect(item.icon, icon); - }); + @override + Future setShortcutItems(List? items) async => + super.noSuchMethod(Invocation.method(#setShortcutItems, [items])); } + +class MockQuickActions extends QuickActions {} From 3dd9871f8df6a060bbe8a6b6a5f1c4d03a92fa43 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 25 Mar 2021 11:23:02 +0100 Subject: [PATCH 0299/1565] Fixed some minor spelling mistakes in README (#3749) --- packages/in_app_purchase/in_app_purchase/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/in_app_purchase/in_app_purchase/README.md b/packages/in_app_purchase/in_app_purchase/README.md index 321864b2a233..62adaa9b4dec 100644 --- a/packages/in_app_purchase/in_app_purchase/README.md +++ b/packages/in_app_purchase/in_app_purchase/README.md @@ -24,7 +24,7 @@ your app with each store to handle purchases using them. Both have extensive guides: * [In-App Purchase (App Store)](https://developer.apple.com/in-app-purchase/) -* [Google Play Biling Overview](https://developer.android.com/google/play/billing/billing_overview) +* [Google Play Billing Overview](https://developer.android.com/google/play/billing/billing_overview) You can check out the [example app README](https://github.com/flutter/plugins/blob/master/packages/in_app_purchase/example/README.md) for steps on how to configure in app purchases in both stores. @@ -34,7 +34,7 @@ able to start using the plugin. There's two basic options available to you to use. 1. [in_app_purchase.dart](https://github.com/flutter/plugins/tree/master/packages/in_app_purchase/lib/src/in_app_purchase), - the generic idiommatic Flutter API. This exposes the most basic IAP-related + the generic idiomatic Flutter API. This exposes the most basic IAP-related functionality. The goal is that Flutter apps should be able to use this API surface on its own for the vast majority of cases. If you use this you should be able to handle most use cases for loading and making purchases. If you would From a303d6ded0f4ddbf0819ab2cf9b42b53dc535e47 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 25 Mar 2021 13:40:14 +0100 Subject: [PATCH 0300/1565] Fix error message (#3750) --- packages/in_app_purchase/in_app_purchase/AUTHORS | 1 + .../in_app_purchase/in_app_purchase/CHANGELOG.md | 4 ++++ .../src/in_app_purchase/app_store_connection.dart | 2 +- .../in_app_purchase/in_app_purchase/pubspec.yaml | 2 +- .../app_store_connection_test.dart | 13 ++++++++++--- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/packages/in_app_purchase/in_app_purchase/AUTHORS b/packages/in_app_purchase/in_app_purchase/AUTHORS index 493a0b4ef9c2..78f9e5ad9f6b 100644 --- a/packages/in_app_purchase/in_app_purchase/AUTHORS +++ b/packages/in_app_purchase/in_app_purchase/AUTHORS @@ -64,3 +64,4 @@ Aleksandr Yurkovskiy Anton Borries Alex Li Rahul Raj <64.rahulraj@gmail.com> +Maurits van Beusekom diff --git a/packages/in_app_purchase/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase/CHANGELOG.md index 84a65f4159f3..6936edd52013 100644 --- a/packages/in_app_purchase/in_app_purchase/CHANGELOG.md +++ b/packages/in_app_purchase/in_app_purchase/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.2 + +* Fix error message when trying to consume purchase on iOS. + ## 0.5.1 * [iOS] Introduce `SKPaymentQueueWrapper.presentCodeRedemptionSheet` diff --git a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart index 069cf7800599..3c56f01966cb 100644 --- a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart +++ b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart @@ -97,7 +97,7 @@ class AppStoreConnection implements InAppPurchaseConnection { @override Future consumePurchase(PurchaseDetails purchase) { - throw UnsupportedError('consume purchase is not available on Android'); + throw UnsupportedError('consume purchase is not available on iOS'); } @override diff --git a/packages/in_app_purchase/in_app_purchase/pubspec.yaml b/packages/in_app_purchase/in_app_purchase/pubspec.yaml index 2a8f56946bf2..c7226078c722 100644 --- a/packages/in_app_purchase/in_app_purchase/pubspec.yaml +++ b/packages/in_app_purchase/in_app_purchase/pubspec.yaml @@ -1,7 +1,7 @@ name: in_app_purchase description: A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases through the App Store and Google Play. homepage: https://github.com/flutter/plugins/tree/master/packages/in_app_purchase -version: 0.5.1 +version: 0.5.2 dependencies: flutter: diff --git a/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart b/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart index dfab31906231..c112829468db 100644 --- a/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart +++ b/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart @@ -294,9 +294,16 @@ void main() { group('consume purchase', () { test('should throw when calling consume purchase on iOS', () async { expect( - () => AppStoreConnection.instance - .consumePurchase(PurchaseDetails.fromPurchase(dummyPurchase)), - throwsUnsupportedError); + () => AppStoreConnection.instance + .consumePurchase(PurchaseDetails.fromPurchase(dummyPurchase)), + throwsA( + isA().having( + (error) => error.message, + 'message', + 'consume purchase is not available on iOS', + ), + ), + ); }); }); From a17efbf861723108a034415f8267780e5fb869be Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 25 Mar 2021 15:16:36 +0100 Subject: [PATCH 0301/1565] Revert "Fix error message (#3750)" (#3751) This reverts commit a303d6ded0f4ddbf0819ab2cf9b42b53dc535e47. --- packages/in_app_purchase/in_app_purchase/AUTHORS | 1 - .../in_app_purchase/in_app_purchase/CHANGELOG.md | 4 ---- .../src/in_app_purchase/app_store_connection.dart | 2 +- .../in_app_purchase/in_app_purchase/pubspec.yaml | 2 +- .../app_store_connection_test.dart | 13 +++---------- 5 files changed, 5 insertions(+), 17 deletions(-) diff --git a/packages/in_app_purchase/in_app_purchase/AUTHORS b/packages/in_app_purchase/in_app_purchase/AUTHORS index 78f9e5ad9f6b..493a0b4ef9c2 100644 --- a/packages/in_app_purchase/in_app_purchase/AUTHORS +++ b/packages/in_app_purchase/in_app_purchase/AUTHORS @@ -64,4 +64,3 @@ Aleksandr Yurkovskiy Anton Borries Alex Li Rahul Raj <64.rahulraj@gmail.com> -Maurits van Beusekom diff --git a/packages/in_app_purchase/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase/CHANGELOG.md index 6936edd52013..84a65f4159f3 100644 --- a/packages/in_app_purchase/in_app_purchase/CHANGELOG.md +++ b/packages/in_app_purchase/in_app_purchase/CHANGELOG.md @@ -1,7 +1,3 @@ -## 0.5.2 - -* Fix error message when trying to consume purchase on iOS. - ## 0.5.1 * [iOS] Introduce `SKPaymentQueueWrapper.presentCodeRedemptionSheet` diff --git a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart index 3c56f01966cb..069cf7800599 100644 --- a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart +++ b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart @@ -97,7 +97,7 @@ class AppStoreConnection implements InAppPurchaseConnection { @override Future consumePurchase(PurchaseDetails purchase) { - throw UnsupportedError('consume purchase is not available on iOS'); + throw UnsupportedError('consume purchase is not available on Android'); } @override diff --git a/packages/in_app_purchase/in_app_purchase/pubspec.yaml b/packages/in_app_purchase/in_app_purchase/pubspec.yaml index c7226078c722..2a8f56946bf2 100644 --- a/packages/in_app_purchase/in_app_purchase/pubspec.yaml +++ b/packages/in_app_purchase/in_app_purchase/pubspec.yaml @@ -1,7 +1,7 @@ name: in_app_purchase description: A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases through the App Store and Google Play. homepage: https://github.com/flutter/plugins/tree/master/packages/in_app_purchase -version: 0.5.2 +version: 0.5.1 dependencies: flutter: diff --git a/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart b/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart index c112829468db..dfab31906231 100644 --- a/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart +++ b/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart @@ -294,16 +294,9 @@ void main() { group('consume purchase', () { test('should throw when calling consume purchase on iOS', () async { expect( - () => AppStoreConnection.instance - .consumePurchase(PurchaseDetails.fromPurchase(dummyPurchase)), - throwsA( - isA().having( - (error) => error.message, - 'message', - 'consume purchase is not available on iOS', - ), - ), - ); + () => AppStoreConnection.instance + .consumePurchase(PurchaseDetails.fromPurchase(dummyPurchase)), + throwsUnsupportedError); }); }); From 708bf9c09a6c1059b8e3dbba27965e7cd5989b28 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 25 Mar 2021 15:44:18 +0100 Subject: [PATCH 0302/1565] Fix error message (#3752) --- packages/in_app_purchase/in_app_purchase/AUTHORS | 1 + .../in_app_purchase/in_app_purchase/CHANGELOG.md | 4 ++++ .../src/in_app_purchase/app_store_connection.dart | 2 +- .../in_app_purchase/in_app_purchase/pubspec.yaml | 2 +- .../app_store_connection_test.dart | 13 ++++++++++--- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/packages/in_app_purchase/in_app_purchase/AUTHORS b/packages/in_app_purchase/in_app_purchase/AUTHORS index 493a0b4ef9c2..78f9e5ad9f6b 100644 --- a/packages/in_app_purchase/in_app_purchase/AUTHORS +++ b/packages/in_app_purchase/in_app_purchase/AUTHORS @@ -64,3 +64,4 @@ Aleksandr Yurkovskiy Anton Borries Alex Li Rahul Raj <64.rahulraj@gmail.com> +Maurits van Beusekom diff --git a/packages/in_app_purchase/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase/CHANGELOG.md index 84a65f4159f3..114f11aa89b3 100644 --- a/packages/in_app_purchase/in_app_purchase/CHANGELOG.md +++ b/packages/in_app_purchase/in_app_purchase/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.1+1 + +* Fix error message when trying to consume purchase on iOS. + ## 0.5.1 * [iOS] Introduce `SKPaymentQueueWrapper.presentCodeRedemptionSheet` diff --git a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart index 069cf7800599..3c56f01966cb 100644 --- a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart +++ b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/app_store_connection.dart @@ -97,7 +97,7 @@ class AppStoreConnection implements InAppPurchaseConnection { @override Future consumePurchase(PurchaseDetails purchase) { - throw UnsupportedError('consume purchase is not available on Android'); + throw UnsupportedError('consume purchase is not available on iOS'); } @override diff --git a/packages/in_app_purchase/in_app_purchase/pubspec.yaml b/packages/in_app_purchase/in_app_purchase/pubspec.yaml index 2a8f56946bf2..b42ca8806819 100644 --- a/packages/in_app_purchase/in_app_purchase/pubspec.yaml +++ b/packages/in_app_purchase/in_app_purchase/pubspec.yaml @@ -1,7 +1,7 @@ name: in_app_purchase description: A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases through the App Store and Google Play. homepage: https://github.com/flutter/plugins/tree/master/packages/in_app_purchase -version: 0.5.1 +version: 0.5.1+1 dependencies: flutter: diff --git a/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart b/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart index dfab31906231..c112829468db 100644 --- a/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart +++ b/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/app_store_connection_test.dart @@ -294,9 +294,16 @@ void main() { group('consume purchase', () { test('should throw when calling consume purchase on iOS', () async { expect( - () => AppStoreConnection.instance - .consumePurchase(PurchaseDetails.fromPurchase(dummyPurchase)), - throwsUnsupportedError); + () => AppStoreConnection.instance + .consumePurchase(PurchaseDetails.fromPurchase(dummyPurchase)), + throwsA( + isA().having( + (error) => error.message, + 'message', + 'consume purchase is not available on iOS', + ), + ), + ); }); }); From c3dc31f665f3ccaa96898a6f719591c8642c32de Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 25 Mar 2021 17:43:51 +0100 Subject: [PATCH 0303/1565] Update example instructions (#3753) --- .../in_app_purchase/example/README.md | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/in_app_purchase/in_app_purchase/example/README.md b/packages/in_app_purchase/in_app_purchase/example/README.md index ef32964f141d..0ecf42298433 100644 --- a/packages/in_app_purchase/in_app_purchase/example/README.md +++ b/packages/in_app_purchase/in_app_purchase/example/README.md @@ -72,7 +72,8 @@ below. - A consumable with product ID `consumable` - An upgrade with product ID `upgrade` - - An auto-renewing subscription with product ID `subscription` + - An auto-renewing subscription with product ID `subscription_silver` + - An non-renewing subscription with product ID `subscription_gold` 2. In XCode, `File > Open File` `example/ios/Runner.xcworkspace`. Update the Bundle ID to match the Bundle ID of the app created in step #1. @@ -82,8 +83,15 @@ below. in-app purchases with. 4. Use `flutter run` to install the app and test it. Note that you need to test - it on a real device instead of a simulator, and signing into any production - service (including iTunes!) with the test account will permanently invalidate - it. Sign in to the test account in the example app following the steps in the - [*In-App Purchase Programming - Guide*](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/ShowUI.html#//apple_ref/doc/uid/TP40008267-CH3-SW11). + it on a real device instead of a simulator. Next click on one of the products + in the example App, this enables the "SANDBOX ACCOUNT" section in the iOS + settings. You will now be asked to sign in with your sandbox test account to + complete the purchase (no worries you won't be charged). If for some reason + you aren't asked to sign-in or the wrong user is listed, go into the iOS + settings ("Settings" -> "App Store" -> "SANDBOX ACCOUNT") and update your + sandbox account from there. This procedure is explained in great detail in + the [Testing In-App Purchases with Sandbox](https://developer.apple.com/documentation/storekit/in-app_purchase/testing_in-app_purchases_with_sandbox?language=objc) article. + + +**Important:** signing into any production service (including iTunes!) with the +sandbox test account will permanently invalidate it. From eab885b84b99f72bb7b8c8b7a5edba6eaaa68808 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Thu, 25 Mar 2021 10:27:23 -0700 Subject: [PATCH 0304/1565] [google_maps_flutter] Fix handling of non-nullable invokeMethod return types (#3754) During the null-safety migration I accepted the auto-migrator use of as Future to handle invokeMethod returning a T?. I didn't realize that as does not actually do that kind of casting, and will fail with "type 'Future' is not a subtype of type 'Future' in type cast". There were no tests that exercised these methods in any way, so automated tests didn't catch the bug. This adds a minimal test that calls all of the non-void methods to ensure that they don't explode (and a TODO to backfill full unit tests of the entire method channel). Fixes flutter/flutter#78426 Fixes flutter/flutter#78856 --- .../CHANGELOG.md | 5 ++ .../method_channel_google_maps_flutter.dart | 22 +++--- .../pubspec.yaml | 2 +- ...thod_channel_google_maps_flutter_test.dart | 72 +++++++++++++++++++ .../google_maps_flutter_platform_test.dart | 21 ------ 5 files changed, 92 insertions(+), 30 deletions(-) create mode 100644 packages/google_maps_flutter/google_maps_flutter_platform_interface/test/method_channel/method_channel_google_maps_flutter_test.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md index e8b12f79220d..1a620834b564 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.0.3 + +* Fix type issues in `isMarkerInfoWindowShown` and `getZoomLevel` introduced + in the null safety migration. + ## 2.0.2 * Mark constructors for CameraUpdate, CircleId, MapsObjectId, MarkerId, PolygonId, PolylineId and TileOverlayId as const diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart index 80a71b4edd2b..49029cc3d22d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart @@ -62,8 +62,9 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { // Keep a collection of mapId to a map of TileOverlays. final Map> _tileOverlays = {}; - @override - Future init(int mapId) { + /// Returns the channel for [mapId], creating it if it doesn't already exist. + @visibleForTesting + MethodChannel ensureChannelInitialized(int mapId) { MethodChannel? channel = _channels[mapId]; if (channel == null) { channel = MethodChannel('plugins.flutter.io/google_maps_$mapId'); @@ -71,6 +72,12 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { (MethodCall call) => _handleMethodCall(call, mapId)); _channels[mapId] = channel; } + return channel; + } + + @override + Future init(int mapId) { + MethodChannel channel = ensureChannelInitialized(mapId); return channel.invokeMethod('map#waitForMap'); } @@ -414,18 +421,17 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { Future isMarkerInfoWindowShown( MarkerId markerId, { required int mapId, - }) { + }) async { assert(markerId != null); - return channel(mapId).invokeMethod('markers#isInfoWindowShown', - {'markerId': markerId.value}) as Future; + return (await channel(mapId).invokeMethod('markers#isInfoWindowShown', + {'markerId': markerId.value}))!; } @override Future getZoomLevel({ required int mapId, - }) { - return channel(mapId).invokeMethod('map#getZoomLevel') - as Future; + }) async { + return (await channel(mapId).invokeMethod('map#getZoomLevel'))!; } @override diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml index 9d419351e85f..628099139021 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the google_maps_flutter plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.2 +version: 2.0.3 dependencies: flutter: diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/method_channel/method_channel_google_maps_flutter_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/method_channel/method_channel_google_maps_flutter_test.dart new file mode 100644 index 000000000000..19e81c960839 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/method_channel/method_channel_google_maps_flutter_test.dart @@ -0,0 +1,72 @@ +// Copyright 2013 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/services.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:google_maps_flutter_platform_interface/src/method_channel/method_channel_google_maps_flutter.dart'; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('$MethodChannelGoogleMapsFlutter', () { + late List log; + + setUp(() async { + log = []; + }); + + /// Initializes a map with the given ID and canned responses, logging all + /// calls to [log]. + void configureMockMap( + MethodChannelGoogleMapsFlutter maps, { + required int mapId, + required Future? Function(MethodCall call) handler, + }) { + maps + .ensureChannelInitialized(mapId) + .setMockMethodCallHandler((MethodCall methodCall) { + log.add(methodCall.method); + return handler(methodCall); + }); + } + + // Calls each method that uses invokeMethod with a return type other than + // void to ensure that the casting/nullability handling succeeds. + // + // TODO(stuartmorgan): Remove this once there is real test coverage of + // each method, since that would cover this issue. + test('non-void invokeMethods handle types correctly', () async { + const int mapId = 0; + final MethodChannelGoogleMapsFlutter maps = + MethodChannelGoogleMapsFlutter(); + configureMockMap(maps, mapId: mapId, + handler: (MethodCall methodCall) async { + switch (methodCall.method) { + case 'map#getLatLng': + return [1.0, 2.0]; + case 'markers#isInfoWindowShown': + return true; + case 'map#getZoomLevel': + return 2.5; + case 'map#takeSnapshot': + return null; + } + }); + + await maps.getLatLng(ScreenCoordinate(x: 0, y: 0), mapId: mapId); + await maps.isMarkerInfoWindowShown(MarkerId(''), mapId: mapId); + await maps.getZoomLevel(mapId: mapId); + await maps.takeSnapshot(mapId: mapId); + // Check that all the invokeMethod calls happened. + expect(log, [ + 'map#getLatLng', + 'markers#isInfoWindowShown', + 'map#getZoomLevel', + 'map#takeSnapshot', + ]); + }); + }); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart index 73cea10ec2d9..2c50313ab8a6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/platform_interface/google_maps_flutter_platform_test.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'package:mockito/mockito.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; @@ -36,26 +35,6 @@ void main() { GoogleMapsFlutterPlatform.instance = ExtendsGoogleMapsFlutterPlatform(); }); }); - - group('$MethodChannelGoogleMapsFlutter', () { - const MethodChannel channel = - MethodChannel('plugins.flutter.io/google_maps_flutter'); - final List log = []; - channel.setMockMethodCallHandler((MethodCall methodCall) async { - log.add(methodCall); - }); - - tearDown(() { - log.clear(); - }); - - test('foo', () async { - expect( - log, - [], - ); - }); - }); } class GoogleMapsFlutterPlatformMock extends Mock From 809d0de989d3f8fddc5f08b2593758841da4d0b6 Mon Sep 17 00:00:00 2001 From: Harpreet Sangar Date: Thu, 25 Mar 2021 18:47:47 +0000 Subject: [PATCH 0305/1565] Update "eponymous concept" link. (#3305) Fixes an obsolete link. --- packages/quick_actions/quick_actions/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/quick_actions/quick_actions/README.md b/packages/quick_actions/quick_actions/README.md index 4573523a5e36..46e87fa0b241 100644 --- a/packages/quick_actions/quick_actions/README.md +++ b/packages/quick_actions/quick_actions/README.md @@ -4,7 +4,7 @@ This Flutter plugin allows you to manage and interact with the application's home screen quick actions. Quick actions refer to the [eponymous -concept](https://developer.apple.com/ios/human-interface-guidelines/extensions/home-screen-actions) +concept](https://developer.apple.com/design/human-interface-guidelines/ios/system-capabilities/home-screen-actions/) on iOS and to the [App Shortcuts](https://developer.android.com/guide/topics/ui/shortcuts.html) APIs on Android (introduced in Android 7.1 / API level 25). It is safe to run this plugin From 7c87a8c52ce228305835e20413e69620da85ac71 Mon Sep 17 00:00:00 2001 From: PiN73 Date: Thu, 25 Mar 2021 22:36:56 +0300 Subject: [PATCH 0306/1565] [video_player] add http headers (#3671) This enables to pass HTTP headers to VideoPlayerController.network. Fixes: flutter/flutter#16466 --- .../video_player/video_player/CHANGELOG.md | 4 ++ .../flutter/plugins/videoplayer/Messages.java | 15 ++++- .../plugins/videoplayer/VideoPlayer.java | 7 ++- .../videoplayer/VideoPlayerPlugin.java | 5 ++ .../ios/Classes/FLTVideoPlayerPlugin.m | 20 +++++-- .../video_player/ios/Classes/messages.h | 3 +- .../video_player/ios/Classes/messages.m | 50 +++++++++------- .../video_player/lib/video_player.dart | 20 ++++++- .../video_player/pigeons/messages.dart | 1 + .../video_player/video_player/pubspec.yaml | 4 +- .../video_player/test/video_player_test.dart | 59 ++++++++++++++++--- 11 files changed, 144 insertions(+), 44 deletions(-) diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index 08a5e443149e..6b20fd964dec 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.0 + +* Add `httpHeaders` option to `VideoPlayerController.network` + ## 2.0.2 * Fix `VideoPlayerValue` size and aspect ratio documentation diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java index f1a909534d58..e0a4a3b8dd08 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/Messages.java @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v0.1.19), do not edit directly. +// Autogenerated from Pigeon (v0.1.21), do not edit directly. // See also: https://pub.dev/packages/pigeon package io.flutter.plugins.videoplayer; @@ -87,12 +87,23 @@ public void setFormatHint(String setterArg) { this.formatHint = setterArg; } + private HashMap httpHeaders; + + public HashMap getHttpHeaders() { + return httpHeaders; + } + + public void setHttpHeaders(HashMap setterArg) { + this.httpHeaders = setterArg; + } + HashMap toMap() { HashMap toMapResult = new HashMap<>(); toMapResult.put("asset", asset); toMapResult.put("uri", uri); toMapResult.put("packageName", packageName); toMapResult.put("formatHint", formatHint); + toMapResult.put("httpHeaders", httpHeaders); return toMapResult; } @@ -106,6 +117,8 @@ static CreateMessage fromMap(HashMap map) { fromMapResult.packageName = (String) packageName; Object formatHint = map.get("formatHint"); fromMapResult.formatHint = (String) formatHint; + Object httpHeaders = map.get("httpHeaders"); + fromMapResult.httpHeaders = (HashMap) httpHeaders; return fromMapResult; } } diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java index 840b1464b4d4..87784eebdefe 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java @@ -65,6 +65,7 @@ final class VideoPlayer { TextureRegistry.SurfaceTextureEntry textureEntry, String dataSource, String formatHint, + Map httpHeaders, VideoPlayerOptions options) { this.eventChannel = eventChannel; this.textureEntry = textureEntry; @@ -76,13 +77,17 @@ final class VideoPlayer { DataSource.Factory dataSourceFactory; if (isHTTP(uri)) { - dataSourceFactory = + DefaultHttpDataSourceFactory httpDataSourceFactory = new DefaultHttpDataSourceFactory( "ExoPlayer", null, DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS, DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS, true); + if (httpHeaders != null && !httpHeaders.isEmpty()) { + httpDataSourceFactory.getDefaultRequestProperties().set(httpHeaders); + } + dataSourceFactory = httpDataSourceFactory; } else { dataSourceFactory = new DefaultDataSourceFactory(context, "ExoPlayer"); } diff --git a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java index 2895db2acd6a..d77b45e03d4b 100644 --- a/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java +++ b/packages/video_player/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java @@ -23,6 +23,7 @@ import io.flutter.view.TextureRegistry; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; +import java.util.Map; import javax.net.ssl.HttpsURLConnection; /** Android platform implementation of the VideoPlayerPlugin. */ @@ -138,8 +139,11 @@ public TextureMessage create(CreateMessage arg) { handle, "asset:///" + assetLookupKey, null, + null, options); } else { + @SuppressWarnings("unchecked") + Map httpHeaders = arg.getHttpHeaders(); player = new VideoPlayer( flutterState.applicationContext, @@ -147,6 +151,7 @@ public TextureMessage create(CreateMessage arg) { handle, arg.getUri(), arg.getFormatHint(), + httpHeaders, options); } videoPlayers.put(handle.id(), player); diff --git a/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m b/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m index 83144a9cb378..b359c1b6c898 100644 --- a/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m +++ b/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m @@ -46,7 +46,9 @@ @interface FLTVideoPlayer : NSObject @property(nonatomic, readonly) bool isPlaying; @property(nonatomic) bool isLooping; @property(nonatomic, readonly) bool isInitialized; -- (instancetype)initWithURL:(NSURL*)url frameUpdater:(FLTFrameUpdater*)frameUpdater; +- (instancetype)initWithURL:(NSURL*)url + frameUpdater:(FLTFrameUpdater*)frameUpdater + httpHeaders:(NSDictionary*)headers; - (void)play; - (void)pause; - (void)setIsLooping:(bool)isLooping; @@ -62,7 +64,7 @@ - (void)updatePlayingState; @implementation FLTVideoPlayer - (instancetype)initWithAsset:(NSString*)asset frameUpdater:(FLTFrameUpdater*)frameUpdater { NSString* path = [[NSBundle mainBundle] pathForResource:asset ofType:nil]; - return [self initWithURL:[NSURL fileURLWithPath:path] frameUpdater:frameUpdater]; + return [self initWithURL:[NSURL fileURLWithPath:path] frameUpdater:frameUpdater httpHeaders:nil]; } - (void)addObservers:(AVPlayerItem*)item { @@ -162,8 +164,15 @@ - (void)createVideoOutputAndDisplayLink:(FLTFrameUpdater*)frameUpdater { _displayLink.paused = YES; } -- (instancetype)initWithURL:(NSURL*)url frameUpdater:(FLTFrameUpdater*)frameUpdater { - AVPlayerItem* item = [AVPlayerItem playerItemWithURL:url]; +- (instancetype)initWithURL:(NSURL*)url + frameUpdater:(FLTFrameUpdater*)frameUpdater + httpHeaders:(NSDictionary*)headers { + NSDictionary* options = nil; + if (headers != nil && [headers count] != 0) { + options = @{@"AVURLAssetHTTPHeaderFieldsKey" : headers}; + } + AVURLAsset* urlAsset = [AVURLAsset URLAssetWithURL:url options:options]; + AVPlayerItem* item = [AVPlayerItem playerItemWithAsset:urlAsset]; return [self initWithPlayerItem:item frameUpdater:frameUpdater]; } @@ -522,7 +531,8 @@ - (FLTTextureMessage*)create:(FLTCreateMessage*)input error:(FlutterError**)erro return [self onPlayerSetup:player frameUpdater:frameUpdater]; } else if (input.uri) { player = [[FLTVideoPlayer alloc] initWithURL:[NSURL URLWithString:input.uri] - frameUpdater:frameUpdater]; + frameUpdater:frameUpdater + httpHeaders:input.httpHeaders]; return [self onPlayerSetup:player frameUpdater:frameUpdater]; } else { *error = [FlutterError errorWithCode:@"video_player" message:@"not implemented" details:nil]; diff --git a/packages/video_player/video_player/ios/Classes/messages.h b/packages/video_player/video_player/ios/Classes/messages.h index 9717f65b23c3..e21e7860ba09 100644 --- a/packages/video_player/video_player/ios/Classes/messages.h +++ b/packages/video_player/video_player/ios/Classes/messages.h @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v0.1.19), do not edit directly. +// Autogenerated from Pigeon (v0.1.21), do not edit directly. // See also: https://pub.dev/packages/pigeon #import @protocol FlutterBinaryMessenger; @@ -28,6 +28,7 @@ NS_ASSUME_NONNULL_BEGIN @property(nonatomic, copy, nullable) NSString *uri; @property(nonatomic, copy, nullable) NSString *packageName; @property(nonatomic, copy, nullable) NSString *formatHint; +@property(nonatomic, strong, nullable) NSDictionary *httpHeaders; @end @interface FLTLoopingMessage : NSObject diff --git a/packages/video_player/video_player/ios/Classes/messages.m b/packages/video_player/video_player/ios/Classes/messages.m index 0993c947c2cb..14e375b33378 100644 --- a/packages/video_player/video_player/ios/Classes/messages.m +++ b/packages/video_player/video_player/ios/Classes/messages.m @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v0.1.19), do not edit directly. +// Autogenerated from Pigeon (v0.1.21), do not edit directly. // See also: https://pub.dev/packages/pigeon #import "messages.h" #import @@ -11,18 +11,19 @@ #error File requires ARC to be enabled. #endif -#ifndef __clang_analyzer__ -static NSDictionary *wrapResult(NSDictionary *result, FlutterError *error) { +static NSDictionary *wrapResult(NSDictionary *result, FlutterError *error) { NSDictionary *errorDict = (NSDictionary *)[NSNull null]; if (error) { - errorDict = [NSDictionary - dictionaryWithObjectsAndKeys:(error.code ? error.code : [NSNull null]), @"code", - (error.message ? error.message : [NSNull null]), @"message", - (error.details ? error.details : [NSNull null]), @"details", - nil]; + errorDict = @{ + @"code" : (error.code ? error.code : [NSNull null]), + @"message" : (error.message ? error.message : [NSNull null]), + @"details" : (error.details ? error.details : [NSNull null]), + }; } - return [NSDictionary dictionaryWithObjectsAndKeys:(result ? result : [NSNull null]), @"result", - errorDict, @"error", nil]; + return @{ + @"result" : (result ? result : [NSNull null]), + @"error" : errorDict, + }; } @interface FLTTextureMessage () @@ -89,6 +90,10 @@ + (FLTCreateMessage *)fromMap:(NSDictionary *)dict { if ((NSNull *)result.formatHint == [NSNull null]) { result.formatHint = nil; } + result.httpHeaders = dict[@"httpHeaders"]; + if ((NSNull *)result.httpHeaders == [NSNull null]) { + result.httpHeaders = nil; + } return result; } - (NSDictionary *)toMap { @@ -98,7 +103,9 @@ - (NSDictionary *)toMap { (self.packageName ? self.packageName : [NSNull null]), @"packageName", (self.formatHint ? self.formatHint : [NSNull null]), - @"formatHint", nil]; + @"formatHint", + (self.httpHeaders ? self.httpHeaders : [NSNull null]), + @"httpHeaders", nil]; } @end @@ -221,8 +228,8 @@ void FLTVideoPlayerApiSetup(id binaryMessenger, id binaryMessenger, id binaryMessenger, id binaryMessenger, id binaryMessenger, id binaryMessenger, id binaryMessenger, id binaryMessenger, id binaryMessenger, id binaryMessenger, id binaryMessenger, id { {this.package, this.closedCaptionFile, this.videoPlayerOptions}) : dataSourceType = DataSourceType.asset, formatHint = null, + httpHeaders = const {}, super(VideoPlayerValue(duration: Duration.zero)); /// Constructs a [VideoPlayerController] playing a video from obtained from @@ -196,9 +197,15 @@ class VideoPlayerController extends ValueNotifier { /// null. /// **Android only**: The [formatHint] option allows the caller to override /// the video format detection code. - VideoPlayerController.network(this.dataSource, - {this.formatHint, this.closedCaptionFile, this.videoPlayerOptions}) - : dataSourceType = DataSourceType.network, + /// [httpHeaders] option allows to specify HTTP headers + /// for the request to the [dataSource]. + VideoPlayerController.network( + this.dataSource, { + this.formatHint, + this.closedCaptionFile, + this.videoPlayerOptions, + this.httpHeaders = const {}, + }) : dataSourceType = DataSourceType.network, package = null, super(VideoPlayerValue(duration: Duration.zero)); @@ -212,12 +219,18 @@ class VideoPlayerController extends ValueNotifier { dataSourceType = DataSourceType.file, package = null, formatHint = null, + httpHeaders = const {}, super(VideoPlayerValue(duration: Duration.zero)); /// The URI to the video file. This will be in different formats depending on /// the [DataSourceType] of the original video. final String dataSource; + /// HTTP headers used for the request to the [dataSource]. + /// Only for [VideoPlayerController.network]. + /// Always empty for other video types. + final Map httpHeaders; + /// **Android only**. Will override the platform's generic file format /// detection with whatever is set here. final VideoFormat? formatHint; @@ -276,6 +289,7 @@ class VideoPlayerController extends ValueNotifier { sourceType: DataSourceType.network, uri: dataSource, formatHint: formatHint, + httpHeaders: httpHeaders, ); break; case DataSourceType.file: diff --git a/packages/video_player/video_player/pigeons/messages.dart b/packages/video_player/video_player/pigeons/messages.dart index c0a76dd301af..e893aaa6830d 100644 --- a/packages/video_player/video_player/pigeons/messages.dart +++ b/packages/video_player/video_player/pigeons/messages.dart @@ -35,6 +35,7 @@ class CreateMessage { String uri; String packageName; String formatHint; + Map httpHeaders; } class MixWithOthersMessage { diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index 17442d7ec09a..0215ead855e7 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -1,7 +1,7 @@ name: video_player description: Flutter plugin for displaying inline video with other Flutter widgets on Android, iOS, and web. -version: 2.0.2 +version: 2.1.0 homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player flutter: @@ -17,7 +17,7 @@ flutter: dependencies: meta: ^1.3.0 - video_player_platform_interface: ^4.0.0 + video_player_platform_interface: ^4.1.0 # The design on https://flutter.dev/go/federated-plugins was to leave # this constraint as "any". We cannot do it right now as it fails pub publish diff --git a/packages/video_player/video_player/test/video_player_test.dart b/packages/video_player/video_player/test/video_player_test.dart index 580c9ad914dd..e17dac7897a6 100644 --- a/packages/video_player/video_player/test/video_player_test.dart +++ b/packages/video_player/video_player/test/video_player_test.dart @@ -30,6 +30,9 @@ class FakeController extends ValueNotifier @override String get dataSource => ''; + @override + Map get httpHeaders => {}; + @override DataSourceType get dataSourceType => DataSourceType.file; @@ -200,22 +203,60 @@ void main() { ); await controller.initialize(); - expect(fakeVideoPlayerPlatform.dataSourceDescriptions[0].uri, - 'https://127.0.0.1'); expect( - fakeVideoPlayerPlatform.dataSourceDescriptions[0].formatHint, null); + fakeVideoPlayerPlatform.dataSourceDescriptions[0].uri, + 'https://127.0.0.1', + ); + expect( + fakeVideoPlayerPlatform.dataSourceDescriptions[0].formatHint, + null, + ); + expect( + fakeVideoPlayerPlatform.dataSourceDescriptions[0].httpHeaders, + {}, + ); }); test('network with hint', () async { final VideoPlayerController controller = VideoPlayerController.network( - 'https://127.0.0.1', - formatHint: VideoFormat.dash); + 'https://127.0.0.1', + formatHint: VideoFormat.dash, + ); await controller.initialize(); - expect(fakeVideoPlayerPlatform.dataSourceDescriptions[0].uri, - 'https://127.0.0.1'); - expect(fakeVideoPlayerPlatform.dataSourceDescriptions[0].formatHint, - 'dash'); + expect( + fakeVideoPlayerPlatform.dataSourceDescriptions[0].uri, + 'https://127.0.0.1', + ); + expect( + fakeVideoPlayerPlatform.dataSourceDescriptions[0].formatHint, + 'dash', + ); + expect( + fakeVideoPlayerPlatform.dataSourceDescriptions[0].httpHeaders, + {}, + ); + }); + + test('network with some headers', () async { + final VideoPlayerController controller = VideoPlayerController.network( + 'https://127.0.0.1', + httpHeaders: {'Authorization': 'Bearer token'}, + ); + await controller.initialize(); + + expect( + fakeVideoPlayerPlatform.dataSourceDescriptions[0].uri, + 'https://127.0.0.1', + ); + expect( + fakeVideoPlayerPlatform.dataSourceDescriptions[0].formatHint, + null, + ); + expect( + fakeVideoPlayerPlatform.dataSourceDescriptions[0].httpHeaders, + {'Authorization': 'Bearer token'}, + ); }); test('init errors', () async { From 4cd43e946d325722e88c17784170e4842d2de0e4 Mon Sep 17 00:00:00 2001 From: Alexander Aprelev Date: Thu, 25 Mar 2021 16:31:07 -0700 Subject: [PATCH 0307/1565] [ci] Drop redundant question marks used with dynamic. (#3756) Fixes https://github.com/flutter/flutter/issues/79089 --- .../google_sign_in_web/lib/src/generated/gapi.dart | 10 +++++----- .../in_app_purchase/in_app_purchase_connection.dart | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart index a7ee1cdd3314..1e2db0fe4609 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapi.dart @@ -19,11 +19,11 @@ import 'package:js/js.dart'; // Module gapi typedef void LoadCallback( - [dynamic? args1, - dynamic? args2, - dynamic? args3, - dynamic? args4, - dynamic? args5]); + [dynamic args1, + dynamic args2, + dynamic args3, + dynamic args4, + dynamic args5]); @anonymous @JS() diff --git a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart index a5db8e5d4206..c333478e3064 100644 --- a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart +++ b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/in_app_purchase_connection.dart @@ -304,5 +304,5 @@ class IAPError { final String message; /// Error details, possibly null. - final dynamic? details; + final dynamic details; } From 1ecc550155e9d0f7ce3feba28ae5ad4a375c0e17 Mon Sep 17 00:00:00 2001 From: Gary Qian Date: Thu, 25 Mar 2021 16:47:14 -0700 Subject: [PATCH 0308/1565] [ci] Drop extra ? for dynamic (#3757) --- .../google_sign_in_web/lib/src/generated/gapiauth2.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart index 0dec17dbd19c..d5efc71d469a 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/src/generated/gapiauth2.dart @@ -68,7 +68,7 @@ class GoogleAuth { /// Attaches the sign-in flow to the specified container's click handler. external dynamic attachClickHandler( - dynamic? container, + dynamic container, SigninOptions options, dynamic onsuccess(GoogleUser googleUser), dynamic onfailure(String reason)); From 5787b354bb14d40a8f83b90a2f39b7d7e3951aa4 Mon Sep 17 00:00:00 2001 From: Rene Floor Date: Fri, 26 Mar 2021 17:09:03 +0100 Subject: [PATCH 0309/1565] [in_app_purchase] moved android iap unit tests (#3732) --- .../in_app_purchase/android/build.gradle | 5 ++++ .../src/test/java/android/text/TextUtils.java | 11 ++++++++ .../src/test/java/android/util/Log.java | 27 +++++++++++++++++++ .../InAppPurchasePluginTest.java | 0 .../inapppurchase/MethodCallHandlerTest.java | 0 .../plugins/inapppurchase/TranslatorTest.java | 0 6 files changed, 43 insertions(+) create mode 100644 packages/in_app_purchase/in_app_purchase/android/src/test/java/android/text/TextUtils.java create mode 100644 packages/in_app_purchase/in_app_purchase/android/src/test/java/android/util/Log.java rename packages/in_app_purchase/in_app_purchase/{example/android/app => android}/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java (100%) rename packages/in_app_purchase/in_app_purchase/{example/android/app => android}/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java (100%) rename packages/in_app_purchase/in_app_purchase/{example/android/app => android}/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java (100%) diff --git a/packages/in_app_purchase/in_app_purchase/android/build.gradle b/packages/in_app_purchase/in_app_purchase/android/build.gradle index 8d5840b4daff..a36f70137129 100644 --- a/packages/in_app_purchase/in_app_purchase/android/build.gradle +++ b/packages/in_app_purchase/in_app_purchase/android/build.gradle @@ -31,12 +31,17 @@ android { lintOptions { disable 'InvalidPackage' } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } dependencies { implementation 'androidx.annotation:annotation:1.0.0' implementation 'com.android.billingclient:billing:3.0.2' testImplementation 'junit:junit:4.12' + testImplementation 'org.json:json:20180813' testImplementation 'org.mockito:mockito-core:3.6.0' androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' diff --git a/packages/in_app_purchase/in_app_purchase/android/src/test/java/android/text/TextUtils.java b/packages/in_app_purchase/in_app_purchase/android/src/test/java/android/text/TextUtils.java new file mode 100644 index 000000000000..d997ae1dcaa0 --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase/android/src/test/java/android/text/TextUtils.java @@ -0,0 +1,11 @@ +// Copyright 2013 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. + +package android.text; + +public class TextUtils { + public static boolean isEmpty(CharSequence str) { + return str == null || str.length() == 0; + } +} diff --git a/packages/in_app_purchase/in_app_purchase/android/src/test/java/android/util/Log.java b/packages/in_app_purchase/in_app_purchase/android/src/test/java/android/util/Log.java new file mode 100644 index 000000000000..310b9ad89cdf --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase/android/src/test/java/android/util/Log.java @@ -0,0 +1,27 @@ +// Copyright 2013 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. + +package android.util; + +public class Log { + public static int d(String tag, String msg) { + System.out.println("DEBUG: " + tag + ": " + msg); + return 0; + } + + public static int i(String tag, String msg) { + System.out.println("INFO: " + tag + ": " + msg); + return 0; + } + + public static int w(String tag, String msg) { + System.out.println("WARN: " + tag + ": " + msg); + return 0; + } + + public static int e(String tag, String msg) { + System.out.println("ERROR: " + tag + ": " + msg); + return 0; + } +} diff --git a/packages/in_app_purchase/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java b/packages/in_app_purchase/in_app_purchase/android/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java similarity index 100% rename from packages/in_app_purchase/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java rename to packages/in_app_purchase/in_app_purchase/android/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java diff --git a/packages/in_app_purchase/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java b/packages/in_app_purchase/in_app_purchase/android/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java similarity index 100% rename from packages/in_app_purchase/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java rename to packages/in_app_purchase/in_app_purchase/android/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java diff --git a/packages/in_app_purchase/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java b/packages/in_app_purchase/in_app_purchase/android/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java similarity index 100% rename from packages/in_app_purchase/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java rename to packages/in_app_purchase/in_app_purchase/android/src/test/java/io/flutter/plugins/inapppurchase/TranslatorTest.java From e4064a31300967bd60fb4373b592229d2f91d838 Mon Sep 17 00:00:00 2001 From: ColonisationCaptain <52425971+ColonisationCaptain@users.noreply.github.com> Date: Mon, 29 Mar 2021 17:49:06 +0100 Subject: [PATCH 0310/1565] capitalise Platform class (#3762) --- packages/android_intent/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/android_intent/README.md b/packages/android_intent/README.md index 7d097e465926..a2f95abe2bae 100644 --- a/packages/android_intent/README.md +++ b/packages/android_intent/README.md @@ -9,7 +9,7 @@ Use it by specifying action, category, data and extra arguments for the intent. It does not support returning the result of the launched activity. Sample usage: ```dart -if (platform.isAndroid) { +if (Platform.isAndroid) { AndroidIntent intent = AndroidIntent( action: 'action_view', data: 'https://play.google.com/store/apps/details?' @@ -33,7 +33,7 @@ for it in the plugin and use an action constant to refer to it. For instance: `'action_application_details_settings'` translates to `android.settings.ACTION_APPLICATION_DETAILS_SETTINGS` ```dart -if (platform.isAndroid) { +if (Platform.isAndroid) { final AndroidIntent intent = AndroidIntent( action: 'action_application_details_settings', data: 'package:com.example.app', // replace com.example.app with your applicationId From ed290be50fb79d9389538cdfa3249223c00c2757 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Mon, 29 Mar 2021 07:27:40 -1000 Subject: [PATCH 0311/1565] Add tests for publish check tool command (#3760) --- .../tool/lib/src/publish_check_command.dart | 4 +- .../tool/test/publish_check_command_test.dart | 114 ++++++++++++++++++ 2 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 script/tool/test/publish_check_command_test.dart diff --git a/script/tool/lib/src/publish_check_command.dart b/script/tool/lib/src/publish_check_command.dart index dcd28d9a89f3..fb57dfcd6dc9 100644 --- a/script/tool/lib/src/publish_check_command.dart +++ b/script/tool/lib/src/publish_check_command.dart @@ -65,10 +65,10 @@ class PublishCheckCommand extends PluginCommand { } Future hasValidPublishCheckRun(Directory package) async { - final io.Process process = await io.Process.start( + final io.Process process = await processRunner.start( 'flutter', ['pub', 'publish', '--', '--dry-run'], - workingDirectory: package.path, + workingDirectory: package, ); final StringBuffer outputBuffer = StringBuffer(); diff --git a/script/tool/test/publish_check_command_test.dart b/script/tool/test/publish_check_command_test.dart new file mode 100644 index 000000000000..dbe6e2cfe548 --- /dev/null +++ b/script/tool/test/publish_check_command_test.dart @@ -0,0 +1,114 @@ +// Copyright 2013 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:collection'; +import 'dart:io' as io; + +import 'package:args/command_runner.dart'; +import 'package:file/file.dart'; +import 'package:flutter_plugin_tools/src/common.dart'; +import 'package:flutter_plugin_tools/src/publish_check_command.dart'; +import 'package:test/test.dart'; + +import 'mocks.dart'; +import 'util.dart'; + +void main() { + group('$PublishCheckProcessRunner tests', () { + PublishCheckProcessRunner processRunner; + CommandRunner runner; + + setUp(() { + initializeFakePackages(); + processRunner = PublishCheckProcessRunner(); + final PublishCheckCommand publishCheckCommand = PublishCheckCommand( + mockPackagesDir, mockFileSystem, + processRunner: processRunner); + + runner = CommandRunner( + 'publish_check_command', + 'Test for publish-check command.', + ); + runner.addCommand(publishCheckCommand); + }); + + tearDown(() { + mockPackagesDir.deleteSync(recursive: true); + }); + + test('publish check all packages', () async { + final Directory plugin1Dir = await createFakePlugin('a'); + final Directory plugin2Dir = await createFakePlugin('b'); + + processRunner.processesToReturn.add( + MockProcess()..exitCodeCompleter.complete(0), + ); + processRunner.processesToReturn.add( + MockProcess()..exitCodeCompleter.complete(0), + ); + await runner.run(['publish-check']); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall('flutter', + ['pub', 'publish', '--', '--dry-run'], plugin1Dir.path), + ProcessCall('flutter', + ['pub', 'publish', '--', '--dry-run'], plugin2Dir.path), + ])); + }); + + test('fail on negative test', () async { + await createFakePlugin('a'); + + final MockProcess process = MockProcess(); + process.stdoutController.close(); // ignore: unawaited_futures + process.stderrController.close(); // ignore: unawaited_futures + process.exitCodeCompleter.complete(1); + + processRunner.processesToReturn.add(process); + + expect( + () => runner.run(['publish-check']), + throwsA(isA()), + ); + }); + + test('fail on bad pubspec', () async { + final Directory dir = await createFakePlugin('c'); + await dir.childFile('pubspec.yaml').writeAsString('bad-yaml'); + + final MockProcess process = MockProcess(); + processRunner.processesToReturn.add(process); + + expect(() => runner.run(['publish-check']), + throwsA(isA())); + }); + + test('pass on prerelease', () async { + await createFakePlugin('d'); + + final String preReleaseOutput = 'Package has 1 warning.' + 'Packages with an SDK constraint on a pre-release of the Dart SDK should themselves be published as a pre-release version.'; + + final MockProcess process = MockProcess(); + process.stdoutController.add(preReleaseOutput.codeUnits); + process.stdoutController.close(); // ignore: unawaited_futures + process.stderrController.close(); // ignore: unawaited_futures + + process.exitCodeCompleter.complete(1); + + processRunner.processesToReturn.add(process); + + expect(runner.run(['publish-check']), completes); + }); + }); +} + +class PublishCheckProcessRunner extends RecordingProcessRunner { + final Queue processesToReturn = Queue(); + + @override + io.Process get processToReturn => processesToReturn.removeFirst(); +} From c631fa190b5865d7263c93adfa3706c4f0a0a6e9 Mon Sep 17 00:00:00 2001 From: xster Date: Mon, 29 Mar 2021 22:03:36 -0700 Subject: [PATCH 0312/1565] Make sure androidx.lifecycle classes aren't R8'ed away when using flutter_plugin_android_lifecycle (#3746) --- packages/flutter_plugin_android_lifecycle/CHANGELOG.md | 4 ++++ .../android/build.gradle | 1 + .../android/proguard.txt | 9 +++++++++ packages/flutter_plugin_android_lifecycle/pubspec.yaml | 2 +- 4 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 packages/flutter_plugin_android_lifecycle/android/proguard.txt diff --git a/packages/flutter_plugin_android_lifecycle/CHANGELOG.md b/packages/flutter_plugin_android_lifecycle/CHANGELOG.md index 08f137c09434..1c7f23b96f69 100644 --- a/packages/flutter_plugin_android_lifecycle/CHANGELOG.md +++ b/packages/flutter_plugin_android_lifecycle/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 +* Make sure androidx.lifecycle.DefaultLifecycleObservable doesn't get shrunk + away. + ## 2.0.0 * Bump Dart SDK for null-safety compatibility. diff --git a/packages/flutter_plugin_android_lifecycle/android/build.gradle b/packages/flutter_plugin_android_lifecycle/android/build.gradle index ac042bf144ab..9a26d574ac2e 100644 --- a/packages/flutter_plugin_android_lifecycle/android/build.gradle +++ b/packages/flutter_plugin_android_lifecycle/android/build.gradle @@ -27,6 +27,7 @@ android { defaultConfig { minSdkVersion 16 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles 'proguard.txt' } lintOptions { disable 'InvalidPackage' diff --git a/packages/flutter_plugin_android_lifecycle/android/proguard.txt b/packages/flutter_plugin_android_lifecycle/android/proguard.txt new file mode 100644 index 000000000000..d3a6df0eefd2 --- /dev/null +++ b/packages/flutter_plugin_android_lifecycle/android/proguard.txt @@ -0,0 +1,9 @@ +# The point of this package is to specify that a dependent plugin intends to +# use the AndroidX lifecycle classes. Make sure no R8 heuristics shrink classes +# brought in by the embedding's pom. +# +# This isn't strictly needed since by definition, plugins using Android +# lifecycles should implement DefaultLifecycleObserver and therefore keep it +# from being shrunk. But there seems to be an R8 bug so this needs to stay +# https://issuetracker.google.com/issues/142778206. +-keep class androidx.lifecycle.DefaultLifecycleObserver diff --git a/packages/flutter_plugin_android_lifecycle/pubspec.yaml b/packages/flutter_plugin_android_lifecycle/pubspec.yaml index fc2805ef814b..62169e4389fc 100644 --- a/packages/flutter_plugin_android_lifecycle/pubspec.yaml +++ b/packages/flutter_plugin_android_lifecycle/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_plugin_android_lifecycle description: Flutter plugin for accessing an Android Lifecycle within other plugins. -version: 2.0.0 +version: 2.0.1 homepage: https://github.com/flutter/plugins/tree/master/packages/flutter_plugin_android_lifecycle environment: From e0e9be0e499dc6a0dcbda1d7d9b19a82310d86ee Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Tue, 30 Mar 2021 13:34:20 -0700 Subject: [PATCH 0313/1565] Update build-all test for null-safe template (#3773) Flutter master now creates NNBD code when running 'flutter create', so the generated pubspec for build_all needs to use a compatible SDK version. This updates from 2.0.0 to 2.12.0. Also includes a test for this, which involved setting up tests for the file, and doing some refactoring to make the command testable. As a result, this fixes https://github.com/flutter/flutter/issues/61049 (although more test backfill is needed). --- script/build_all_plugins_app.sh | 8 +- .../src/create_all_plugins_app_command.dart | 53 ++++++----- .../create_all_plugins_app_command_test.dart | 91 +++++++++++++++++++ script/tool/test/util.dart | 15 ++- 4 files changed, 138 insertions(+), 29 deletions(-) create mode 100644 script/tool/test/create_all_plugins_app_command_test.dart diff --git a/script/build_all_plugins_app.sh b/script/build_all_plugins_app.sh index ab15a7d64249..56b05853fdcb 100755 --- a/script/build_all_plugins_app.sh +++ b/script/build_all_plugins_app.sh @@ -39,6 +39,12 @@ echo "Excluding the following plugins: $ALL_EXCLUDED" (cd "$REPO_DIR" && plugin_tools all-plugins-app --exclude $ALL_EXCLUDED) +# Master now creates null-safe app code by default; migrate stable so both +# branches are building in the same mode. +if [[ "${CHANNEL}" == "stable" ]]; then + (cd $REPO_DIR/all_plugins && dart migrate --apply-changes) +fi + function error() { echo "$@" 1>&2 } @@ -53,7 +59,7 @@ fi for version in "${BUILD_MODES[@]}"; do echo "Building $version..." - (cd $REPO_DIR/all_plugins && flutter build $@ --$version) + (cd $REPO_DIR/all_plugins && flutter build $@ --$version --no-sound-null-safety) if [ $? -eq 0 ]; then echo "Successfully built $version all_plugins app." diff --git a/script/tool/lib/src/create_all_plugins_app_command.dart b/script/tool/lib/src/create_all_plugins_app_command.dart index f1f11d15ca95..aaa7f7fb9667 100644 --- a/script/tool/lib/src/create_all_plugins_app_command.dart +++ b/script/tool/lib/src/create_all_plugins_app_command.dart @@ -12,11 +12,21 @@ import 'package:pubspec_parse/pubspec_parse.dart'; import 'common.dart'; -// TODO(cyanglaz): Add tests for this command. -// https://github.com/flutter/flutter/issues/61049 class CreateAllPluginsAppCommand extends PluginCommand { - CreateAllPluginsAppCommand(Directory packagesDir, FileSystem fileSystem) - : super(packagesDir, fileSystem); + CreateAllPluginsAppCommand( + Directory packagesDir, + FileSystem fileSystem, { + this.pluginsRoot, + }) : super(packagesDir, fileSystem) { + pluginsRoot ??= fileSystem.currentDirectory; + appDirectory = pluginsRoot.childDirectory('all_plugins'); + } + + /// The root directory of the plugin repository. + Directory pluginsRoot; + + /// The location of the synthesized app project. + Directory appDirectory; @override String get description => @@ -27,7 +37,7 @@ class CreateAllPluginsAppCommand extends PluginCommand { @override Future run() async { - final int exitCode = await _createPlugin(); + final int exitCode = await _createApp(); if (exitCode != 0) { throw ToolExit(exitCode); } @@ -39,7 +49,7 @@ class CreateAllPluginsAppCommand extends PluginCommand { ]); } - Future _createPlugin() async { + Future _createApp() async { final io.ProcessResult result = io.Process.runSync( 'flutter', [ @@ -47,7 +57,7 @@ class CreateAllPluginsAppCommand extends PluginCommand { '--template=app', '--project-name=all_plugins', '--android-language=java', - './all_plugins', + appDirectory.path, ], ); @@ -57,12 +67,10 @@ class CreateAllPluginsAppCommand extends PluginCommand { } Future _updateAppGradle() async { - final File gradleFile = fileSystem.file(p.join( - 'all_plugins', - 'android', - 'app', - 'build.gradle', - )); + final File gradleFile = appDirectory + .childDirectory('android') + .childDirectory('app') + .childFile('build.gradle'); if (!gradleFile.existsSync()) { throw ToolExit(64); } @@ -86,14 +94,12 @@ class CreateAllPluginsAppCommand extends PluginCommand { } Future _updateManifest() async { - final File manifestFile = fileSystem.file(p.join( - 'all_plugins', - 'android', - 'app', - 'src', - 'main', - 'AndroidManifest.xml', - )); + final File manifestFile = appDirectory + .childDirectory('android') + .childDirectory('app') + .childDirectory('src') + .childDirectory('main') + .childFile('AndroidManifest.xml'); if (!manifestFile.existsSync()) { throw ToolExit(64); } @@ -124,7 +130,7 @@ class CreateAllPluginsAppCommand extends PluginCommand { version: Version.parse('1.0.0+1'), environment: { 'sdk': VersionConstraint.compatibleWith( - Version.parse('2.0.0'), + Version.parse('2.12.0'), ), }, dependencies: { @@ -135,8 +141,7 @@ class CreateAllPluginsAppCommand extends PluginCommand { }, dependencyOverrides: pluginDeps, ); - final File pubspecFile = - fileSystem.file(p.join('all_plugins', 'pubspec.yaml')); + final File pubspecFile = appDirectory.childFile('pubspec.yaml'); pubspecFile.writeAsStringSync(_pubspecToString(pubspec)); } diff --git a/script/tool/test/create_all_plugins_app_command_test.dart b/script/tool/test/create_all_plugins_app_command_test.dart new file mode 100644 index 000000000000..58f24c9a3de1 --- /dev/null +++ b/script/tool/test/create_all_plugins_app_command_test.dart @@ -0,0 +1,91 @@ +// Copyright 2013 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:args/command_runner.dart'; +import 'package:file/file.dart'; +import 'package:file/local.dart'; +import 'package:flutter_plugin_tools/src/create_all_plugins_app_command.dart'; +import 'package:test/test.dart'; + +import 'util.dart'; + +void main() { + group('$CreateAllPluginsAppCommand', () { + CommandRunner runner; + FileSystem fileSystem; + Directory testRoot; + Directory packagesDir; + Directory appDir; + + setUp(() { + // Since the core of this command is a call to 'flutter create', the test + // has to use the real filesystem. Put everything possible in a unique + // temporary to minimize affect on the host system. + fileSystem = LocalFileSystem(); + testRoot = fileSystem.systemTempDirectory.createTempSync(); + packagesDir = testRoot.childDirectory('packages'); + + final CreateAllPluginsAppCommand command = CreateAllPluginsAppCommand( + packagesDir, + fileSystem, + pluginsRoot: testRoot, + ); + appDir = command.appDirectory; + runner = CommandRunner( + 'create_all_test', 'Test for $CreateAllPluginsAppCommand'); + runner.addCommand(command); + }); + + tearDown(() { + testRoot.deleteSync(recursive: true); + }); + + test('pubspec includes all plugins', () async { + createFakePlugin('plugina', packagesDirectory: packagesDir); + createFakePlugin('pluginb', packagesDirectory: packagesDir); + createFakePlugin('pluginc', packagesDirectory: packagesDir); + + await runner.run(['all-plugins-app']); + final List pubspec = + appDir.childFile('pubspec.yaml').readAsLinesSync(); + + expect( + pubspec, + containsAll([ + contains(RegExp('path: .*/packages/plugina')), + contains(RegExp('path: .*/packages/pluginb')), + contains(RegExp('path: .*/packages/pluginc')), + ])); + }); + + test('pubspec has overrides for all plugins', () async { + createFakePlugin('plugina', packagesDirectory: packagesDir); + createFakePlugin('pluginb', packagesDirectory: packagesDir); + createFakePlugin('pluginc', packagesDirectory: packagesDir); + + await runner.run(['all-plugins-app']); + final List pubspec = + appDir.childFile('pubspec.yaml').readAsLinesSync(); + + expect( + pubspec, + containsAllInOrder([ + contains('dependency_overrides:'), + contains(RegExp('path: .*/packages/plugina')), + contains(RegExp('path: .*/packages/pluginb')), + contains(RegExp('path: .*/packages/pluginc')), + ])); + }); + + test('pubspec is compatible with null-safe app code', () async { + createFakePlugin('plugina', packagesDirectory: packagesDir); + + await runner.run(['all-plugins-app']); + final String pubspec = + appDir.childFile('pubspec.yaml').readAsStringSync(); + + expect(pubspec, contains(RegExp('sdk:\\s*(?:["\']>=|[^])2\\.12\\.'))); + }); + }); +} diff --git a/script/tool/test/util.dart b/script/tool/test/util.dart index 908b67b3cf75..d02b756ee9c6 100644 --- a/script/tool/test/util.dart +++ b/script/tool/test/util.dart @@ -12,6 +12,9 @@ import 'package:platform/platform.dart'; import 'package:flutter_plugin_tools/src/common.dart'; import 'package:quiver/collection.dart'; +// TODO(stuartmorgan): Eliminate this in favor of setting up a clean filesystem +// for each test, to eliminate the chance of files from one test interfering +// with another test. FileSystem mockFileSystem = MemoryFileSystem( style: LocalPlatform().isWindows ? FileSystemStyle.windows @@ -28,7 +31,8 @@ void initializeFakePackages({Directory parentDir}) { mockPackagesDir.createSync(); } -/// Creates a plugin package with the given [name] in [mockPackagesDir]. +/// Creates a plugin package with the given [name] in [packagesDirectory], +/// defaulting to [mockPackagesDir]. Directory createFakePlugin( String name, { bool withSingleExample = false, @@ -44,13 +48,16 @@ Directory createFakePlugin( bool includeChangeLog = false, bool includeVersion = false, String parentDirectoryName = '', + Directory packagesDirectory, }) { assert(!(withSingleExample && withExamples.isNotEmpty), 'cannot pass withSingleExample and withExamples simultaneously'); - final Directory pluginDirectory = (parentDirectoryName != '') - ? mockPackagesDir.childDirectory(parentDirectoryName).childDirectory(name) - : mockPackagesDir.childDirectory(name); + Directory parentDirectory = packagesDirectory ?? mockPackagesDir; + if (parentDirectoryName != '') { + parentDirectory = parentDirectory.childDirectory(parentDirectoryName); + } + final Directory pluginDirectory = parentDirectory.childDirectory(name); pluginDirectory.createSync(recursive: true); createFakePubspec( From ef641f77f40998602e3326a66b2bab9d1e9a82fd Mon Sep 17 00:00:00 2001 From: xster Date: Tue, 30 Mar 2021 13:36:18 -0700 Subject: [PATCH 0314/1565] Update flutter_plugin_android_lifecycle dependency versions (#3767) --- .../google_maps_flutter/google_maps_flutter/CHANGELOG.md | 5 +++++ .../google_maps_flutter/example/pubspec.yaml | 2 +- .../google_maps_flutter/google_maps_flutter/pubspec.yaml | 4 ++-- packages/image_picker/image_picker/CHANGELOG.md | 5 +++++ packages/image_picker/image_picker/example/pubspec.yaml | 2 +- packages/image_picker/image_picker/pubspec.yaml | 4 ++-- packages/local_auth/CHANGELOG.md | 5 +++++ packages/local_auth/pubspec.yaml | 4 ++-- 8 files changed, 23 insertions(+), 8 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index eb16024575bb..141a096aee94 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.0.2 + +* Update flutter_plugin_android_lifecycle dependency to 2.0.1 to fix an R8 issue + on some versions. + ## 2.0.1 * Update platform_plugin_interface version requirement. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml index 5d553eaa3c99..eb06e09a8757 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml @@ -17,7 +17,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - flutter_plugin_android_lifecycle: ^2.0.0-nullsafety.2 + flutter_plugin_android_lifecycle: ^2.0.1 dev_dependencies: flutter_driver: diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index d30c9d030de6..5e73586e07e4 100644 --- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml @@ -1,12 +1,12 @@ name: google_maps_flutter description: A Flutter plugin for integrating Google Maps in iOS and Android applications. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter -version: 2.0.1 +version: 2.0.2 dependencies: flutter: sdk: flutter - flutter_plugin_android_lifecycle: ^2.0.0 + flutter_plugin_android_lifecycle: ^2.0.1 google_maps_flutter_platform_interface: ^2.0.0 dev_dependencies: diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md index fc3d5c156a17..6af3cb090ca6 100644 --- a/packages/image_picker/image_picker/CHANGELOG.md +++ b/packages/image_picker/image_picker/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.7.4 + +* Update flutter_plugin_android_lifecycle dependency to 2.0.1 to fix an R8 issue + on some versions. + ## 0.7.3 * Endorse image_picker_for_web diff --git a/packages/image_picker/image_picker/example/pubspec.yaml b/packages/image_picker/image_picker/example/pubspec.yaml index 68b70b909162..b2e5b6399f47 100755 --- a/packages/image_picker/image_picker/example/pubspec.yaml +++ b/packages/image_picker/image_picker/example/pubspec.yaml @@ -6,7 +6,7 @@ dependencies: video_player: ^2.0.0-nullsafety.7 flutter: sdk: flutter - flutter_plugin_android_lifecycle: ^2.0.0 + flutter_plugin_android_lifecycle: ^2.0.1 image_picker: # When depending on this package from a real application you should use: # image_picker: ^x.y.z diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index 0018e87ab437..73c6a6ed1824 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker description: Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker -version: 0.7.3 +version: 0.7.4 flutter: plugin: @@ -18,7 +18,7 @@ flutter: dependencies: flutter: sdk: flutter - flutter_plugin_android_lifecycle: ^2.0.0 + flutter_plugin_android_lifecycle: ^2.0.1 image_picker_platform_interface: ^2.0.0 image_picker_for_web: ^2.0.0 diff --git a/packages/local_auth/CHANGELOG.md b/packages/local_auth/CHANGELOG.md index b4d58395295f..258144cd0daa 100644 --- a/packages/local_auth/CHANGELOG.md +++ b/packages/local_auth/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.1.1 + +* Update flutter_plugin_android_lifecycle dependency to 2.0.1 to fix an R8 issue + on some versions. + ## 1.1.0 * Migrate to null safety. diff --git a/packages/local_auth/pubspec.yaml b/packages/local_auth/pubspec.yaml index a63027728d86..76722c00a147 100644 --- a/packages/local_auth/pubspec.yaml +++ b/packages/local_auth/pubspec.yaml @@ -2,7 +2,7 @@ name: local_auth description: Flutter plugin for Android and iOS devices to allow local authentication via fingerprint, touch ID, face ID, passcode, pin, or pattern. homepage: https://github.com/flutter/plugins/tree/master/packages/local_auth -version: 1.1.0 +version: 1.1.1 flutter: plugin: @@ -19,7 +19,7 @@ dependencies: meta: ^1.3.0 intl: ^0.17.0 platform: ^3.0.0 - flutter_plugin_android_lifecycle: ^2.0.0 + flutter_plugin_android_lifecycle: ^2.0.1 dev_dependencies: integration_test: From 860adb44e38502f2986f30718c3522a36877d0ec Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Tue, 30 Mar 2021 16:48:41 -0700 Subject: [PATCH 0315/1565] [google_maps_flutter] Fix TileOverlay cloning (#3771) TileOverlay was not copying its TileProvider. During the NNBD migration, map object updates were refactored to share code, and in that refactoring TileOverlay update construction was aligned with other map objects to use clones, so certain operations involving TileOverlays started dropping the TileProvider. Fixes https://github.com/flutter/flutter/issues/77500 --- .../CHANGELOG.md | 5 ++ .../lib/src/types/tile_overlay.dart | 7 ++- .../pubspec.yaml | 2 +- .../test/types/tile_overlay_test.dart | 51 +++++++++++++++---- 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md index 1a620834b564..b6603d66fa89 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.0.4 + +* Preserve the `TileProvider` when copying `TileOverlay`, fixing a + regression with tile overlays introduced in the null safety migration. + ## 2.0.3 * Fix type issues in `isMarkerInfoWindowShown` and `getZoomLevel` introduced diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart index 55dca55f9d8e..8cdd2c4699e1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/tile_overlay.dart @@ -92,6 +92,7 @@ class TileOverlay implements MapsObject { /// unless overwritten by the specified parameters. TileOverlay copyWith({ bool? fadeInParam, + TileProvider? tileProviderParam, double? transparencyParam, int? zIndexParam, bool? visibleParam, @@ -100,6 +101,7 @@ class TileOverlay implements MapsObject { return TileOverlay( tileOverlayId: tileOverlayId, fadeIn: fadeInParam ?? fadeIn, + tileProvider: tileProviderParam ?? tileProvider, transparency: transparencyParam ?? transparency, zIndex: zIndexParam ?? zIndex, visible: visibleParam ?? visible, @@ -137,6 +139,7 @@ class TileOverlay implements MapsObject { return other is TileOverlay && tileOverlayId == other.tileOverlayId && fadeIn == other.fadeIn && + tileProvider == other.tileProvider && transparency == other.transparency && zIndex == other.zIndex && visible == other.visible && @@ -144,6 +147,6 @@ class TileOverlay implements MapsObject { } @override - int get hashCode => hashValues( - tileOverlayId, fadeIn, transparency, zIndex, visible, tileSize); + int get hashCode => hashValues(tileOverlayId, fadeIn, tileProvider, + transparency, zIndex, visible, tileSize); } diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml index 628099139021..4bce4aa8a5a1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the google_maps_flutter plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.3 +version: 2.0.4 dependencies: flutter: diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart index a17f86d4f19a..3a4c34764ef7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/tile_overlay_test.dart @@ -7,6 +7,13 @@ import 'dart:ui' show hashValues; import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; +class _TestTileProvider extends TileProvider { + @override + Future getTile(int x, int y, int? zoom) async { + return Tile(0, 0, null); + } +} + void main() { TestWidgetsFlutterBinding.ensureInitialized(); @@ -58,40 +65,65 @@ void main() { }); test('equality', () async { - const TileOverlay tileOverlay1 = TileOverlay( + final TileProvider tileProvider = _TestTileProvider(); + final TileOverlay tileOverlay1 = TileOverlay( tileOverlayId: TileOverlayId('id1'), fadeIn: false, - tileProvider: null, + tileProvider: tileProvider, transparency: 0.1, zIndex: 1, visible: false, tileSize: 128); - const TileOverlay tileOverlay2 = TileOverlay( + final TileOverlay tileOverlaySameValues = TileOverlay( tileOverlayId: TileOverlayId('id1'), fadeIn: false, - tileProvider: null, + tileProvider: tileProvider, transparency: 0.1, zIndex: 1, visible: false, tileSize: 128); - const TileOverlay tileOverlay3 = TileOverlay( + final TileOverlay tileOverlayDifferentId = TileOverlay( tileOverlayId: TileOverlayId('id2'), fadeIn: false, + tileProvider: tileProvider, + transparency: 0.1, + zIndex: 1, + visible: false, + tileSize: 128); + final TileOverlay tileOverlayDifferentProvider = TileOverlay( + tileOverlayId: TileOverlayId('id1'), + fadeIn: false, tileProvider: null, transparency: 0.1, zIndex: 1, visible: false, tileSize: 128); - expect(tileOverlay1, tileOverlay2); - expect(tileOverlay1, isNot(tileOverlay3)); + expect(tileOverlay1, tileOverlaySameValues); + expect(tileOverlay1, isNot(tileOverlayDifferentId)); + expect(tileOverlay1, isNot(tileOverlayDifferentProvider)); + }); + + test('clone', () async { + final TileProvider tileProvider = _TestTileProvider(); + // Set non-default values for every parameter. + final TileOverlay tileOverlay = TileOverlay( + tileOverlayId: TileOverlayId('id1'), + fadeIn: false, + tileProvider: tileProvider, + transparency: 0.1, + zIndex: 1, + visible: false, + tileSize: 128); + expect(tileOverlay, tileOverlay.clone()); }); test('hashCode', () async { + final TileProvider tileProvider = _TestTileProvider(); const TileOverlayId id = TileOverlayId('id1'); - const TileOverlay tileOverlay = TileOverlay( + final TileOverlay tileOverlay = TileOverlay( tileOverlayId: id, fadeIn: false, - tileProvider: null, + tileProvider: tileProvider, transparency: 0.1, zIndex: 1, visible: false, @@ -101,6 +133,7 @@ void main() { hashValues( tileOverlay.tileOverlayId, tileOverlay.fadeIn, + tileOverlay.tileProvider, tileOverlay.transparency, tileOverlay.zIndex, tileOverlay.visible, From 0db60bbfc156d3c71d098a81848540c2215b5746 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Tue, 30 Mar 2021 17:38:16 -0700 Subject: [PATCH 0316/1565] let google_maps_flutter_web version solve for older mockito (#3769) --- .../google_maps_flutter_web/example/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml index 9f942d654caa..28955016ab40 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: dev_dependencies: google_maps: ^3.4.4 http: ^0.13.0 - mockito: ^4.1.4 # Update to ^5.0.0 as soon as this migrates to null-safety + mockito: ^4.1.1+1 # Update to ^5.0.0 as soon as this migrates to null-safety flutter_driver: sdk: flutter flutter_test: From febc3e36e8acc8920bbea9658b891bdc82b53db3 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Wed, 31 Mar 2021 12:44:47 -0700 Subject: [PATCH 0317/1565] [path_provider] Switch to new analysis options (#3755) Removes the override to use the legacy analysis, and fixes all resulting issues. Part of flutter/flutter#76229 --- packages/path_provider/analysis_options.yaml | 1 - .../integration_test/path_provider_test.dart | 8 ++- .../path_provider/example/lib/main.dart | 20 +++---- .../example/test_driver/integration_test.dart | 3 +- .../path_provider/lib/path_provider.dart | 4 +- .../test/path_provider_test.dart | 41 +++++++++----- .../path_provider_linux/example/lib/main.dart | 8 +-- .../example/test/widget_test.dart | 12 ++--- .../example/test_driver/integration_test.dart | 3 +- .../lib/path_provider_linux.dart | 17 +++--- .../test/path_provider_linux_test.dart | 2 +- .../path_provider_macos/example/lib/main.dart | 4 +- .../example/test_driver/integration_test.dart | 3 +- .../lib/path_provider_platform_interface.dart | 4 +- .../lib/src/method_channel_path_provider.dart | 16 ++++-- .../method_channel_path_provider_test.dart | 2 +- .../example/lib/main.dart | 4 +- .../example/test_driver/integration_test.dart | 3 +- .../lib/src/folders.dart | 3 ++ .../lib/src/path_provider_windows_real.dart | 53 +++++++++---------- .../lib/src/path_provider_windows_stub.dart | 4 +- .../test/path_provider_windows_test.dart | 39 +++++++------- script/incremental_build.sh | 1 - 23 files changed, 132 insertions(+), 123 deletions(-) delete mode 100644 packages/path_provider/analysis_options.yaml diff --git a/packages/path_provider/analysis_options.yaml b/packages/path_provider/analysis_options.yaml deleted file mode 100644 index cda4f6e153e6..000000000000 --- a/packages/path_provider/analysis_options.yaml +++ /dev/null @@ -1 +0,0 @@ -include: ../../analysis_options_legacy.yaml diff --git a/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart b/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart index 2613b45a8574..f1e7c0aef59b 100644 --- a/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart +++ b/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart @@ -4,8 +4,6 @@ // @dart=2.9 -import 'dart:async'; - import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:path_provider/path_provider.dart'; @@ -55,7 +53,7 @@ void main() { expect(result, throwsA(isInstanceOf())); } else if (Platform.isAndroid) { final List directories = await getExternalCacheDirectories(); - for (Directory result in directories) { + for (final Directory result in directories) { _verifySampleFile(result, 'externalCache'); } } @@ -72,7 +70,7 @@ void main() { StorageDirectory.movies, ]; - for (StorageDirectory type in _allDirs) { + for (final StorageDirectory type in _allDirs) { test('getExternalStorageDirectories (type: $type)', () async { if (Platform.isIOS) { final Future> result = @@ -81,7 +79,7 @@ void main() { } else if (Platform.isAndroid) { final List directories = await getExternalStorageDirectories(type: type); - for (Directory result in directories) { + for (final Directory result in directories) { _verifySampleFile(result, '$type'); } } diff --git a/packages/path_provider/path_provider/example/lib/main.dart b/packages/path_provider/path_provider/example/lib/main.dart index 7b1d6a73a2f5..c0ac126b2a00 100644 --- a/packages/path_provider/path_provider/example/lib/main.dart +++ b/packages/path_provider/path_provider/example/lib/main.dart @@ -4,7 +4,6 @@ // ignore_for_file: public_member_api_docs -import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; @@ -22,13 +21,13 @@ class MyApp extends StatelessWidget { theme: ThemeData( primarySwatch: Colors.blue, ), - home: MyHomePage(title: 'Path Provider'), + home: const MyHomePage(title: 'Path Provider'), ); } } class MyHomePage extends StatefulWidget { - MyHomePage({Key? key, required this.title}) : super(key: key); + const MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @override @@ -166,8 +165,9 @@ class _MyHomePageState extends State { Padding( padding: const EdgeInsets.all(16.0), child: ElevatedButton( - child: Text( - '${Platform.isIOS ? "External directories are unavailable " "on iOS" : "Get External Storage Directory"}'), + child: Text(Platform.isIOS + ? 'External directories are unavailable on iOS' + : 'Get External Storage Directory'), onPressed: Platform.isIOS ? null : _requestExternalStorageDirectory, ), @@ -178,8 +178,9 @@ class _MyHomePageState extends State { Padding( padding: const EdgeInsets.all(16.0), child: ElevatedButton( - child: Text( - '${Platform.isIOS ? "External directories are unavailable " "on iOS" : "Get External Storage Directories"}'), + child: Text(Platform.isIOS + ? 'External directories are unavailable on iOS' + : 'Get External Storage Directories'), onPressed: Platform.isIOS ? null : () { @@ -197,8 +198,9 @@ class _MyHomePageState extends State { Padding( padding: const EdgeInsets.all(16.0), child: ElevatedButton( - child: Text( - '${Platform.isIOS ? "External directories are unavailable " "on iOS" : "Get External Cache Directories"}'), + child: Text(Platform.isIOS + ? 'External directories are unavailable on iOS' + : 'Get External Cache Directories'), onPressed: Platform.isIOS ? null : _requestExternalCacheDirectories, ), diff --git a/packages/path_provider/path_provider/example/test_driver/integration_test.dart b/packages/path_provider/path_provider/example/test_driver/integration_test.dart index 18ed3cff3ee8..24a0ee720b2a 100644 --- a/packages/path_provider/path_provider/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider/example/test_driver/integration_test.dart @@ -4,7 +4,6 @@ // @dart=2.9 -import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; @@ -14,6 +13,6 @@ Future main() async { final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - final Map result = jsonDecode(data); + final Map result = jsonDecode(data) as Map; exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/path_provider/path_provider/lib/path_provider.dart b/packages/path_provider/path_provider/lib/path_provider.dart index d63887a60267..a51aefe8e29f 100644 --- a/packages/path_provider/path_provider/lib/path_provider.dart +++ b/packages/path_provider/path_provider/lib/path_provider.dart @@ -2,13 +2,13 @@ // 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' show Directory, Platform; import 'package:flutter/foundation.dart' show kIsWeb, visibleForTesting; import 'package:path_provider_linux/path_provider_linux.dart'; import 'package:path_provider_windows/path_provider_windows.dart'; import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; +// ignore: implementation_imports import 'package:path_provider_platform_interface/src/method_channel_path_provider.dart'; export 'package:path_provider_platform_interface/path_provider_platform_interface.dart' @@ -36,7 +36,7 @@ class MissingPlatformDirectoryException implements Exception { @override String toString() { - String detailsAddition = details == null ? '' : ': $details'; + final String detailsAddition = details == null ? '' : ': $details'; return 'MissingPlatformDirectoryException($message)$detailsAddition'; } } diff --git a/packages/path_provider/path_provider/test/path_provider_test.dart b/packages/path_provider/path_provider/test/path_provider_test.dart index 7232a74a1253..218861606209 100644 --- a/packages/path_provider/path_provider/test/path_provider_test.dart +++ b/packages/path_provider/path_provider/test/path_provider_test.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'dart:io' show Directory; -import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; import 'package:path_provider/path_provider.dart'; @@ -27,44 +26,44 @@ void main() { }); test('getTemporaryDirectory', () async { - Directory result = await getTemporaryDirectory(); + final Directory result = await getTemporaryDirectory(); expect(result.path, kTemporaryPath); }); test('getApplicationSupportDirectory', () async { - Directory result = await getApplicationSupportDirectory(); + final Directory result = await getApplicationSupportDirectory(); expect(result.path, kApplicationSupportPath); }); test('getLibraryDirectory', () async { - Directory result = await getLibraryDirectory(); + final Directory result = await getLibraryDirectory(); expect(result.path, kLibraryPath); }); test('getApplicationDocumentsDirectory', () async { - Directory result = await getApplicationDocumentsDirectory(); + final Directory result = await getApplicationDocumentsDirectory(); expect(result.path, kApplicationDocumentsPath); }); test('getExternalStorageDirectory', () async { - Directory? result = await getExternalStorageDirectory(); + final Directory? result = await getExternalStorageDirectory(); expect(result?.path, kExternalStoragePath); }); test('getExternalCacheDirectories', () async { - List? result = await getExternalCacheDirectories(); + final List? result = await getExternalCacheDirectories(); expect(result?.length, 1); expect(result?.first.path, kExternalCachePath); }); test('getExternalStorageDirectories', () async { - List? result = await getExternalStorageDirectories(); + final List? result = await getExternalStorageDirectories(); expect(result?.length, 1); expect(result?.first.path, kExternalStoragePath); }); test('getDownloadsDirectory', () async { - Directory? result = await getDownloadsDirectory(); + final Directory? result = await getDownloadsDirectory(); expect(result?.path, kDownloadsPath); }); }); @@ -95,22 +94,22 @@ void main() { }); test('getExternalStorageDirectory passes null through', () async { - Directory? result = await getExternalStorageDirectory(); + final Directory? result = await getExternalStorageDirectory(); expect(result, isNull); }); test('getExternalCacheDirectories passes null through', () async { - List? result = await getExternalCacheDirectories(); + final List? result = await getExternalCacheDirectories(); expect(result, isNull); }); test('getExternalStorageDirectories passes null through', () async { - List? result = await getExternalStorageDirectories(); + final List? result = await getExternalStorageDirectories(); expect(result, isNull); }); test('getDownloadsDirectory passses null through', () async { - Directory? result = await getDownloadsDirectory(); + final Directory? result = await getDownloadsDirectory(); expect(result, isNull); }); }); @@ -119,36 +118,44 @@ void main() { class FakePathProviderPlatform extends Fake with MockPlatformInterfaceMixin implements PathProviderPlatform { + @override Future getTemporaryPath() async { return kTemporaryPath; } + @override Future getApplicationSupportPath() async { return kApplicationSupportPath; } + @override Future getLibraryPath() async { return kLibraryPath; } + @override Future getApplicationDocumentsPath() async { return kApplicationDocumentsPath; } + @override Future getExternalStoragePath() async { return kExternalStoragePath; } + @override Future?> getExternalCachePaths() async { return [kExternalCachePath]; } + @override Future?> getExternalStoragePaths({ StorageDirectory? type, }) async { return [kExternalStoragePath]; } + @override Future getDownloadsPath() async { return kDownloadsPath; } @@ -157,36 +164,44 @@ class FakePathProviderPlatform extends Fake class AllNullFakePathProviderPlatform extends Fake with MockPlatformInterfaceMixin implements PathProviderPlatform { + @override Future getTemporaryPath() async { return null; } + @override Future getApplicationSupportPath() async { return null; } + @override Future getLibraryPath() async { return null; } + @override Future getApplicationDocumentsPath() async { return null; } + @override Future getExternalStoragePath() async { return null; } + @override Future?> getExternalCachePaths() async { return null; } + @override Future?> getExternalStoragePaths({ StorageDirectory? type, }) async { return null; } + @override Future getDownloadsPath() async { return null; } diff --git a/packages/path_provider/path_provider_linux/example/lib/main.dart b/packages/path_provider/path_provider_linux/example/lib/main.dart index 104c998bc61a..d365e6bdeab4 100644 --- a/packages/path_provider/path_provider_linux/example/lib/main.dart +++ b/packages/path_provider/path_provider_linux/example/lib/main.dart @@ -3,8 +3,6 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import 'dart:async'; - import 'package:flutter/services.dart'; import 'package:path_provider_linux/path_provider_linux.dart'; @@ -67,7 +65,9 @@ class _MyAppState extends State { // If the widget was removed from the tree while the asynchronous platform // message was in flight, we want to discard the reply rather than calling // setState to update our non-existent appearance. - if (!mounted) return; + if (!mounted) { + return; + } setState(() { _tempDirectory = tempDirectory; @@ -86,7 +86,7 @@ class _MyAppState extends State { ), body: Center( child: Column( - children: [ + children: [ Text('Temp Directory: $_tempDirectory\n'), Text('Documents Directory: $_documentsDirectory\n'), Text('Downloads Directory: $_downloadsDirectory\n'), diff --git a/packages/path_provider/path_provider_linux/example/test/widget_test.dart b/packages/path_provider/path_provider_linux/example/test/widget_test.dart index 4d5da3e4e330..59f839d431fa 100644 --- a/packages/path_provider/path_provider_linux/example/test/widget_test.dart +++ b/packages/path_provider/path_provider_linux/example/test/widget_test.dart @@ -9,8 +9,6 @@ // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. -import 'dart:async'; - import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -19,14 +17,14 @@ import 'package:pathproviderexample/main.dart'; void main() { group('Test linux path provider example', () { setUpAll(() async { - await WidgetsFlutterBinding.ensureInitialized(); + WidgetsFlutterBinding.ensureInitialized(); }); testWidgets('Finds tmp directory', (WidgetTester tester) async { // Build our app and trigger a frame. await tester.runAsync(() async { await tester.pumpWidget(MyApp()); - await Future.delayed(Duration(milliseconds: 20)); + await Future.delayed(const Duration(milliseconds: 20)); await tester.pump(); // Verify that temporary directory is retrieved. @@ -44,7 +42,7 @@ void main() { // Build our app and trigger a frame. await tester.runAsync(() async { await tester.pumpWidget(MyApp()); - await Future.delayed(Duration(milliseconds: 20)); + await Future.delayed(const Duration(milliseconds: 20)); await tester.pump(); // Verify that documents directory is retrieved. @@ -62,7 +60,7 @@ void main() { // Build our app and trigger a frame. await tester.runAsync(() async { await tester.pumpWidget(MyApp()); - await Future.delayed(Duration(milliseconds: 20)); + await Future.delayed(const Duration(milliseconds: 20)); await tester.pump(); // Verify that downloads directory is retrieved. @@ -81,7 +79,7 @@ void main() { // Build our app and trigger a frame. await tester.runAsync(() async { await tester.pumpWidget(MyApp()); - await Future.delayed(Duration(milliseconds: 20)); + await Future.delayed(const Duration(milliseconds: 20)); await tester.pump(); // Verify that Application Support Directory is retrieved. diff --git a/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart b/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart index 18ed3cff3ee8..24a0ee720b2a 100644 --- a/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider_linux/example/test_driver/integration_test.dart @@ -4,7 +4,6 @@ // @dart=2.9 -import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; @@ -14,6 +13,6 @@ Future main() async { final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - final Map result = jsonDecode(data); + final Map result = jsonDecode(data) as Map; exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart b/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart index cf8d12436429..5a81114cc92d 100644 --- a/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart +++ b/packages/path_provider/path_provider_linux/lib/path_provider_linux.dart @@ -1,12 +1,12 @@ // Copyright 2013 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:io'; -import 'dart:async'; -import 'package:xdg_directories/xdg_directories.dart' as xdg; import 'package:path/path.dart' as path; import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; +import 'package:xdg_directories/xdg_directories.dart' as xdg; /// The linux implementation of [PathProviderPlatform] /// @@ -19,16 +19,17 @@ class PathProviderLinux extends PathProviderPlatform { @override Future getTemporaryPath() { - return Future.value("/tmp"); + return Future.value('/tmp'); } @override Future getApplicationSupportPath() async { - final processName = path.basenameWithoutExtension( + final String processName = path.basenameWithoutExtension( await File('/proc/self/exe').resolveSymbolicLinks()); - final directory = Directory(path.join(xdg.dataHome.path, processName)); + final Directory directory = + Directory(path.join(xdg.dataHome.path, processName)); // Creating the directory if it doesn't exist, because mobile implementations assume the directory exists - if (!await directory.exists()) { + if (!directory.existsSync()) { await directory.create(recursive: true); } return directory.path; @@ -36,11 +37,11 @@ class PathProviderLinux extends PathProviderPlatform { @override Future getApplicationDocumentsPath() { - return Future.value(xdg.getUserDirectory('DOCUMENTS')?.path); + return Future.value(xdg.getUserDirectory('DOCUMENTS')?.path); } @override Future getDownloadsPath() { - return Future.value(xdg.getUserDirectory('DOWNLOAD')?.path); + return Future.value(xdg.getUserDirectory('DOWNLOAD')?.path); } } diff --git a/packages/path_provider/path_provider_linux/test/path_provider_linux_test.dart b/packages/path_provider/path_provider_linux/test/path_provider_linux_test.dart index 81329fb7c3cb..9ab75ff477de 100644 --- a/packages/path_provider/path_provider_linux/test/path_provider_linux_test.dart +++ b/packages/path_provider/path_provider_linux/test/path_provider_linux_test.dart @@ -14,7 +14,7 @@ void main() { tearDown(() {}); test('getTemporaryPath', () async { - final plugin = PathProviderPlatform.instance; + final PathProviderPlatform plugin = PathProviderPlatform.instance; expect(await plugin.getTemporaryPath(), '/tmp'); }); } diff --git a/packages/path_provider/path_provider_macos/example/lib/main.dart b/packages/path_provider/path_provider_macos/example/lib/main.dart index 19ba86e31cf5..67a0eb32eeda 100644 --- a/packages/path_provider/path_provider_macos/example/lib/main.dart +++ b/packages/path_provider/path_provider_macos/example/lib/main.dart @@ -4,8 +4,6 @@ // ignore_for_file: public_member_api_docs -import 'dart:async'; - import 'package:flutter/material.dart'; import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; @@ -79,7 +77,7 @@ class _MyAppState extends State { ), body: Center( child: Column( - children: [ + children: [ Text('Temp Directory: $_tempDirectory\n'), Text('Documents Directory: $_documentsDirectory\n'), Text('Downloads Directory: $_downloadsDirectory\n'), diff --git a/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart b/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart index 18ed3cff3ee8..24a0ee720b2a 100644 --- a/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider_macos/example/test_driver/integration_test.dart @@ -4,7 +4,6 @@ // @dart=2.9 -import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; @@ -14,6 +13,6 @@ Future main() async { final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - final Map result = jsonDecode(data); + final Map result = jsonDecode(data) as Map; exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart b/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart index 3eb1580711ef..99e600d05263 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart @@ -2,13 +2,11 @@ // 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:plugin_platform_interface/plugin_platform_interface.dart'; import 'src/enums.dart'; import 'src/method_channel_path_provider.dart'; -import 'package:plugin_platform_interface/plugin_platform_interface.dart'; - export 'src/enums.dart'; /// The interface that implementations of path_provider must implement. diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart index 7889e004126f..007787444adb 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart @@ -2,21 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:async'; - -import 'enums.dart'; - import 'package:flutter/services.dart'; import 'package:meta/meta.dart'; import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; import 'package:platform/platform.dart'; +import 'enums.dart'; + /// An implementation of [PathProviderPlatform] that uses method channels. class MethodChannelPathProvider extends PathProviderPlatform { /// The method channel used to interact with the native platform. @visibleForTesting MethodChannel methodChannel = - MethodChannel('plugins.flutter.io/path_provider'); + const MethodChannel('plugins.flutter.io/path_provider'); // Ideally, this property shouldn't exist, and each platform should // just implement the supported methods. Once all the platforms are @@ -30,14 +28,17 @@ class MethodChannelPathProvider extends PathProviderPlatform { _platform = platform; } + @override Future getTemporaryPath() { return methodChannel.invokeMethod('getTemporaryDirectory'); } + @override Future getApplicationSupportPath() { return methodChannel.invokeMethod('getApplicationSupportDirectory'); } + @override Future getLibraryPath() { if (!_platform.isIOS && !_platform.isMacOS) { throw UnsupportedError('Functionality only available on iOS/macOS'); @@ -45,11 +46,13 @@ class MethodChannelPathProvider extends PathProviderPlatform { return methodChannel.invokeMethod('getLibraryDirectory'); } + @override Future getApplicationDocumentsPath() { return methodChannel .invokeMethod('getApplicationDocumentsDirectory'); } + @override Future getExternalStoragePath() { if (!_platform.isAndroid) { throw UnsupportedError('Functionality only available on Android'); @@ -57,6 +60,7 @@ class MethodChannelPathProvider extends PathProviderPlatform { return methodChannel.invokeMethod('getStorageDirectory'); } + @override Future?> getExternalCachePaths() { if (!_platform.isAndroid) { throw UnsupportedError('Functionality only available on Android'); @@ -65,6 +69,7 @@ class MethodChannelPathProvider extends PathProviderPlatform { .invokeListMethod('getExternalCacheDirectories'); } + @override Future?> getExternalStoragePaths({ StorageDirectory? type, }) async { @@ -77,6 +82,7 @@ class MethodChannelPathProvider extends PathProviderPlatform { ); } + @override Future getDownloadsPath() { if (!_platform.isMacOS) { throw UnsupportedError('Functionality only available on macOS'); diff --git a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart index 71d55861c7b1..69c9b2b01f19 100644 --- a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart +++ b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart @@ -147,7 +147,7 @@ void main() { } }); - for (StorageDirectory? type in [ + for (final StorageDirectory? type in [ null, ...StorageDirectory.values ]) { diff --git a/packages/path_provider/path_provider_windows/example/lib/main.dart b/packages/path_provider/path_provider_windows/example/lib/main.dart index b4b0f999d937..509292bf7405 100644 --- a/packages/path_provider/path_provider_windows/example/lib/main.dart +++ b/packages/path_provider/path_provider_windows/example/lib/main.dart @@ -4,8 +4,6 @@ // ignore_for_file: public_member_api_docs -import 'dart:async'; - import 'package:flutter/material.dart'; import 'package:path_provider_windows/path_provider_windows.dart'; @@ -79,7 +77,7 @@ class _MyAppState extends State { ), body: Center( child: Column( - children: [ + children: [ Text('Temp Directory: $_tempDirectory\n'), Text('Documents Directory: $_documentsDirectory\n'), Text('Downloads Directory: $_downloadsDirectory\n'), diff --git a/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart b/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart index 18ed3cff3ee8..24a0ee720b2a 100644 --- a/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart +++ b/packages/path_provider/path_provider_windows/example/test_driver/integration_test.dart @@ -4,7 +4,6 @@ // @dart=2.9 -import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; @@ -14,6 +13,6 @@ Future main() async { final String data = await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); - final Map result = jsonDecode(data); + final Map result = jsonDecode(data) as Map; exit(result['result'] == 'true' ? 0 : 1); } diff --git a/packages/path_provider/path_provider_windows/lib/src/folders.dart b/packages/path_provider/path_provider_windows/lib/src/folders.dart index e8112c1a953a..55def29df2d7 100644 --- a/packages/path_provider/path_provider_windows/lib/src/folders.dart +++ b/packages/path_provider/path_provider_windows/lib/src/folders.dart @@ -4,6 +4,9 @@ import 'package:win32/win32.dart'; +// ignore_for_file: non_constant_identifier_names + +// ignore: avoid_classes_with_only_static_members /// A class containing the GUID references for each of the documented Windows /// known folders. A property of this class may be passed to the `getPath` /// method in the [PathProvidersWindows] class to retrieve a known folder from diff --git a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart index 5fef0dba32ed..13841a058638 100644 --- a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart +++ b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_real.dart @@ -2,9 +2,8 @@ // 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 'dart:ffi'; +import 'dart:io'; import 'package:ffi/ffi.dart'; import 'package:meta/meta.dart'; @@ -22,14 +21,15 @@ import 'folders.dart'; class VersionInfoQuerier { /// Returns the value for [key] in [versionInfo]s English strings section, or /// null if there is no such entry, or if versionInfo is null. - getStringValue(Pointer? versionInfo, key) { + String? getStringValue(Pointer? versionInfo, String key) { if (versionInfo == null) { return null; } - const kEnUsLanguageCode = '040904e4'; - final keyPath = TEXT('\\StringFileInfo\\$kEnUsLanguageCode\\$key'); - final length = calloc(); - final valueAddress = calloc>(); + const String kEnUsLanguageCode = '040904e4'; + final Pointer keyPath = + TEXT('\\StringFileInfo\\$kEnUsLanguageCode\\$key'); + final Pointer length = calloc(); + final Pointer> valueAddress = calloc>(); try { if (VerQueryValue(versionInfo, keyPath, valueAddress, length) == 0) { return null; @@ -54,14 +54,14 @@ class PathProviderWindows extends PathProviderPlatform { /// This is typically the same as the TMP environment variable. @override Future getTemporaryPath() async { - final buffer = calloc(MAX_PATH + 1).cast(); + final Pointer buffer = calloc(MAX_PATH + 1).cast(); String path; try { - final length = GetTempPath(MAX_PATH, buffer); + final int length = GetTempPath(MAX_PATH, buffer); if (length == 0) { - final error = GetLastError(); + final int error = GetLastError(); throw WindowsException(error); } else { path = buffer.toDartString(); @@ -69,18 +69,18 @@ class PathProviderWindows extends PathProviderPlatform { // GetTempPath adds a trailing backslash, but SHGetKnownFolderPath does // not. Strip off trailing backslash for consistency with other methods // here. - if (path.endsWith('\\')) { + if (path.endsWith(r'\')) { path = path.substring(0, path.length - 1); } } // Ensure that the directory exists, since GetTempPath doesn't. - final directory = Directory(path); + final Directory directory = Directory(path); if (!directory.existsSync()) { await directory.create(recursive: true); } - return Future.value(path); + return path; } finally { calloc.free(buffer); } @@ -88,8 +88,8 @@ class PathProviderWindows extends PathProviderPlatform { @override Future getApplicationSupportPath() async { - final appDataRoot = await getPath(WindowsKnownFolder.RoamingAppData); - final directory = Directory( + final String appDataRoot = await getPath(WindowsKnownFolder.RoamingAppData); + final Directory directory = Directory( path.join(appDataRoot, _getApplicationSpecificSubdirectory())); // Ensure that the directory exists if possible, since it will on other // platforms. If the name is longer than MAXPATH, creating will fail, so @@ -115,11 +115,11 @@ class PathProviderWindows extends PathProviderPlatform { /// folderID is a GUID that represents a specific known folder ID, drawn from /// [WindowsKnownFolder]. Future getPath(String folderID) { - final pathPtrPtr = calloc>(); + final Pointer> pathPtrPtr = calloc>(); final Pointer knownFolderID = calloc()..ref.setGUID(folderID); try { - final hr = SHGetKnownFolderPath( + final int hr = SHGetKnownFolderPath( knownFolderID, KF_FLAG_DEFAULT, NULL, @@ -132,8 +132,8 @@ class PathProviderWindows extends PathProviderPlatform { } } - final path = pathPtrPtr.value.toDartString(); - return Future.value(path); + final String path = pathPtrPtr.value.toDartString(); + return Future.value(path); } finally { calloc.free(pathPtrPtr); calloc.free(knownFolderID); @@ -160,14 +160,15 @@ class PathProviderWindows extends PathProviderPlatform { Pointer? infoBuffer; try { // Get the module name. - final moduleNameLength = GetModuleFileName(0, moduleNameBuffer, MAX_PATH); + final int moduleNameLength = + GetModuleFileName(0, moduleNameBuffer, MAX_PATH); if (moduleNameLength == 0) { - final error = GetLastError(); + final int error = GetLastError(); throw WindowsException(error); } // From that, load the VERSIONINFO resource - int infoSize = GetFileVersionInfoSize(moduleNameBuffer, unused); + final int infoSize = GetFileVersionInfoSize(moduleNameBuffer, unused); if (infoSize != 0) { infoBuffer = calloc(infoSize); if (GetFileVersionInfo(moduleNameBuffer, 0, infoSize, infoBuffer) == @@ -182,10 +183,8 @@ class PathProviderWindows extends PathProviderPlatform { versionInfoQuerier.getStringValue(infoBuffer, 'ProductName')); // If there was no product name, use the executable name. - if (productName == null) { - productName = - path.basenameWithoutExtension(moduleNameBuffer.toDartString()); - } + productName ??= + path.basenameWithoutExtension(moduleNameBuffer.toDartString()); return companyName != null ? path.join(companyName, productName) @@ -214,7 +213,7 @@ class PathProviderWindows extends PathProviderPlatform { .trimRight() // Ensure that it does not end with a '.'. .replaceAll(RegExp(r'[.]+$'), ''); - const kMaxComponentLength = 255; + const int kMaxComponentLength = 255; if (sanitized.length > kMaxComponentLength) { sanitized = sanitized.substring(0, kMaxComponentLength); } diff --git a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_stub.dart b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_stub.dart index 69094af9eafa..91334d95ae24 100644 --- a/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_stub.dart +++ b/packages/path_provider/path_provider_windows/lib/src/path_provider_windows_stub.dart @@ -14,9 +14,7 @@ import 'package:path_provider_platform_interface/path_provider_platform_interfac class PathProviderWindows extends PathProviderPlatform { /// Errors on attempted instantiation of the stub. It exists only to satisfy /// compile-time dependencies, and should never actually be created. - PathProviderWindows() { - assert(false); - } + PathProviderWindows() : assert(false); /// Stub; see comment on VersionInfoQuerier. VersionInfoQuerier versionInfoQuerier = VersionInfoQuerier(); diff --git a/packages/path_provider/path_provider_windows/test/path_provider_windows_test.dart b/packages/path_provider/path_provider_windows/test/path_provider_windows_test.dart index 22683d721e7c..a66c9e1ffb0d 100644 --- a/packages/path_provider/path_provider_windows/test/path_provider_windows_test.dart +++ b/packages/path_provider/path_provider_windows/test/path_provider_windows_test.dart @@ -13,20 +13,21 @@ class FakeVersionInfoQuerier implements VersionInfoQuerier { final Map responses; - getStringValue(Pointer? versionInfo, key) => responses[key]; + String? getStringValue(Pointer? versionInfo, String key) => + responses[key]; } void main() { test('getTemporaryPath', () async { - final pathProvider = PathProviderWindows(); + final PathProviderWindows pathProvider = PathProviderWindows(); expect(await pathProvider.getTemporaryPath(), contains(r'C:\')); }, skip: !Platform.isWindows); test('getApplicationSupportPath with no version info', () async { - final pathProvider = PathProviderWindows(); + final PathProviderWindows pathProvider = PathProviderWindows(); pathProvider.versionInfoQuerier = FakeVersionInfoQuerier({}); - final path = await pathProvider.getApplicationSupportPath(); + final String? path = await pathProvider.getApplicationSupportPath(); expect(path, contains(r'C:\')); expect(path, contains(r'AppData')); // The last path component should be the executable name. @@ -34,12 +35,12 @@ void main() { }, skip: !Platform.isWindows); test('getApplicationSupportPath with full version info', () async { - final pathProvider = PathProviderWindows(); + final PathProviderWindows pathProvider = PathProviderWindows(); pathProvider.versionInfoQuerier = FakeVersionInfoQuerier({ 'CompanyName': 'A Company', 'ProductName': 'Amazing App', }); - final path = await pathProvider.getApplicationSupportPath(); + final String? path = await pathProvider.getApplicationSupportPath(); expect(path, isNotNull); if (path != null) { expect(path, endsWith(r'AppData\Roaming\A Company\Amazing App')); @@ -48,11 +49,11 @@ void main() { }, skip: !Platform.isWindows); test('getApplicationSupportPath with missing company', () async { - final pathProvider = PathProviderWindows(); + final PathProviderWindows pathProvider = PathProviderWindows(); pathProvider.versionInfoQuerier = FakeVersionInfoQuerier({ 'ProductName': 'Amazing App', }); - final path = await pathProvider.getApplicationSupportPath(); + final String? path = await pathProvider.getApplicationSupportPath(); expect(path, isNotNull); if (path != null) { expect(path, endsWith(r'AppData\Roaming\Amazing App')); @@ -61,12 +62,12 @@ void main() { }, skip: !Platform.isWindows); test('getApplicationSupportPath with problematic values', () async { - final pathProvider = PathProviderWindows(); + final PathProviderWindows pathProvider = PathProviderWindows(); pathProvider.versionInfoQuerier = FakeVersionInfoQuerier({ 'CompanyName': r'A Company: Name.', 'ProductName': r'A"/Terrible\|App?*Name', }); - final path = await pathProvider.getApplicationSupportPath(); + final String? path = await pathProvider.getApplicationSupportPath(); expect(path, isNotNull); if (path != null) { expect( @@ -79,12 +80,12 @@ void main() { }, skip: !Platform.isWindows); test('getApplicationSupportPath with a completely invalid company', () async { - final pathProvider = PathProviderWindows(); + final PathProviderWindows pathProvider = PathProviderWindows(); pathProvider.versionInfoQuerier = FakeVersionInfoQuerier({ 'CompanyName': r'..', 'ProductName': r'Amazing App', }); - final path = await pathProvider.getApplicationSupportPath(); + final String? path = await pathProvider.getApplicationSupportPath(); expect(path, isNotNull); if (path != null) { expect(path, endsWith(r'AppData\Roaming\Amazing App')); @@ -93,28 +94,28 @@ void main() { }, skip: !Platform.isWindows); test('getApplicationSupportPath with very long app name', () async { - final pathProvider = PathProviderWindows(); - final truncatedName = 'A' * 255; + final PathProviderWindows pathProvider = PathProviderWindows(); + final String truncatedName = 'A' * 255; pathProvider.versionInfoQuerier = FakeVersionInfoQuerier({ 'CompanyName': 'A Company', 'ProductName': truncatedName * 2, }); - final path = await pathProvider.getApplicationSupportPath(); + final String? path = await pathProvider.getApplicationSupportPath(); expect(path, endsWith('\\$truncatedName')); // The directory won't exist, since it's longer than MAXPATH, so don't check // that here. }, skip: !Platform.isWindows); test('getApplicationDocumentsPath', () async { - final pathProvider = PathProviderWindows(); - final path = await pathProvider.getApplicationDocumentsPath(); + final PathProviderWindows pathProvider = PathProviderWindows(); + final String? path = await pathProvider.getApplicationDocumentsPath(); expect(path, contains(r'C:\')); expect(path, contains(r'Documents')); }, skip: !Platform.isWindows); test('getDownloadsPath', () async { - final pathProvider = PathProviderWindows(); - final path = await pathProvider.getDownloadsPath(); + final PathProviderWindows pathProvider = PathProviderWindows(); + final String? path = await pathProvider.getDownloadsPath(); expect(path, contains(r'C:\')); expect(path, contains(r'Downloads')); }, skip: !Platform.isWindows); diff --git a/script/incremental_build.sh b/script/incremental_build.sh index ade89afe4ca1..f0c4bc4ac35e 100755 --- a/script/incremental_build.sh +++ b/script/incremental_build.sh @@ -42,7 +42,6 @@ CUSTOM_ANALYSIS_PLUGINS=( ios_platform_images local_auth package_info - path_provider plugin_platform_interface quick_actions sensors From dc22884c113362fe8385fa4fe6365c55e6900a76 Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Wed, 31 Mar 2021 13:50:39 -0700 Subject: [PATCH 0318/1565] [google_maps_flutter_web] Migrate to null-safety. (#3726) * Updates JS-interop package to google_maps ^5.1.0 * Breaking changes: * The property `icon` of a `Marker` cannot be `null`. Defaults to `BitmapDescriptor.defaultMarker` * The property `initialCameraPosition` of a `GoogleMapController` can't be `null`. It is also marked as `required`. * The parameter `creationId` of the `buildView` method cannot be `null` (this should be handled internally for users of the plugin) * Most of the Controller methods can't be called after `remove`/`dispose`. Calling these methods now will throw an Assertion error. Before it'd be a no-op, or a null-pointer exception. --- .../google_maps_flutter_web/CHANGELOG.md | 9 + .../google_maps_flutter_web/example/README.md | 10 + .../example/build.yaml | 6 + .../google_maps_controller_test.dart | 319 +++++++++++------- .../google_maps_controller_test.mocks.dart | 202 +++++++++++ .../google_maps_plugin_test.dart | 74 ++-- .../google_maps_plugin_test.mocks.dart | 106 ++++++ .../example/integration_test/marker_test.dart | 131 +++++-- .../integration_test/markers_test.dart | 81 +++-- .../example/integration_test/shape_test.dart | 177 +++++++--- .../example/integration_test/shapes_test.dart | 70 ++-- .../example/pubspec.yaml | 21 +- .../example/regen_mocks.sh | 10 + .../example/run_test.sh | 2 + .../example/web/index.html | 1 - .../lib/google_maps_flutter_web.dart | 1 + .../lib/src/circle.dart | 23 +- .../lib/src/circles.dart | 15 +- .../lib/src/convert.dart | 192 ++++------- .../lib/src/google_maps_controller.dart | 160 ++++++--- .../lib/src/google_maps_flutter_web.dart | 76 ++--- .../lib/src/marker.dart | 54 +-- .../lib/src/markers.dart | 27 +- .../lib/src/polygon.dart | 21 +- .../lib/src/polygons.dart | 12 +- .../lib/src/polyline.dart | 22 +- .../lib/src/polylines.dart | 16 +- .../lib/src/types.dart | 4 +- .../google_maps_flutter_web/pubspec.yaml | 6 +- script/build_all_plugins_app.sh | 2 +- 30 files changed, 1245 insertions(+), 605 deletions(-) create mode 100644 packages/google_maps_flutter/google_maps_flutter_web/example/build.yaml create mode 100644 packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.mocks.dart create mode 100644 packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart create mode 100755 packages/google_maps_flutter/google_maps_flutter_web/example/regen_mocks.sh diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md index 29e9287a14fb..fd56b64dbe57 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.3.0 + +* Migrate package to null-safety. +* **Breaking changes:** + * The property `icon` of a `Marker` cannot be `null`. Defaults to `BitmapDescriptor.defaultMarker` + * The property `initialCameraPosition` of a `GoogleMapController` can't be `null`. It is also marked as `required`. + * The parameter `creationId` of the `buildView` method cannot be `null` (this should be handled internally for users of the plugin) + * Most of the Controller methods can't be called after `remove`/`dispose`. Calling these methods now will throw an Assertion error. Before it'd be a no-op, or a null-pointer exception. + ## 0.2.1 * Move integration tests to `example`. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/README.md b/packages/google_maps_flutter/google_maps_flutter_web/example/README.md index 0ec01e025570..582288a561a4 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/README.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/README.md @@ -19,3 +19,13 @@ Make sure you have updated to the latest Flutter master. * Single: `./run_test.sh integration_test/TEST_NAME.dart` * All: `./run_test.sh` + +## Mocks + +There's new `.mocks.dart` files next to the test files that use them. + +Mock files are [generated by `package:mockito`](https://github.com/dart-lang/mockito/blob/master/NULL_SAFETY_README.md#code-generation). The contents of these files can change with how the mocks are used within the tests, in addition to actual changes in the APIs they're mocking. + +Mock files can be updated either manually by running the following command: `flutter pub run build_runner build` (or the `regen_mocks.sh` script), or automatically on each call to the `run_test.sh` script. + +Please, add whatever changes show up in mock files to your PRs, or CI will fail. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/build.yaml b/packages/google_maps_flutter/google_maps_flutter_web/example/build.yaml new file mode 100644 index 000000000000..db3104bb04c6 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/build.yaml @@ -0,0 +1,6 @@ +targets: + $default: + sources: + - integration_test/*.dart + - lib/$lib$ + - $package$ diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index fd4df2ee4fd8..1d33eea4c7f3 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -2,43 +2,30 @@ // 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:html' as html; -import 'package:integration_test/integration_test.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; -import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; +import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; -import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; - -class _MockCirclesController extends Mock implements CirclesController {} - -class _MockPolygonsController extends Mock implements PolygonsController {} - -class _MockPolylinesController extends Mock implements PolylinesController {} - -class _MockMarkersController extends Mock implements MarkersController {} - -class _MockGMap extends Mock implements gmaps.GMap { - final onClickController = StreamController.broadcast(); - @override - Stream get onClick => onClickController.stream; +import 'google_maps_controller_test.mocks.dart'; - final onRightclickController = StreamController.broadcast(); - @override - Stream get onRightclick => onRightclickController.stream; +// This value is used when comparing long~num, like +// LatLng values. +const _acceptableDelta = 0.0000000001; - final onBoundsChangedController = StreamController.broadcast(); - @override - Stream get onBoundsChanged => onBoundsChangedController.stream; - - final onIdleController = StreamController.broadcast(); - @override - Stream get onIdle => onIdleController.stream; -} +@GenerateMocks([], customMocks: [ + MockSpec(returnNullOnMissingStub: true), + MockSpec(returnNullOnMissingStub: true), + MockSpec(returnNullOnMissingStub: true), + MockSpec(returnNullOnMissingStub: true), +]) /// Test Google Map Controller void main() { @@ -46,8 +33,8 @@ void main() { group('GoogleMapController', () { final int mapId = 33930; - GoogleMapController controller; - StreamController stream; + late GoogleMapController controller; + late StreamController stream; // Creates a controller with the default mapId and stream controller, and any `options` needed. GoogleMapController _createController({ @@ -57,17 +44,18 @@ void main() { Set polygons = const {}, Set polylines = const {}, Set circles = const {}, - Map options, + Map options = const {}, }) { return GoogleMapController( - mapId: mapId, - streamController: stream, - initialCameraPosition: initialCameraPosition, - markers: markers, - polygons: polygons, - polylines: polylines, - circles: circles, - mapOptions: options ?? {}); + mapId: mapId, + streamController: stream, + initialCameraPosition: initialCameraPosition, + markers: markers, + polygons: polygons, + polylines: polylines, + circles: circles, + mapOptions: options, + ); } setUp(() { @@ -81,7 +69,9 @@ void main() { testWidgets('constructor creates widget', (WidgetTester tester) async { expect(controller.widget, isNotNull); - expect(controller.widget.viewType, endsWith('$mapId')); + expect(controller.widget, isA()); + expect((controller.widget as HtmlElementView).viewType, + endsWith('$mapId')); }); testWidgets('widget is cached when reused', (WidgetTester tester) async { @@ -90,27 +80,130 @@ void main() { expect(identical(first, again), isTrue); }); - testWidgets('dispose closes the stream and removes the widget', - (WidgetTester tester) async { - controller.dispose(); - expect(stream.isClosed, isTrue); - expect(controller.widget, isNull); + group('dispose', () { + testWidgets('closes the stream and removes the widget', + (WidgetTester tester) async { + controller.dispose(); + + expect(stream.isClosed, isTrue); + expect(controller.widget, isNull); + }); + + testWidgets('cannot call getVisibleRegion after dispose', + (WidgetTester tester) async { + controller.dispose(); + + expect(() async { + await controller.getVisibleRegion(); + }, throwsAssertionError); + }); + + testWidgets('cannot call getScreenCoordinate after dispose', + (WidgetTester tester) async { + controller.dispose(); + + expect(() async { + await controller.getScreenCoordinate( + LatLng(43.3072465, -5.6918241), + ); + }, throwsAssertionError); + }); + + testWidgets('cannot call getLatLng after dispose', + (WidgetTester tester) async { + controller.dispose(); + + expect(() async { + await controller.getLatLng( + ScreenCoordinate(x: 640, y: 480), + ); + }, throwsAssertionError); + }); + + testWidgets('cannot call moveCamera after dispose', + (WidgetTester tester) async { + controller.dispose(); + + expect(() async { + await controller.moveCamera(CameraUpdate.zoomIn()); + }, throwsAssertionError); + }); + + testWidgets('cannot call getZoomLevel after dispose', + (WidgetTester tester) async { + controller.dispose(); + + expect(() async { + await controller.getZoomLevel(); + }, throwsAssertionError); + }); + + testWidgets('cannot updateCircles after dispose', + (WidgetTester tester) async { + controller.dispose(); + + expect(() { + controller.updateCircles(CircleUpdates.from({}, {})); + }, throwsAssertionError); + }); + + testWidgets('cannot updatePolygons after dispose', + (WidgetTester tester) async { + controller.dispose(); + + expect(() { + controller.updatePolygons(PolygonUpdates.from({}, {})); + }, throwsAssertionError); + }); + + testWidgets('cannot updatePolylines after dispose', + (WidgetTester tester) async { + controller.dispose(); + + expect(() { + controller.updatePolylines(PolylineUpdates.from({}, {})); + }, throwsAssertionError); + }); + + testWidgets('cannot updateMarkers after dispose', + (WidgetTester tester) async { + controller.dispose(); + + expect(() { + controller.updateMarkers(MarkerUpdates.from({}, {})); + }, throwsAssertionError); + + expect(() { + controller.showInfoWindow(MarkerId('any')); + }, throwsAssertionError); + + expect(() { + controller.hideInfoWindow(MarkerId('any')); + }, throwsAssertionError); + }); + + testWidgets('isInfoWindowShown defaults to false', + (WidgetTester tester) async { + controller.dispose(); + + expect(controller.isInfoWindowShown(MarkerId('any')), false); + }); }); }); group('init', () { - _MockCirclesController circles; - _MockMarkersController markers; - _MockPolygonsController polygons; - _MockPolylinesController polylines; - _MockGMap map; + late MockCirclesController circles; + late MockMarkersController markers; + late MockPolygonsController polygons; + late MockPolylinesController polylines; + late gmaps.GMap map; setUp(() { - circles = _MockCirclesController(); - markers = _MockMarkersController(); - polygons = _MockPolygonsController(); - polylines = _MockPolylinesController(); - map = _MockGMap(); + circles = MockCirclesController(); + markers = MockMarkersController(); + polygons = MockPolygonsController(); + polylines = MockPolylinesController(); + map = gmaps.GMap(html.DivElement()); }); testWidgets('listens to map events', (WidgetTester tester) async { @@ -123,17 +216,25 @@ void main() { polylines: polylines, ); - expect(map.onClickController.hasListener, isFalse); - expect(map.onRightclickController.hasListener, isFalse); - expect(map.onBoundsChangedController.hasListener, isFalse); - expect(map.onIdleController.hasListener, isFalse); - controller.init(); - expect(map.onClickController.hasListener, isTrue); - expect(map.onRightclickController.hasListener, isTrue); - expect(map.onBoundsChangedController.hasListener, isTrue); - expect(map.onIdleController.hasListener, isTrue); + // Trigger events on the map, and verify they've been broadcast to the stream + final capturedEvents = stream.stream.take(5); + + gmaps.Event.trigger( + map, 'click', [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); + gmaps.Event.trigger(map, 'rightclick', + [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); + gmaps.Event.trigger(map, 'bounds_changed', []); // Causes 2 events + gmaps.Event.trigger(map, 'idle', []); + + final events = await capturedEvents.toList(); + + expect(events[0], isA()); + expect(events[1], isA()); + expect(events[2], isA()); + expect(events[3], isA()); + expect(events[4], isA()); }); testWidgets('binds geometry controllers to map\'s', @@ -227,7 +328,7 @@ void main() { testWidgets('empty infoWindow does not create InfoWindow instance.', (WidgetTester tester) async { controller = _createController(markers: { - Marker(markerId: MarkerId('marker-1'), infoWindow: null), + Marker(markerId: MarkerId('marker-1')), }); controller.debugSetOverrides( @@ -239,11 +340,11 @@ void main() { final capturedMarkers = verify(markers.addMarkers(captureAny)).captured[0] as Set; - expect(capturedMarkers.first.infoWindow, isNull); + expect(capturedMarkers.first.infoWindow, InfoWindow.noText); }); group('Initialization options', () { - gmaps.MapOptions capturedOptions; + gmaps.MapOptions? capturedOptions; setUp(() { capturedOptions = null; }); @@ -260,9 +361,9 @@ void main() { controller.init(); expect(capturedOptions, isNotNull); - expect(capturedOptions.mapTypeId, gmaps.MapTypeId.SATELLITE); - expect(capturedOptions.zoomControl, true); - expect(capturedOptions.gestureHandling, 'auto', + expect(capturedOptions!.mapTypeId, gmaps.MapTypeId.SATELLITE); + expect(capturedOptions!.zoomControl, true); + expect(capturedOptions!.gestureHandling, 'auto', reason: 'by default the map handles zoom/pan gestures internally'); }); @@ -280,7 +381,7 @@ void main() { controller.init(); expect(capturedOptions, isNotNull); - expect(capturedOptions.gestureHandling, 'none', + expect(capturedOptions!.gestureHandling, 'none', reason: 'disabling scroll gestures disables all gesture handling'); }); @@ -298,29 +399,11 @@ void main() { controller.init(); expect(capturedOptions, isNotNull); - expect(capturedOptions.gestureHandling, 'none', + expect(capturedOptions!.gestureHandling, 'none', reason: 'disabling scroll gestures disables all gesture handling'); }); - testWidgets('does not set initial position if absent', - (WidgetTester tester) async { - controller = _createController( - initialCameraPosition: null, - ); - - controller.debugSetOverrides(createMap: (_, options) { - capturedOptions = options; - return map; - }); - - controller.init(); - - expect(capturedOptions, isNotNull); - expect(capturedOptions.zoom, isNull); - expect(capturedOptions.center, isNull); - }); - testWidgets('sets initial position when passed', (WidgetTester tester) async { controller = _createController( @@ -340,8 +423,8 @@ void main() { controller.init(); expect(capturedOptions, isNotNull); - expect(capturedOptions.zoom, 12); - expect(capturedOptions.center, isNotNull); + expect(capturedOptions!.zoom, 12); + expect(capturedOptions!.center, isNotNull); }); }); @@ -366,10 +449,15 @@ void main() { // These are the methods that are delegated to the gmaps.GMap object, that we can mock... group('Map control methods', () { - _MockGMap map; + late gmaps.GMap map; setUp(() { - map = _MockGMap(); + map = gmaps.GMap( + html.DivElement(), + gmaps.MapOptions() + ..zoom = 10 + ..center = gmaps.LatLng(0, 0), + ); controller = _createController(); controller.debugSetOverrides(createMap: (_, __) => map); controller.init(); @@ -380,9 +468,8 @@ void main() { controller.updateRawOptions({ 'mapType': 2, }); - final options = verify(map.options = captureAny).captured[0]; - expect(options.mapTypeId, gmaps.MapTypeId.SATELLITE); + expect(map.mapTypeId, gmaps.MapTypeId.SATELLITE); }); testWidgets('can turn on/off traffic', (WidgetTester tester) async { @@ -404,17 +491,19 @@ void main() { group('viewport getters', () { testWidgets('getVisibleRegion', (WidgetTester tester) async { - await controller.getVisibleRegion(); + final gmCenter = map.center!; + final center = + LatLng(gmCenter.lat.toDouble(), gmCenter.lng.toDouble()); + + final bounds = await controller.getVisibleRegion(); - verify(map.bounds); + expect(bounds.contains(center), isTrue, + reason: + 'The computed visible region must contain the center of the created map.'); }); testWidgets('getZoomLevel', (WidgetTester tester) async { - when(map.zoom).thenReturn(10); - - await controller.getZoomLevel(); - - verify(map.zoom); + expect(await controller.getZoomLevel(), map.zoom); }); }); @@ -423,10 +512,11 @@ void main() { await (controller .moveCamera(CameraUpdate.newLatLngZoom(LatLng(19, 26), 12))); - verify(map.zoom = 12); - final captured = verify(map.panTo(captureAny)).captured[0]; - expect(captured.lat, 19); - expect(captured.lng, 26); + final gmCenter = map.center!; + + expect(map.zoom, 12); + expect(gmCenter.lat, closeTo(19, _acceptableDelta)); + expect(gmCenter.lng, closeTo(26, _acceptableDelta)); }); }); @@ -445,7 +535,7 @@ void main() { }); testWidgets('updateCircles', (WidgetTester tester) async { - final mock = _MockCirclesController(); + final mock = MockCirclesController(); controller.debugSetOverrides(circles: mock); final previous = { @@ -472,7 +562,7 @@ void main() { }); testWidgets('updateMarkers', (WidgetTester tester) async { - final mock = _MockMarkersController(); + final mock = MockMarkersController(); controller.debugSetOverrides(markers: mock); final previous = { @@ -499,7 +589,7 @@ void main() { }); testWidgets('updatePolygons', (WidgetTester tester) async { - final mock = _MockPolygonsController(); + final mock = MockPolygonsController(); controller.debugSetOverrides(polygons: mock); final previous = { @@ -526,7 +616,7 @@ void main() { }); testWidgets('updatePolylines', (WidgetTester tester) async { - final mock = _MockPolylinesController(); + final mock = MockPolylinesController(); controller.debugSetOverrides(polylines: mock); final previous = { @@ -553,9 +643,10 @@ void main() { }); testWidgets('infoWindow visibility', (WidgetTester tester) async { - final mock = _MockMarkersController(); - controller.debugSetOverrides(markers: mock); + final mock = MockMarkersController(); final markerId = MarkerId('marker-with-infowindow'); + when(mock.isInfoWindowShown(markerId)).thenReturn(true); + controller.debugSetOverrides(markers: mock); controller.showInfoWindow(markerId); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.mocks.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.mocks.dart new file mode 100644 index 000000000000..47933285b208 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.mocks.dart @@ -0,0 +1,202 @@ +// Copyright 2013 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. + +// Mocks generated by Mockito 5.0.2 from annotations +// in google_maps_flutter_web_integration_tests/integration_test/google_maps_controller_test.dart. +// Do not manually edit this file. + +import 'package:google_maps/src/generated/google_maps_core.js.g.dart' as _i2; +import 'package:google_maps_flutter_platform_interface/src/types/circle.dart' + as _i4; +import 'package:google_maps_flutter_platform_interface/src/types/marker.dart' + as _i7; +import 'package:google_maps_flutter_platform_interface/src/types/polygon.dart' + as _i5; +import 'package:google_maps_flutter_platform_interface/src/types/polyline.dart' + as _i6; +import 'package:google_maps_flutter_web/google_maps_flutter_web.dart' as _i3; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: comment_references +// ignore_for_file: unnecessary_parenthesis + +class _FakeGMap extends _i1.Fake implements _i2.GMap {} + +/// A class which mocks [CirclesController]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockCirclesController extends _i1.Mock implements _i3.CirclesController { + @override + Map<_i4.CircleId, _i3.CircleController> get circles => + (super.noSuchMethod(Invocation.getter(#circles), + returnValue: <_i4.CircleId, _i3.CircleController>{}) + as Map<_i4.CircleId, _i3.CircleController>); + @override + _i2.GMap get googleMap => (super.noSuchMethod(Invocation.getter(#googleMap), + returnValue: _FakeGMap()) as _i2.GMap); + @override + set googleMap(_i2.GMap? _googleMap) => + super.noSuchMethod(Invocation.setter(#googleMap, _googleMap), + returnValueForMissingStub: null); + @override + int get mapId => + (super.noSuchMethod(Invocation.getter(#mapId), returnValue: 0) as int); + @override + set mapId(int? _mapId) => + super.noSuchMethod(Invocation.setter(#mapId, _mapId), + returnValueForMissingStub: null); + @override + void addCircles(Set<_i4.Circle>? circlesToAdd) => + super.noSuchMethod(Invocation.method(#addCircles, [circlesToAdd]), + returnValueForMissingStub: null); + @override + void changeCircles(Set<_i4.Circle>? circlesToChange) => + super.noSuchMethod(Invocation.method(#changeCircles, [circlesToChange]), + returnValueForMissingStub: null); + @override + void removeCircles(Set<_i4.CircleId>? circleIdsToRemove) => + super.noSuchMethod(Invocation.method(#removeCircles, [circleIdsToRemove]), + returnValueForMissingStub: null); + @override + void bindToMap(int? mapId, _i2.GMap? googleMap) => + super.noSuchMethod(Invocation.method(#bindToMap, [mapId, googleMap]), + returnValueForMissingStub: null); +} + +/// A class which mocks [PolygonsController]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockPolygonsController extends _i1.Mock + implements _i3.PolygonsController { + @override + Map<_i5.PolygonId, _i3.PolygonController> get polygons => + (super.noSuchMethod(Invocation.getter(#polygons), + returnValue: <_i5.PolygonId, _i3.PolygonController>{}) + as Map<_i5.PolygonId, _i3.PolygonController>); + @override + _i2.GMap get googleMap => (super.noSuchMethod(Invocation.getter(#googleMap), + returnValue: _FakeGMap()) as _i2.GMap); + @override + set googleMap(_i2.GMap? _googleMap) => + super.noSuchMethod(Invocation.setter(#googleMap, _googleMap), + returnValueForMissingStub: null); + @override + int get mapId => + (super.noSuchMethod(Invocation.getter(#mapId), returnValue: 0) as int); + @override + set mapId(int? _mapId) => + super.noSuchMethod(Invocation.setter(#mapId, _mapId), + returnValueForMissingStub: null); + @override + void addPolygons(Set<_i5.Polygon>? polygonsToAdd) => + super.noSuchMethod(Invocation.method(#addPolygons, [polygonsToAdd]), + returnValueForMissingStub: null); + @override + void changePolygons(Set<_i5.Polygon>? polygonsToChange) => + super.noSuchMethod(Invocation.method(#changePolygons, [polygonsToChange]), + returnValueForMissingStub: null); + @override + void removePolygons(Set<_i5.PolygonId>? polygonIdsToRemove) => super + .noSuchMethod(Invocation.method(#removePolygons, [polygonIdsToRemove]), + returnValueForMissingStub: null); + @override + void bindToMap(int? mapId, _i2.GMap? googleMap) => + super.noSuchMethod(Invocation.method(#bindToMap, [mapId, googleMap]), + returnValueForMissingStub: null); +} + +/// A class which mocks [PolylinesController]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockPolylinesController extends _i1.Mock + implements _i3.PolylinesController { + @override + Map<_i6.PolylineId, _i3.PolylineController> get lines => + (super.noSuchMethod(Invocation.getter(#lines), + returnValue: <_i6.PolylineId, _i3.PolylineController>{}) + as Map<_i6.PolylineId, _i3.PolylineController>); + @override + _i2.GMap get googleMap => (super.noSuchMethod(Invocation.getter(#googleMap), + returnValue: _FakeGMap()) as _i2.GMap); + @override + set googleMap(_i2.GMap? _googleMap) => + super.noSuchMethod(Invocation.setter(#googleMap, _googleMap), + returnValueForMissingStub: null); + @override + int get mapId => + (super.noSuchMethod(Invocation.getter(#mapId), returnValue: 0) as int); + @override + set mapId(int? _mapId) => + super.noSuchMethod(Invocation.setter(#mapId, _mapId), + returnValueForMissingStub: null); + @override + void addPolylines(Set<_i6.Polyline>? polylinesToAdd) => + super.noSuchMethod(Invocation.method(#addPolylines, [polylinesToAdd]), + returnValueForMissingStub: null); + @override + void changePolylines(Set<_i6.Polyline>? polylinesToChange) => super + .noSuchMethod(Invocation.method(#changePolylines, [polylinesToChange]), + returnValueForMissingStub: null); + @override + void removePolylines(Set<_i6.PolylineId>? polylineIdsToRemove) => super + .noSuchMethod(Invocation.method(#removePolylines, [polylineIdsToRemove]), + returnValueForMissingStub: null); + @override + void bindToMap(int? mapId, _i2.GMap? googleMap) => + super.noSuchMethod(Invocation.method(#bindToMap, [mapId, googleMap]), + returnValueForMissingStub: null); +} + +/// A class which mocks [MarkersController]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockMarkersController extends _i1.Mock implements _i3.MarkersController { + @override + Map<_i7.MarkerId, _i3.MarkerController> get markers => + (super.noSuchMethod(Invocation.getter(#markers), + returnValue: <_i7.MarkerId, _i3.MarkerController>{}) + as Map<_i7.MarkerId, _i3.MarkerController>); + @override + _i2.GMap get googleMap => (super.noSuchMethod(Invocation.getter(#googleMap), + returnValue: _FakeGMap()) as _i2.GMap); + @override + set googleMap(_i2.GMap? _googleMap) => + super.noSuchMethod(Invocation.setter(#googleMap, _googleMap), + returnValueForMissingStub: null); + @override + int get mapId => + (super.noSuchMethod(Invocation.getter(#mapId), returnValue: 0) as int); + @override + set mapId(int? _mapId) => + super.noSuchMethod(Invocation.setter(#mapId, _mapId), + returnValueForMissingStub: null); + @override + void addMarkers(Set<_i7.Marker>? markersToAdd) => + super.noSuchMethod(Invocation.method(#addMarkers, [markersToAdd]), + returnValueForMissingStub: null); + @override + void changeMarkers(Set<_i7.Marker>? markersToChange) => + super.noSuchMethod(Invocation.method(#changeMarkers, [markersToChange]), + returnValueForMissingStub: null); + @override + void removeMarkers(Set<_i7.MarkerId>? markerIdsToRemove) => + super.noSuchMethod(Invocation.method(#removeMarkers, [markerIdsToRemove]), + returnValueForMissingStub: null); + @override + void showMarkerInfoWindow(_i7.MarkerId? markerId) => + super.noSuchMethod(Invocation.method(#showMarkerInfoWindow, [markerId]), + returnValueForMissingStub: null); + @override + void hideMarkerInfoWindow(_i7.MarkerId? markerId) => + super.noSuchMethod(Invocation.method(#hideMarkerInfoWindow, [markerId]), + returnValueForMissingStub: null); + @override + bool isInfoWindowShown(_i7.MarkerId? markerId) => + (super.noSuchMethod(Invocation.method(#isInfoWindowShown, [markerId]), + returnValue: false) as bool); + @override + void bindToMap(int? mapId, _i2.GMap? googleMap) => + super.noSuchMethod(Invocation.method(#bindToMap, [mapId, googleMap]), + returnValueForMissingStub: null); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart index dee37618c940..2de431a5445e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart @@ -2,36 +2,40 @@ // 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:js_util' show getProperty; import 'package:integration_test/integration_test.dart'; import 'package:flutter/widgets.dart'; import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; -class _MockGoogleMapController extends Mock implements GoogleMapController {} +import 'google_maps_plugin_test.mocks.dart'; + +@GenerateMocks([], customMocks: [ + MockSpec(returnNullOnMissingStub: true), +]) /// Test GoogleMapsPlugin void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('GoogleMapsPlugin', () { - _MockGoogleMapController controller; - GoogleMapsPlugin plugin; - int reportedMapId; + late MockGoogleMapController controller; + late GoogleMapsPlugin plugin; + int? reportedMapId; void onPlatformViewCreated(int id) { reportedMapId = id; } setUp(() { - controller = _MockGoogleMapController(); + controller = MockGoogleMapController(); plugin = GoogleMapsPlugin(); reportedMapId = null; }); @@ -72,34 +76,21 @@ void main() { final testMapId = 33930; final initialCameraPosition = CameraPosition(target: LatLng(0, 0)); - testWidgets('throws without _webOnlyMapCreationId', - (WidgetTester tester) async { - expect( - () => plugin.buildView( - null, - onPlatformViewCreated, - initialCameraPosition: initialCameraPosition, - ), - throwsAssertionError, - reason: - '_webOnlyMapCreationId is mandatory to prevent unnecessary reloads in web.', - ); - }); - testWidgets( 'returns an HtmlElementView and caches the controller for later', (WidgetTester tester) async { final Map cache = {}; plugin.debugSetMapById(cache); - final HtmlElementView widget = plugin.buildView( + final Widget widget = plugin.buildView( testMapId, onPlatformViewCreated, initialCameraPosition: initialCameraPosition, ); + expect(widget, isA()); expect( - widget.viewType, + (widget as HtmlElementView).viewType, contains('$testMapId'), reason: 'view type should contain the mapId passed when creating the map.', @@ -160,11 +151,10 @@ void main() { expect(styles.length, 1); // Let's peek inside the styles... var style = styles[0] as gmaps.MapTypeStyle; - expect(style.featureType, gmaps.MapTypeStyleFeatureType.POI_PARK); - expect( - style.elementType, gmaps.MapTypeStyleElementType.LABELS_TEXT_FILL); - expect(style.stylers.length, 1); - expect(style.stylers[0].color, '#6b9a76'); + expect(style.featureType, 'poi.park'); + expect(style.elementType, 'labels.text.fill'); + expect(style.stylers?.length, 1); + expect(getProperty(style.stylers![0]!, 'color'), '#6b9a76'); }); }); @@ -247,31 +237,50 @@ void main() { verify(controller.moveCamera(expectedUpdates)); }); + // Viewport testWidgets('getVisibleRegion', (WidgetTester tester) async { + when(controller.getVisibleRegion()) + .thenAnswer((_) async => LatLngBounds( + northeast: LatLng(47.2359634, -68.0192019), + southwest: LatLng(34.5019594, -120.4974629), + )); await plugin.getVisibleRegion(mapId: mapId); verify(controller.getVisibleRegion()); }); + testWidgets('getZoomLevel', (WidgetTester tester) async { + when(controller.getZoomLevel()).thenAnswer((_) async => 10); await plugin.getZoomLevel(mapId: mapId); verify(controller.getZoomLevel()); }); + testWidgets('getScreenCoordinate', (WidgetTester tester) async { + when(controller.getScreenCoordinate(any)).thenAnswer( + (_) async => ScreenCoordinate(x: 320, y: 240) // fake return + ); + final latLng = LatLng(43.3613, -5.8499); await plugin.getScreenCoordinate(latLng, mapId: mapId); verify(controller.getScreenCoordinate(latLng)); }); + testWidgets('getLatLng', (WidgetTester tester) async { + when(controller.getLatLng(any)) + .thenAnswer((_) async => LatLng(43.3613, -5.8499) // fake return + ); + final coordinates = ScreenCoordinate(x: 19, y: 26); await plugin.getLatLng(coordinates, mapId: mapId); verify(controller.getLatLng(coordinates)); }); + // InfoWindows testWidgets('showMarkerInfoWindow', (WidgetTester tester) async { final markerId = MarkerId('testing-123'); @@ -280,6 +289,7 @@ void main() { verify(controller.showInfoWindow(markerId)); }); + testWidgets('hideMarkerInfoWindow', (WidgetTester tester) async { final markerId = MarkerId('testing-123'); @@ -287,7 +297,10 @@ void main() { verify(controller.hideInfoWindow(markerId)); }); + testWidgets('isMarkerInfoWindowShown', (WidgetTester tester) async { + when(controller.isInfoWindowShown(any)).thenReturn(true); + final markerId = MarkerId('testing-123'); await plugin.isMarkerInfoWindowShown(markerId, mapId: mapId); @@ -299,7 +312,7 @@ void main() { // Verify all event streams are filtered correctly from the main one... group('Event Streams', () { int mapId = 0; - StreamController streamController; + late StreamController streamController; setUp(() { streamController = StreamController.broadcast(); when(controller.events) @@ -308,7 +321,8 @@ void main() { }); // Dispatches a few events in the global streamController, and expects *only* the passed event to be there. - void _testStreamFiltering(Stream stream, MapEvent event) async { + Future _testStreamFiltering( + Stream stream, MapEvent event) async { Timer.run(() { streamController.add(_OtherMapEvent(mapId)); streamController.add(event); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart new file mode 100644 index 000000000000..43150f63ef93 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart @@ -0,0 +1,106 @@ +// Copyright 2013 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. + +// Mocks generated by Mockito 5.0.2 from annotations +// in google_maps_flutter_web_integration_tests/integration_test/google_maps_plugin_test.dart. +// Do not manually edit this file. + +import 'dart:async' as _i5; + +import 'package:google_maps_flutter_platform_interface/src/events/map_event.dart' + as _i6; +import 'package:google_maps_flutter_platform_interface/src/types/camera.dart' + as _i7; +import 'package:google_maps_flutter_platform_interface/src/types/circle_updates.dart' + as _i8; +import 'package:google_maps_flutter_platform_interface/src/types/location.dart' + as _i2; +import 'package:google_maps_flutter_platform_interface/src/types/marker.dart' + as _i12; +import 'package:google_maps_flutter_platform_interface/src/types/marker_updates.dart' + as _i11; +import 'package:google_maps_flutter_platform_interface/src/types/polygon_updates.dart' + as _i9; +import 'package:google_maps_flutter_platform_interface/src/types/polyline_updates.dart' + as _i10; +import 'package:google_maps_flutter_platform_interface/src/types/screen_coordinate.dart' + as _i3; +import 'package:google_maps_flutter_web/google_maps_flutter_web.dart' as _i4; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: comment_references +// ignore_for_file: unnecessary_parenthesis + +class _FakeLatLngBounds extends _i1.Fake implements _i2.LatLngBounds {} + +class _FakeScreenCoordinate extends _i1.Fake implements _i3.ScreenCoordinate {} + +class _FakeLatLng extends _i1.Fake implements _i2.LatLng {} + +/// A class which mocks [GoogleMapController]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockGoogleMapController extends _i1.Mock + implements _i4.GoogleMapController { + @override + _i5.Stream<_i6.MapEvent> get events => + (super.noSuchMethod(Invocation.getter(#events), + returnValue: Stream<_i6.MapEvent>.empty()) + as _i5.Stream<_i6.MapEvent>); + @override + void updateRawOptions(Map? optionsUpdate) => + super.noSuchMethod(Invocation.method(#updateRawOptions, [optionsUpdate]), + returnValueForMissingStub: null); + @override + _i5.Future<_i2.LatLngBounds> getVisibleRegion() => + (super.noSuchMethod(Invocation.method(#getVisibleRegion, []), + returnValue: Future.value(_FakeLatLngBounds())) + as _i5.Future<_i2.LatLngBounds>); + @override + _i5.Future<_i3.ScreenCoordinate> getScreenCoordinate(_i2.LatLng? latLng) => + (super.noSuchMethod(Invocation.method(#getScreenCoordinate, [latLng]), + returnValue: Future.value(_FakeScreenCoordinate())) + as _i5.Future<_i3.ScreenCoordinate>); + @override + _i5.Future<_i2.LatLng> getLatLng(_i3.ScreenCoordinate? screenCoordinate) => + (super.noSuchMethod(Invocation.method(#getLatLng, [screenCoordinate]), + returnValue: Future.value(_FakeLatLng())) as _i5.Future<_i2.LatLng>); + @override + _i5.Future moveCamera(_i7.CameraUpdate? cameraUpdate) => + (super.noSuchMethod(Invocation.method(#moveCamera, [cameraUpdate]), + returnValue: Future.value(null), + returnValueForMissingStub: Future.value()) as _i5.Future); + @override + _i5.Future getZoomLevel() => + (super.noSuchMethod(Invocation.method(#getZoomLevel, []), + returnValue: Future.value(0.0)) as _i5.Future); + @override + void updateCircles(_i8.CircleUpdates? updates) => + super.noSuchMethod(Invocation.method(#updateCircles, [updates]), + returnValueForMissingStub: null); + @override + void updatePolygons(_i9.PolygonUpdates? updates) => + super.noSuchMethod(Invocation.method(#updatePolygons, [updates]), + returnValueForMissingStub: null); + @override + void updatePolylines(_i10.PolylineUpdates? updates) => + super.noSuchMethod(Invocation.method(#updatePolylines, [updates]), + returnValueForMissingStub: null); + @override + void updateMarkers(_i11.MarkerUpdates? updates) => + super.noSuchMethod(Invocation.method(#updateMarkers, [updates]), + returnValueForMissingStub: null); + @override + void showInfoWindow(_i12.MarkerId? markerId) => + super.noSuchMethod(Invocation.method(#showInfoWindow, [markerId]), + returnValueForMissingStub: null); + @override + void hideInfoWindow(_i12.MarkerId? markerId) => + super.noSuchMethod(Invocation.method(#hideInfoWindow, [markerId]), + returnValueForMissingStub: null); + @override + bool isInfoWindowShown(_i12.MarkerId? markerId) => + (super.noSuchMethod(Invocation.method(#isInfoWindowShown, [markerId]), + returnValue: false) as bool); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart index 1a85f3bb28e1..2bfa27b73a77 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart @@ -2,100 +2,157 @@ // 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:html' as html; import 'package:integration_test/integration_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; - -class _MockMarker extends Mock implements gmaps.Marker { - final onClickController = StreamController(); - final onDragEndController = StreamController(); - - @override - Stream get onClick => onClickController.stream; - - @override - Stream get onDragend => onDragEndController.stream; -} - -class _MockMouseEvent extends Mock implements gmaps.MouseEvent {} - -class _MockInfoWindow extends Mock implements gmaps.InfoWindow {} /// Test Markers void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - bool called = false; + // Since onTap/DragEnd events happen asynchronously, we need to store when the event + // is fired. We use a completer so the test can wait for the future to be completed. + late Completer _methodCalledCompleter; + + /// This is the future value of the [_methodCalledCompleter]. Reinitialized + /// in the [setUp] method, and completed (as `true`) by [onTap] and [onDragEnd] + /// when those methods are called from the MarkerController. + late Future methodCalled; + void onTap() { - called = true; + _methodCalledCompleter.complete(true); } void onDragEnd(gmaps.LatLng _) { - called = true; + _methodCalledCompleter.complete(true); } setUp(() { - called = false; + _methodCalledCompleter = Completer(); + methodCalled = _methodCalledCompleter.future; }); group('MarkerController', () { - _MockMarker marker; + late gmaps.Marker marker; setUp(() { - marker = _MockMarker(); + marker = gmaps.Marker(); }); testWidgets('onTap gets called', (WidgetTester tester) async { MarkerController(marker: marker, onTap: onTap); - // Simulate a click - await marker.onClickController.add(null); - expect(called, isTrue); + + // Trigger a click event... + gmaps.Event.trigger(marker, 'click', [gmaps.MapMouseEvent()]); + + // The event handling is now truly async. Wait for it... + expect(await methodCalled, isTrue); }); testWidgets('onDragEnd gets called', (WidgetTester tester) async { - when(marker.draggable).thenReturn(true); MarkerController(marker: marker, onDragEnd: onDragEnd); - // Simulate a drag end - await marker.onDragEndController.add(_MockMouseEvent()); - expect(called, isTrue); + + // Trigger a drag end event... + gmaps.Event.trigger(marker, 'dragend', + [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); + + expect(await methodCalled, isTrue); }); testWidgets('update', (WidgetTester tester) async { final controller = MarkerController(marker: marker); - final options = gmaps.MarkerOptions()..draggable = false; + final options = gmaps.MarkerOptions()..draggable = true; + + expect(marker.draggable, isNull); + controller.update(options); - verify(marker.options = options); + + expect(marker.draggable, isTrue); }); testWidgets('infoWindow null, showInfoWindow.', (WidgetTester tester) async { final controller = MarkerController(marker: marker); + controller.showInfoWindow(); + expect(controller.infoWindowShown, isFalse); }); testWidgets('showInfoWindow', (WidgetTester tester) async { - final infoWindow = _MockInfoWindow(); + final infoWindow = gmaps.InfoWindow(); + final map = gmaps.GMap(html.DivElement()); + marker.set('map', map); final controller = MarkerController(marker: marker, infoWindow: infoWindow); + controller.showInfoWindow(); - verify(infoWindow.open(any, any)).called(1); + + expect(infoWindow.get('map'), map); expect(controller.infoWindowShown, isTrue); }); testWidgets('hideInfoWindow', (WidgetTester tester) async { - final infoWindow = _MockInfoWindow(); + final infoWindow = gmaps.InfoWindow(); + final map = gmaps.GMap(html.DivElement()); + marker.set('map', map); final controller = MarkerController(marker: marker, infoWindow: infoWindow); + controller.hideInfoWindow(); - verify(infoWindow.close()).called(1); + + expect(infoWindow.get('map'), isNull); expect(controller.infoWindowShown, isFalse); }); + + group('remove', () { + late MarkerController controller; + + setUp(() { + final infoWindow = gmaps.InfoWindow(); + final map = gmaps.GMap(html.DivElement()); + marker.set('map', map); + controller = MarkerController(marker: marker, infoWindow: infoWindow); + }); + + testWidgets('drops gmaps instance', (WidgetTester tester) async { + controller.remove(); + + expect(controller.marker, isNull); + }); + + testWidgets('cannot call update after remove', + (WidgetTester tester) async { + final options = gmaps.MarkerOptions()..draggable = true; + + controller.remove(); + + expect(() { + controller.update(options); + }, throwsAssertionError); + }); + + testWidgets('cannot call showInfoWindow after remove', + (WidgetTester tester) async { + controller.remove(); + + expect(() { + controller.showInfoWindow(); + }, throwsAssertionError); + }); + + testWidgets('cannot call hideInfoWindow after remove', + (WidgetTester tester) async { + controller.remove(); + + expect(() { + controller.hideInfoWindow(); + }, throwsAssertionError); + }); + }); }); } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart index e9e458c85685..6f2bf610f77d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart @@ -2,17 +2,17 @@ // 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:html'; +import 'dart:html' as html; +import 'dart:js_util' show getProperty; -import 'package:http/http.dart' as http; -import 'package:integration_test/integration_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; -import 'package:flutter_test/flutter_test.dart'; +import 'package:http/http.dart' as http; +import 'package:integration_test/integration_test.dart'; import 'resources/icon_image_base64.dart'; @@ -20,12 +20,15 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('MarkersController', () { - StreamController stream; - MarkersController controller; + late StreamController events; + late MarkersController controller; + late gmaps.GMap map; setUp(() { - stream = StreamController(); - controller = MarkersController(stream: stream); + events = StreamController(); + controller = MarkersController(stream: events); + map = gmaps.GMap(html.DivElement()); + controller.bindToMap(123, map); }); testWidgets('addMarkers', (WidgetTester tester) async { @@ -48,7 +51,7 @@ void main() { }; controller.addMarkers(markers); - expect(controller.markers[MarkerId('1')].marker.draggable, isFalse); + expect(controller.markers[MarkerId('1')]?.marker?.draggable, isFalse); // Update the marker with radius 10 final updatedMarkers = { @@ -57,7 +60,7 @@ void main() { controller.changeMarkers(updatedMarkers); expect(controller.markers.length, 1); - expect(controller.markers[MarkerId('1')].marker.draggable, isTrue); + expect(controller.markers[MarkerId('1')]?.marker?.draggable, isTrue); }); testWidgets('removeMarkers', (WidgetTester tester) async { @@ -95,15 +98,15 @@ void main() { controller.addMarkers(markers); - expect(controller.markers[MarkerId('1')].infoWindowShown, isFalse); + expect(controller.markers[MarkerId('1')]?.infoWindowShown, isFalse); controller.showMarkerInfoWindow(MarkerId('1')); - expect(controller.markers[MarkerId('1')].infoWindowShown, isTrue); + expect(controller.markers[MarkerId('1')]?.infoWindowShown, isTrue); controller.hideMarkerInfoWindow(MarkerId('1')); - expect(controller.markers[MarkerId('1')].infoWindowShown, isFalse); + expect(controller.markers[MarkerId('1')]?.infoWindowShown, isFalse); }); // https://github.com/flutter/flutter/issues/67380 @@ -121,33 +124,21 @@ void main() { }; controller.addMarkers(markers); - expect(controller.markers[MarkerId('1')].infoWindowShown, isFalse); - expect(controller.markers[MarkerId('2')].infoWindowShown, isFalse); + expect(controller.markers[MarkerId('1')]?.infoWindowShown, isFalse); + expect(controller.markers[MarkerId('2')]?.infoWindowShown, isFalse); controller.showMarkerInfoWindow(MarkerId('1')); - expect(controller.markers[MarkerId('1')].infoWindowShown, isTrue); - expect(controller.markers[MarkerId('2')].infoWindowShown, isFalse); + expect(controller.markers[MarkerId('1')]?.infoWindowShown, isTrue); + expect(controller.markers[MarkerId('2')]?.infoWindowShown, isFalse); controller.showMarkerInfoWindow(MarkerId('2')); - expect(controller.markers[MarkerId('1')].infoWindowShown, isFalse); - expect(controller.markers[MarkerId('2')].infoWindowShown, isTrue); + expect(controller.markers[MarkerId('1')]?.infoWindowShown, isFalse); + expect(controller.markers[MarkerId('2')]?.infoWindowShown, isTrue); }); - // https://github.com/flutter/flutter/issues/64938 - testWidgets('markers with icon:null work', (WidgetTester tester) async { - final markers = { - Marker(markerId: MarkerId('1'), icon: null), - }; - - controller.addMarkers(markers); - - expect(controller.markers.length, 1); - expect(controller.markers[MarkerId('1')].marker.icon, isNull); - }); - - // + // https://github.com/flutter/flutter/issues/66622 testWidgets('markers with custom bitmap icon work', (WidgetTester tester) async { final bytes = Base64Decoder().convert(iconImageBase64); @@ -159,11 +150,15 @@ void main() { controller.addMarkers(markers); expect(controller.markers.length, 1); - expect(controller.markers[MarkerId('1')].marker.icon, isNotNull); - expect(controller.markers[MarkerId('1')].marker.icon.url, - startsWith('blob:')); + expect(controller.markers[MarkerId('1')]?.marker?.icon, isNotNull); + + final blobUrl = getProperty( + controller.markers[MarkerId('1')]!.marker!.icon!, + 'url', + ); + + expect(blobUrl, startsWith('blob:')); - final blobUrl = controller.markers[MarkerId('1')].marker.icon.url; final response = await http.get(Uri.parse(blobUrl)); expect(response.bodyBytes, bytes, @@ -187,8 +182,8 @@ void main() { controller.addMarkers(markers); expect(controller.markers.length, 1); - final content = - controller.markers[MarkerId('1')].infoWindow.content as HtmlElement; + final content = controller.markers[MarkerId('1')]?.infoWindow?.content + as html.HtmlElement; expect(content.innerHtml, contains('title for test')); expect( content.innerHtml, @@ -211,12 +206,12 @@ void main() { controller.addMarkers(markers); expect(controller.markers.length, 1); - final content = - controller.markers[MarkerId('1')].infoWindow.content as HtmlElement; + final content = controller.markers[MarkerId('1')]?.infoWindow?.content + as html.HtmlElement; content.click(); - final event = await stream.stream.first; + final event = await events.stream.first; expect(event, isA()); expect((event as InfoWindowTapEvent).value, equals(MarkerId('1'))); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart index 0c351971af7c..547aaec6dc0a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart @@ -2,114 +2,195 @@ // 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 'package:integration_test/integration_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; - -class _MockCircle extends Mock implements gmaps.Circle { - final onClickController = StreamController(); - @override - Stream get onClick => onClickController.stream; -} - -class _MockPolygon extends Mock implements gmaps.Polygon { - final onClickController = StreamController(); - @override - Stream get onClick => onClickController.stream; -} - -class _MockPolyline extends Mock implements gmaps.Polyline { - final onClickController = StreamController(); - @override - Stream get onClick => onClickController.stream; -} /// Test Shapes (Circle, Polygon, Polyline) void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - bool called = false; + // Since onTap events happen asynchronously, we need to store when the event + // is fired. We use a completer so the test can wait for the future to be completed. + late Completer _methodCalledCompleter; + + /// This is the future value of the [_methodCalledCompleter]. Reinitialized + /// in the [setUp] method, and completed (as `true`) by [onTap], when it gets + /// called by the corresponding Shape Controller. + late Future methodCalled; + void onTap() { - called = true; + _methodCalledCompleter.complete(true); } setUp(() { - called = false; + _methodCalledCompleter = Completer(); + methodCalled = _methodCalledCompleter.future; }); group('CircleController', () { - _MockCircle circle; + late gmaps.Circle circle; setUp(() { - circle = _MockCircle(); + circle = gmaps.Circle(); }); testWidgets('onTap gets called', (WidgetTester tester) async { CircleController(circle: circle, consumeTapEvents: true, onTap: onTap); - expect(circle.onClickController.hasListener, isTrue); - // Simulate a click - await circle.onClickController.add(null); - expect(called, isTrue); + + // Trigger a click event... + gmaps.Event.trigger(circle, 'click', [gmaps.MapMouseEvent()]); + + // The event handling is now truly async. Wait for it... + expect(await methodCalled, isTrue); }); testWidgets('update', (WidgetTester tester) async { final controller = CircleController(circle: circle); - final options = gmaps.CircleOptions()..draggable = false; + final options = gmaps.CircleOptions()..draggable = true; + + expect(circle.draggable, isNull); + controller.update(options); - verify(circle.options = options); + + expect(circle.draggable, isTrue); + }); + + group('remove', () { + late CircleController controller; + + setUp(() { + controller = CircleController(circle: circle); + }); + + testWidgets('drops gmaps instance', (WidgetTester tester) async { + controller.remove(); + + expect(controller.circle, isNull); + }); + + testWidgets('cannot call update after remove', + (WidgetTester tester) async { + final options = gmaps.CircleOptions()..draggable = true; + + controller.remove(); + + expect(() { + controller.update(options); + }, throwsAssertionError); + }); }); }); group('PolygonController', () { - _MockPolygon polygon; + late gmaps.Polygon polygon; setUp(() { - polygon = _MockPolygon(); + polygon = gmaps.Polygon(); }); testWidgets('onTap gets called', (WidgetTester tester) async { PolygonController(polygon: polygon, consumeTapEvents: true, onTap: onTap); - expect(polygon.onClickController.hasListener, isTrue); - // Simulate a click - await polygon.onClickController.add(null); - expect(called, isTrue); + + // Trigger a click event... + gmaps.Event.trigger(polygon, 'click', [gmaps.MapMouseEvent()]); + + // The event handling is now truly async. Wait for it... + expect(await methodCalled, isTrue); }); testWidgets('update', (WidgetTester tester) async { final controller = PolygonController(polygon: polygon); - final options = gmaps.PolygonOptions()..draggable = false; + final options = gmaps.PolygonOptions()..draggable = true; + + expect(polygon.draggable, isNull); + controller.update(options); - verify(polygon.options = options); + + expect(polygon.draggable, isTrue); + }); + + group('remove', () { + late PolygonController controller; + + setUp(() { + controller = PolygonController(polygon: polygon); + }); + + testWidgets('drops gmaps instance', (WidgetTester tester) async { + controller.remove(); + + expect(controller.polygon, isNull); + }); + + testWidgets('cannot call update after remove', + (WidgetTester tester) async { + final options = gmaps.PolygonOptions()..draggable = true; + + controller.remove(); + + expect(() { + controller.update(options); + }, throwsAssertionError); + }); }); }); group('PolylineController', () { - _MockPolyline polyline; + late gmaps.Polyline polyline; setUp(() { - polyline = _MockPolyline(); + polyline = gmaps.Polyline(); }); testWidgets('onTap gets called', (WidgetTester tester) async { PolylineController( polyline: polyline, consumeTapEvents: true, onTap: onTap); - expect(polyline.onClickController.hasListener, isTrue); - // Simulate a click - await polyline.onClickController.add(null); - expect(called, isTrue); + + // Trigger a click event... + gmaps.Event.trigger(polyline, 'click', [gmaps.MapMouseEvent()]); + + // The event handling is now truly async. Wait for it... + expect(await methodCalled, isTrue); }); testWidgets('update', (WidgetTester tester) async { final controller = PolylineController(polyline: polyline); - final options = gmaps.PolylineOptions()..draggable = false; + final options = gmaps.PolylineOptions()..draggable = true; + + expect(polyline.draggable, isNull); + controller.update(options); - verify(polyline.options = options); + + expect(polyline.draggable, isTrue); + }); + + group('remove', () { + late PolylineController controller; + + setUp(() { + controller = PolylineController(polyline: polyline); + }); + + testWidgets('drops gmaps instance', (WidgetTester tester) async { + controller.remove(); + + expect(controller.line, isNull); + }); + + testWidgets('cannot call update after remove', + (WidgetTester tester) async { + final options = gmaps.PolylineOptions()..draggable = true; + + controller.remove(); + + expect(() { + controller.update(options); + }, throwsAssertionError); + }); }); }); } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart index 9bb3599311d2..80b4e0823bb5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart @@ -2,10 +2,9 @@ // 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:ui'; +import 'dart:html' as html; import 'package:integration_test/integration_test.dart'; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; @@ -23,13 +22,20 @@ const _acceptableDelta = 0.01; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + late gmaps.GMap map; + + setUp(() { + map = gmaps.GMap(html.DivElement()); + }); + group('CirclesController', () { - StreamController stream; - CirclesController controller; + late StreamController events; + late CirclesController controller; setUp(() { - stream = StreamController(); - controller = CirclesController(stream: stream); + events = StreamController(); + controller = CirclesController(stream: events); + controller.bindToMap(123, map); }); testWidgets('addCircles', (WidgetTester tester) async { @@ -52,7 +58,7 @@ void main() { }; controller.addCircles(circles); - expect(controller.circles[CircleId('1')].circle.visible, isTrue); + expect(controller.circles[CircleId('1')]?.circle?.visible, isTrue); final updatedCircles = { Circle(circleId: CircleId('1'), visible: false), @@ -60,7 +66,7 @@ void main() { controller.changeCircles(updatedCircles); expect(controller.circles.length, 1); - expect(controller.circles[CircleId('1')].circle.visible, isFalse); + expect(controller.circles[CircleId('1')]?.circle?.visible, isFalse); }); testWidgets('removeCircles', (WidgetTester tester) async { @@ -99,7 +105,7 @@ void main() { controller.addCircles(circles); - final circle = controller.circles.values.first.circle; + final circle = controller.circles.values.first.circle!; expect(circle.get('fillColor'), '#fabada'); expect(circle.get('fillOpacity'), closeTo(0.5, _acceptableDelta)); @@ -109,12 +115,13 @@ void main() { }); group('PolygonsController', () { - StreamController stream; - PolygonsController controller; + late StreamController events; + late PolygonsController controller; setUp(() { - stream = StreamController(); - controller = PolygonsController(stream: stream); + events = StreamController(); + controller = PolygonsController(stream: events); + controller.bindToMap(123, map); }); testWidgets('addPolygons', (WidgetTester tester) async { @@ -137,7 +144,7 @@ void main() { }; controller.addPolygons(polygons); - expect(controller.polygons[PolygonId('1')].polygon.visible, isTrue); + expect(controller.polygons[PolygonId('1')]?.polygon?.visible, isTrue); // Update the polygon final updatedPolygons = { @@ -146,7 +153,7 @@ void main() { controller.changePolygons(updatedPolygons); expect(controller.polygons.length, 1); - expect(controller.polygons[PolygonId('1')].polygon.visible, isFalse); + expect(controller.polygons[PolygonId('1')]?.polygon?.visible, isFalse); }); testWidgets('removePolygons', (WidgetTester tester) async { @@ -185,7 +192,7 @@ void main() { controller.addPolygons(polygons); - final polygon = controller.polygons.values.first.polygon; + final polygon = controller.polygons.values.first.polygon!; expect(polygon.get('fillColor'), '#fabada'); expect(polygon.get('fillOpacity'), closeTo(0.5, _acceptableDelta)); @@ -243,7 +250,7 @@ void main() { final polygon = controller.polygons.values.first.polygon; final pointInHole = gmaps.LatLng(28.632, -68.401); - expect(geometry.poly.containsLocation(pointInHole, polygon), false); + expect(geometry.Poly.containsLocation(pointInHole, polygon), false); }); testWidgets('Hole Path gets reversed to display correctly', @@ -268,25 +275,22 @@ void main() { controller.addPolygons(polygons); - expect( - controller.polygons.values.first.polygon.paths.getAt(1).getAt(0).lat, - 28.745); - expect( - controller.polygons.values.first.polygon.paths.getAt(1).getAt(1).lat, - 29.57); - expect( - controller.polygons.values.first.polygon.paths.getAt(1).getAt(2).lat, - 27.339); + final paths = controller.polygons.values.first.polygon!.paths!; + + expect(paths.getAt(1)?.getAt(0)?.lat, 28.745); + expect(paths.getAt(1)?.getAt(1)?.lat, 29.57); + expect(paths.getAt(1)?.getAt(2)?.lat, 27.339); }); }); group('PolylinesController', () { - StreamController stream; - PolylinesController controller; + late StreamController events; + late PolylinesController controller; setUp(() { - stream = StreamController(); - controller = PolylinesController(stream: stream); + events = StreamController(); + controller = PolylinesController(stream: events); + controller.bindToMap(123, map); }); testWidgets('addPolylines', (WidgetTester tester) async { @@ -309,7 +313,7 @@ void main() { }; controller.addPolylines(polylines); - expect(controller.lines[PolylineId('1')].line.visible, isTrue); + expect(controller.lines[PolylineId('1')]?.line?.visible, isTrue); final updatedPolylines = { Polyline(polylineId: PolylineId('1'), visible: false), @@ -317,7 +321,7 @@ void main() { controller.changePolylines(updatedPolylines); expect(controller.lines.length, 1); - expect(controller.lines[PolylineId('1')].line.visible, isFalse); + expect(controller.lines[PolylineId('1')]?.line?.visible, isFalse); }); testWidgets('removePolylines', (WidgetTester tester) async { @@ -355,7 +359,7 @@ void main() { controller.addPolylines(lines); - final line = controller.lines.values.first.line; + final line = controller.lines.values.first.line!; expect(line.get('strokeColor'), '#fabada'); expect(line.get('strokeOpacity'), closeTo(0.5, _acceptableDelta)); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml index 28955016ab40..311f05a69dc4 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml @@ -1,9 +1,15 @@ name: google_maps_flutter_web_integration_tests publish_to: none +# Tests require flutter beta or greater to run. environment: - sdk: ">=2.2.2 <3.0.0" # Bump this to 2.12 when migrating to nnbd. - flutter: ">=1.27.0-0" # For integration_test from sdk + sdk: ">=2.12.0 <3.0.0" + flutter: ">=2.0.0" + # Actually, Flutter 2.0.0 shipped with a slightly older version of integration_test that + # did *not* support null safety. This flutter constraint should be changed to >=2.1.0 when + # that version (or greater) is shipped to the `stable` channel. + # This causes integration tests to *not* work in `stable`, for now. Please, run integration tests + # in `beta` or newer (flutter/plugins runs these tests in `master`). dependencies: google_maps_flutter_web: @@ -12,12 +18,19 @@ dependencies: sdk: flutter dev_dependencies: - google_maps: ^3.4.4 + build_runner: ^1.11.0 + google_maps: ^5.1.0 http: ^0.13.0 - mockito: ^4.1.1+1 # Update to ^5.0.0 as soon as this migrates to null-safety + mockito: ^5.0.0 flutter_driver: sdk: flutter flutter_test: sdk: flutter integration_test: sdk: flutter + +# Remove these once environment flutter is set to ">=2.1.0". +# Used to reconcile mockito ^5.0.0 with flutter 2.0.x (current stable). +dependency_overrides: + crypto: ^3.0.0 + convert: ^3.0.0 diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/regen_mocks.sh b/packages/google_maps_flutter/google_maps_flutter_web/example/regen_mocks.sh new file mode 100755 index 000000000000..78bcdc0f9e28 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/regen_mocks.sh @@ -0,0 +1,10 @@ +#!/usr/bin/bash +# Copyright 2013 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. + +flutter pub get + +echo "(Re)generating mocks." + +flutter pub run build_runner build --delete-conflicting-outputs diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh b/packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh index aa52974f310e..fcac5f600acb 100755 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/run_test.sh @@ -6,6 +6,8 @@ if pgrep -lf chromedriver > /dev/null; then echo "chromedriver is running." + ./regen_mocks.sh + if [ $# -eq 0 ]; then echo "No target specified, running all tests..." find integration_test/ -iname *_test.dart | xargs -n1 -i -t flutter drive -d web-server --web-port=7357 --browser-name=chrome --driver=test_driver/integration_test.dart --target='{}' diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html index f324d1c7538f..3121d189b913 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/web/index.html @@ -12,4 +12,3 @@ - diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart index 0aa563ccb889..6dc2dab572a6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart @@ -6,6 +6,7 @@ library google_maps_flutter_web; import 'dart:async'; import 'dart:html'; +import 'dart:js_util'; import 'src/shims/dart_ui.dart' as ui; // Conditionally imports dart:ui in web import 'dart:convert'; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart index 84bae1b98e2e..65057d8c869e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart @@ -6,15 +6,15 @@ part of google_maps_flutter_web; /// The `CircleController` class wraps a [gmaps.Circle] and its `onTap` behavior. class CircleController { - gmaps.Circle _circle; + gmaps.Circle? _circle; final bool _consumeTapEvents; /// Creates a `CircleController`, which wraps a [gmaps.Circle] object and its `onTap` behavior. CircleController({ - @required gmaps.Circle circle, + required gmaps.Circle circle, bool consumeTapEvents = false, - ui.VoidCallback onTap, + ui.VoidCallback? onTap, }) : _circle = circle, _consumeTapEvents = consumeTapEvents { if (onTap != null) { @@ -26,21 +26,26 @@ class CircleController { /// Returns the wrapped [gmaps.Circle]. Only used for testing. @visibleForTesting - gmaps.Circle get circle => _circle; + gmaps.Circle? get circle => _circle; /// Returns `true` if this Controller will use its own `onTap` handler to consume events. bool get consumeTapEvents => _consumeTapEvents; /// Updates the options of the wrapped [gmaps.Circle] object. + /// + /// This cannot be called after [remove]. void update(gmaps.CircleOptions options) { - _circle.options = options; + assert(_circle != null, 'Cannot `update` Circle after calling `remove`.'); + _circle!.options = options; } /// Disposes of the currently wrapped [gmaps.Circle]. void remove() { - _circle.visible = false; - _circle.radius = 0; - _circle.map = null; - _circle = null; + if (_circle != null) { + _circle!.visible = false; + _circle!.radius = 0; + _circle!.map = null; + _circle = null; + } } } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart index 659d8ac823a6..2a19d87adfec 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart @@ -14,8 +14,8 @@ class CirclesController extends GeometryController { /// Initialize the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. CirclesController({ - @required StreamController stream, - }) : _streamController = stream, + required StreamController stream, + }) : _streamController = stream, _circleIdToController = Map(); /// Returns the cache of [CircleController]s. Test only. @@ -26,7 +26,7 @@ class CirclesController extends GeometryController { /// /// Wraps each [Circle] into its corresponding [CircleController]. void addCircles(Set circlesToAdd) { - circlesToAdd?.forEach((circle) { + circlesToAdd.forEach((circle) { _addCircle(circle); }); } @@ -50,20 +50,21 @@ class CirclesController extends GeometryController { /// Updates a set of [Circle] objects with new options. void changeCircles(Set circlesToChange) { - circlesToChange?.forEach((circleToChange) { + circlesToChange.forEach((circleToChange) { _changeCircle(circleToChange); }); } void _changeCircle(Circle circle) { - final circleController = _circleIdToController[circle?.circleId]; + final circleController = _circleIdToController[circle.circleId]; circleController?.update(_circleOptionsFromCircle(circle)); } /// Removes a set of [CircleId]s from the cache. void removeCircles(Set circleIdsToRemove) { - circleIdsToRemove?.forEach((circleId) { - final CircleController circleController = _circleIdToController[circleId]; + circleIdsToRemove.forEach((circleId) { + final CircleController? circleController = + _circleIdToController[circleId]; circleController?.remove(); _circleIdToController.remove(circleId); }); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index c875bf782474..2e71c795ff0e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -4,11 +4,10 @@ part of google_maps_flutter_web; -final _nullLatLng = LatLng(0, 0); -final _nullLatLngBounds = LatLngBounds( - northeast: _nullLatLng, - southwest: _nullLatLng, -); +// Default values for when the gmaps objects return null/undefined values. +final _nullGmapsLatLng = gmaps.LatLng(0, 0); +final _nullGmapsLatLngBounds = + gmaps.LatLngBounds(_nullGmapsLatLng, _nullGmapsLatLng); // Defaults taken from the Google Maps Platform SDK documentation. final _defaultCssColor = '#000000'; @@ -115,80 +114,6 @@ bool _isTrafficLayerEnabled(Map rawOptions) { return rawOptions['trafficEnabled'] ?? false; } -// Coverts the incoming JSON object into a List of MapTypeStyler objects. -List _parseStylers(List stylerJsons) { - return stylerJsons?.map((styler) { - return gmaps.MapTypeStyler() - ..color = styler['color'] - ..gamma = styler['gamma'] - ..hue = styler['hue'] - ..invertLightness = styler['invertLightness'] - ..lightness = styler['lightness'] - ..saturation = styler['saturation'] - ..visibility = styler['visibility'] - ..weight = styler['weight']; - })?.toList(); -} - -// Converts a String to its corresponding MapTypeStyleElementType enum value. -final _elementTypeToEnum = { - 'all': gmaps.MapTypeStyleElementType.ALL, - 'geometry': gmaps.MapTypeStyleElementType.GEOMETRY, - 'geometry.fill': gmaps.MapTypeStyleElementType.GEOMETRY_FILL, - 'geometry.stroke': gmaps.MapTypeStyleElementType.GEOMETRY_STROKE, - 'labels': gmaps.MapTypeStyleElementType.LABELS, - 'labels.icon': gmaps.MapTypeStyleElementType.LABELS_ICON, - 'labels.text': gmaps.MapTypeStyleElementType.LABELS_TEXT, - 'labels.text.fill': gmaps.MapTypeStyleElementType.LABELS_TEXT_FILL, - 'labels.text.stroke': gmaps.MapTypeStyleElementType.LABELS_TEXT_STROKE, -}; - -// Converts a String to its corresponding MapTypeStyleFeatureType enum value. -final _featureTypeToEnum = { - 'administrative': gmaps.MapTypeStyleFeatureType.ADMINISTRATIVE, - 'administrative.country': - gmaps.MapTypeStyleFeatureType.ADMINISTRATIVE_COUNTRY, - 'administrative.land_parcel': - gmaps.MapTypeStyleFeatureType.ADMINISTRATIVE_LAND_PARCEL, - 'administrative.locality': - gmaps.MapTypeStyleFeatureType.ADMINISTRATIVE_LOCALITY, - 'administrative.neighborhood': - gmaps.MapTypeStyleFeatureType.ADMINISTRATIVE_NEIGHBORHOOD, - 'administrative.province': - gmaps.MapTypeStyleFeatureType.ADMINISTRATIVE_PROVINCE, - 'all': gmaps.MapTypeStyleFeatureType.ALL, - 'landscape': gmaps.MapTypeStyleFeatureType.LANDSCAPE, - 'landscape.man_made': gmaps.MapTypeStyleFeatureType.LANDSCAPE_MAN_MADE, - 'landscape.natural': gmaps.MapTypeStyleFeatureType.LANDSCAPE_NATURAL, - 'landscape.natural.landcover': - gmaps.MapTypeStyleFeatureType.LANDSCAPE_NATURAL_LANDCOVER, - 'landscape.natural.terrain': - gmaps.MapTypeStyleFeatureType.LANDSCAPE_NATURAL_TERRAIN, - 'poi': gmaps.MapTypeStyleFeatureType.POI, - 'poi.attraction': gmaps.MapTypeStyleFeatureType.POI_ATTRACTION, - 'poi.business': gmaps.MapTypeStyleFeatureType.POI_BUSINESS, - 'poi.government': gmaps.MapTypeStyleFeatureType.POI_GOVERNMENT, - 'poi.medical': gmaps.MapTypeStyleFeatureType.POI_MEDICAL, - 'poi.park': gmaps.MapTypeStyleFeatureType.POI_PARK, - 'poi.place_of_worship': gmaps.MapTypeStyleFeatureType.POI_PLACE_OF_WORSHIP, - 'poi.school': gmaps.MapTypeStyleFeatureType.POI_SCHOOL, - 'poi.sports_complex': gmaps.MapTypeStyleFeatureType.POI_SPORTS_COMPLEX, - 'road': gmaps.MapTypeStyleFeatureType.ROAD, - 'road.arterial': gmaps.MapTypeStyleFeatureType.ROAD_ARTERIAL, - 'road.highway': gmaps.MapTypeStyleFeatureType.ROAD_HIGHWAY, - 'road.highway.controlled_access': - gmaps.MapTypeStyleFeatureType.ROAD_HIGHWAY_CONTROLLED_ACCESS, - 'road.local': gmaps.MapTypeStyleFeatureType.ROAD_LOCAL, - 'transit': gmaps.MapTypeStyleFeatureType.TRANSIT, - 'transit.line': gmaps.MapTypeStyleFeatureType.TRANSIT_LINE, - 'transit.station': gmaps.MapTypeStyleFeatureType.TRANSIT_STATION, - 'transit.station.airport': - gmaps.MapTypeStyleFeatureType.TRANSIT_STATION_AIRPORT, - 'transit.station.bus': gmaps.MapTypeStyleFeatureType.TRANSIT_STATION_BUS, - 'transit.station.rail': gmaps.MapTypeStyleFeatureType.TRANSIT_STATION_RAIL, - 'water': gmaps.MapTypeStyleFeatureType.WATER, -}; - // The keys we'd expect to see in a serialized MapTypeStyle JSON object. final _mapStyleKeys = { 'elementType', @@ -202,37 +127,36 @@ bool _isJsonMapStyle(Map value) { } // Converts an incoming JSON-encoded Style info, into the correct gmaps array. -List _mapStyles(String mapStyleJson) { +List _mapStyles(String? mapStyleJson) { List styles = []; if (mapStyleJson != null) { - styles = json.decode(mapStyleJson, reviver: (key, value) { - if (value is Map && _isJsonMapStyle(value)) { - return gmaps.MapTypeStyle() - ..elementType = _elementTypeToEnum[value['elementType']] - ..featureType = _featureTypeToEnum[value['featureType']] - ..stylers = _parseStylers(value['stylers']); - } - return value; - }).cast(); + styles = json + .decode(mapStyleJson, reviver: (key, value) { + if (value is Map && _isJsonMapStyle(value)) { + return gmaps.MapTypeStyle() + ..elementType = value['elementType'] + ..featureType = value['featureType'] + ..stylers = + (value['stylers'] as List).map((e) => jsify(e)).toList(); + } + return value; + }) + .cast() + .toList(); + // .toList calls are required so the JS API understands the underlying data structure. } return styles; } gmaps.LatLng _latLngToGmLatLng(LatLng latLng) { - if (latLng == null) return null; return gmaps.LatLng(latLng.latitude, latLng.longitude); } LatLng _gmLatLngToLatLng(gmaps.LatLng latLng) { - if (latLng == null) return _nullLatLng; - return LatLng(latLng.lat, latLng.lng); + return LatLng(latLng.lat.toDouble(), latLng.lng.toDouble()); } LatLngBounds _gmLatLngBoundsTolatLngBounds(gmaps.LatLngBounds latLngBounds) { - if (latLngBounds == null) { - return _nullLatLngBounds; - } - return LatLngBounds( southwest: _gmLatLngToLatLng(latLngBounds.southWest), northeast: _gmLatLngToLatLng(latLngBounds.northEast), @@ -241,10 +165,10 @@ LatLngBounds _gmLatLngBoundsTolatLngBounds(gmaps.LatLngBounds latLngBounds) { CameraPosition _gmViewportToCameraPosition(gmaps.GMap map) { return CameraPosition( - target: _gmLatLngToLatLng(map.center), - bearing: map.heading ?? 0, - tilt: map.tilt ?? 0, - zoom: map.zoom?.toDouble() ?? 10, + target: _gmLatLngToLatLng(map.center ?? _nullGmapsLatLng), + bearing: map.heading?.toDouble() ?? 0, + tilt: map.tilt?.toDouble() ?? 0, + zoom: map.zoom?.toDouble() ?? 0, ); } @@ -252,9 +176,13 @@ CameraPosition _gmViewportToCameraPosition(gmaps.GMap map) { // TODO: Move to their appropriate objects, maybe make these copy constructors: // Marker.fromMarker(anotherMarker, moreOptions); -gmaps.InfoWindowOptions _infoWindowOptionsFromMarker(Marker marker) { - if ((marker.infoWindow?.title?.isEmpty ?? true) && - (marker.infoWindow?.snippet?.isEmpty ?? true)) { +gmaps.InfoWindowOptions? _infoWindowOptionsFromMarker(Marker marker) { + final markerTitle = marker.infoWindow.title ?? ''; + final markerSnippet = marker.infoWindow.snippet ?? ''; + + // If both the title and snippet of an infowindow are empty, we don't really + // want an infowindow... + if ((markerTitle.isEmpty) && (markerSnippet.isEmpty)) { return null; } @@ -262,17 +190,18 @@ gmaps.InfoWindowOptions _infoWindowOptionsFromMarker(Marker marker) { // to click events... final HtmlElement container = DivElement() ..id = 'gmaps-marker-${marker.markerId.value}-infowindow'; - if (marker.infoWindow.title?.isNotEmpty ?? false) { + + if (markerTitle.isNotEmpty) { final HtmlElement title = HeadingElement.h3() ..className = 'infowindow-title' - ..innerText = marker.infoWindow.title; + ..innerText = markerTitle; container.children.add(title); } - if (marker.infoWindow.snippet?.isNotEmpty ?? false) { + if (markerSnippet.isNotEmpty) { final HtmlElement snippet = DivElement() ..className = 'infowindow-snippet' ..setInnerHtml( - sanitizeHtml(marker.infoWindow.snippet), + sanitizeHtml(markerSnippet), treeSanitizer: NodeTreeSanitizer.trusted, ); container.children.add(snippet); @@ -290,10 +219,10 @@ gmaps.InfoWindowOptions _infoWindowOptionsFromMarker(Marker marker) { // Preserves the position from the [currentMarker], if set. gmaps.MarkerOptions _markerOptionsFromMarker( Marker marker, - gmaps.Marker currentMarker, + gmaps.Marker? currentMarker, ) { - final iconConfig = marker.icon?.toJson() as List; - gmaps.Icon icon; + final iconConfig = marker.icon.toJson() as List; + gmaps.Icon? icon; if (iconConfig != null) { if (iconConfig[0] == 'fromAssetImage') { @@ -324,7 +253,7 @@ gmaps.MarkerOptions _markerOptionsFromMarker( marker.position.latitude, marker.position.longitude, ) - ..title = sanitizeHtml(marker.infoWindow?.title ?? "") + ..title = sanitizeHtml(marker.infoWindow.title ?? "") ..zIndex = marker.zIndex ..visible = marker.visible ..opacity = marker.alpha @@ -356,7 +285,7 @@ gmaps.PolygonOptions _polygonOptionsFromPolygon( final polygonDirection = _isPolygonClockwise(path); List> paths = [path]; int holeIndex = 0; - polygon.holes?.forEach((hole) { + polygon.holes.forEach((hole) { List holePath = hole.map((point) => _latLngToGmLatLng(point)).toList(); if (_isPolygonClockwise(holePath) == polygonDirection) { @@ -387,6 +316,13 @@ gmaps.PolygonOptions _polygonOptionsFromPolygon( /// based on: https://stackoverflow.com/a/1165943 /// /// returns [true] if clockwise [false] if counterclockwise +/// +/// This method expects that the incoming [path] is a `List` of well-formed, +/// non-null [gmaps.LatLng] objects. +/// +/// Currently, this method is only called from [_polygonOptionsFromPolygon], and +/// the `path` is a transformed version of [Polygon.points] or each of the +/// [Polygon.holes], guaranteeing that `lat` and `lng` can be accessed with `!`. bool _isPolygonClockwise(List path) { var direction = 0.0; for (var i = 0; i < path.length; i++) { @@ -447,7 +383,7 @@ void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) { map.panBy(json[1], json[2]); break; case 'zoomBy': - gmaps.LatLng focusLatLng; + gmaps.LatLng? focusLatLng; double zoomDelta = json[1] ?? 0; // Web only supports integer changes... int newZoomDelta = zoomDelta < 0 ? zoomDelta.floor() : zoomDelta.ceil(); @@ -460,16 +396,16 @@ void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) { // print('Error computing new focus LatLng. JS Error: ' + e.toString()); } } - map.zoom = map.zoom + newZoomDelta; + map.zoom = (map.zoom ?? 0) + newZoomDelta; if (focusLatLng != null) { map.panTo(focusLatLng); } break; case 'zoomIn': - map.zoom++; + map.zoom = (map.zoom ?? 0) + 1; break; case 'zoomOut': - map.zoom--; + map.zoom = (map.zoom ?? 0) - 1; break; case 'zoomTo': map.zoom = json[1]; @@ -481,17 +417,27 @@ void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) { // original JS by: Byron Singh (https://stackoverflow.com/a/30541162) gmaps.LatLng _pixelToLatLng(gmaps.GMap map, int x, int y) { - final ne = map.bounds.northEast; - final sw = map.bounds.southWest; + final bounds = map.bounds; final projection = map.projection; + final zoom = map.zoom; + + assert( + bounds != null, 'Map Bounds required to compute LatLng of screen x/y.'); + assert(projection != null, + 'Map Projection required to compute LatLng of screen x/y'); + assert(zoom != null, + 'Current map zoom level required to compute LatLng of screen x/y'); + + final ne = bounds!.northEast; + final sw = bounds.southWest; - final topRight = projection.fromLatLngToPoint(ne); - final bottomLeft = projection.fromLatLngToPoint(sw); + final topRight = projection!.fromLatLngToPoint!(ne)!; + final bottomLeft = projection.fromLatLngToPoint!(sw)!; - final scale = 1 << map.zoom; // 2 ^ zoom + final scale = 1 << (zoom!.toInt()); // 2 ^ zoom final point = - gmaps.Point((x / scale) + bottomLeft.x, (y / scale) + topRight.y); + gmaps.Point((x / scale) + bottomLeft.x!, (y / scale) + topRight.y!); - return projection.fromPointToLatLng(point); + return projection.fromPointToLatLng!(point)!; } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index cc8d79a6226d..25284909d596 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -27,11 +27,11 @@ class GoogleMapController { String _getViewType(int mapId) => 'plugins.flutter.io/google_maps_$mapId'; // The Flutter widget that contains the rendered Map. - HtmlElementView _widget; - HtmlElement _div; + HtmlElementView? _widget; + late HtmlElement _div; /// The Flutter widget that will contain the rendered Map. Used for caching. - HtmlElementView get widget { + Widget? get widget { if (_widget == null && !_streamController.isClosed) { _widget = HtmlElementView( viewType: _getViewType(_mapId), @@ -41,14 +41,14 @@ class GoogleMapController { } // The currently-enabled traffic layer. - gmaps.TrafficLayer _trafficLayer; + gmaps.TrafficLayer? _trafficLayer; /// A getter for the current traffic layer. Only for tests. @visibleForTesting - gmaps.TrafficLayer get trafficLayer => _trafficLayer; + gmaps.TrafficLayer? get trafficLayer => _trafficLayer; // The underlying GMap instance. This is the interface with the JS SDK. - gmaps.GMap _googleMap; + gmaps.GMap? _googleMap; // The StreamController used by this controller and the geometry ones. final StreamController _streamController; @@ -57,10 +57,10 @@ class GoogleMapController { Stream get events => _streamController.stream; // Geometry controllers, for different features of the map. - CirclesController _circlesController; - PolygonsController _polygonsController; - PolylinesController _polylinesController; - MarkersController _markersController; + CirclesController? _circlesController; + PolygonsController? _polygonsController; + PolylinesController? _polylinesController; + MarkersController? _markersController; // Keeps track if _attachGeometryControllers has been called or not. bool _controllersBoundToMap = false; @@ -69,9 +69,9 @@ class GoogleMapController { /// Initializes the GMap, and the sub-controllers related to it. Wires events. GoogleMapController({ - @required int mapId, - @required StreamController streamController, - @required CameraPosition initialCameraPosition, + required int mapId, + required StreamController streamController, + required CameraPosition initialCameraPosition, Set markers = const {}, Set polygons = const {}, Set polylines = const {}, @@ -107,11 +107,11 @@ class GoogleMapController { /// Overrides certain properties to install mocks defined during testing. @visibleForTesting void debugSetOverrides({ - DebugCreateMapFunction createMap, - MarkersController markers, - CirclesController circles, - PolygonsController polygons, - PolylinesController polylines, + DebugCreateMapFunction? createMap, + MarkersController? markers, + CirclesController? circles, + PolygonsController? polygons, + PolylinesController? polylines, }) { _overrideCreateMap = createMap; _markersController = markers ?? _markersController; @@ -120,11 +120,11 @@ class GoogleMapController { _polylinesController = polylines ?? _polylinesController; } - DebugCreateMapFunction _overrideCreateMap; + DebugCreateMapFunction? _overrideCreateMap; gmaps.GMap _createMap(HtmlElement div, gmaps.MapOptions options) { if (_overrideCreateMap != null) { - return _overrideCreateMap(div, options); + return _overrideCreateMap!(div, options); } return gmaps.GMap(div, options); } @@ -142,10 +142,11 @@ class GoogleMapController { options = _applyInitialPosition(_initialCameraPosition, options); // Create the map... - _googleMap = _createMap(_div, options); + final map = _createMap(_div, options); + _googleMap = map; - _attachMapEvents(_googleMap); - _attachGeometryControllers(_googleMap); + _attachMapEvents(map); + _attachGeometryControllers(map); _renderInitialGeometry( markers: _markers, @@ -154,19 +155,21 @@ class GoogleMapController { polylines: _polylines, ); - _setTrafficLayer(_googleMap, _isTrafficLayerEnabled(_rawMapOptions)); + _setTrafficLayer(map, _isTrafficLayerEnabled(_rawMapOptions)); } // Funnels map gmap events into the plugin's stream controller. void _attachMapEvents(gmaps.GMap map) { map.onClick.listen((event) { + assert(event.latLng != null); _streamController.add( - MapTapEvent(_mapId, _gmLatLngToLatLng(event.latLng)), + MapTapEvent(_mapId, _gmLatLngToLatLng(event.latLng!)), ); }); map.onRightclick.listen((event) { + assert(event.latLng != null); _streamController.add( - MapLongPressEvent(_mapId, _gmLatLngToLatLng(event.latLng)), + MapLongPressEvent(_mapId, _gmLatLngToLatLng(event.latLng!)), ); }); map.onBoundsChanged.listen((event) { @@ -188,28 +191,47 @@ class GoogleMapController { void _attachGeometryControllers(gmaps.GMap map) { // Now we can add the initial geometry. // And bind the (ready) map instance to the other geometry controllers. - _circlesController.bindToMap(_mapId, map); - _polygonsController.bindToMap(_mapId, map); - _polylinesController.bindToMap(_mapId, map); - _markersController.bindToMap(_mapId, map); + // + // These controllers are either created in the constructor of this class, or + // overriden (for testing) by the [debugSetOverrides] method. They can't be + // null. + assert(_circlesController != null, + 'Cannot attach a map to a null CirclesController instance.'); + assert(_polygonsController != null, + 'Cannot attach a map to a null PolygonsController instance.'); + assert(_polylinesController != null, + 'Cannot attach a map to a null PolylinesController instance.'); + assert(_markersController != null, + 'Cannot attach a map to a null MarkersController instance.'); + + _circlesController!.bindToMap(_mapId, map); + _polygonsController!.bindToMap(_mapId, map); + _polylinesController!.bindToMap(_mapId, map); + _markersController!.bindToMap(_mapId, map); + _controllersBoundToMap = true; } // Renders the initial sets of geometry. void _renderInitialGeometry({ - Set markers, - Set circles, - Set polygons, - Set polylines, + Set markers = const {}, + Set circles = const {}, + Set polygons = const {}, + Set polylines = const {}, }) { assert( _controllersBoundToMap, 'Geometry controllers must be bound to a map before any geometry can ' + 'be added to them. Ensure _attachGeometryControllers is called first.'); - _markersController.addMarkers(markers); - _circlesController.addCircles(circles); - _polygonsController.addPolygons(polygons); - _polylinesController.addPolylines(polylines); + + // The above assert will only succeed if the controllers have been bound to a map + // in the [_attachGeometryControllers] method, which ensures that all these + // controllers below are *not* null. + + _markersController!.addMarkers(markers); + _circlesController!.addCircles(circles); + _polygonsController!.addPolygons(polygons); + _polylinesController!.addPolylines(polylines); } // Merges new options coming from the plugin into the _rawMapOptions map. @@ -227,10 +249,12 @@ class GoogleMapController { /// /// This method converts the map into the proper [gmaps.MapOptions] void updateRawOptions(Map optionsUpdate) { + assert(_googleMap != null, 'Cannot update options on a null map.'); + final newOptions = _mergeRawOptions(optionsUpdate); _setOptions(_rawOptionsToGmapsOptions(newOptions)); - _setTrafficLayer(_googleMap, _isTrafficLayerEnabled(newOptions)); + _setTrafficLayer(_googleMap!, _isTrafficLayerEnabled(newOptions)); } // Sets new [gmaps.MapOptions] on the wrapped map. @@ -241,11 +265,10 @@ class GoogleMapController { // Attaches/detaches a Traffic Layer on the passed `map` if `attach` is true/false. void _setTrafficLayer(gmaps.GMap map, bool attach) { if (attach && _trafficLayer == null) { - _trafficLayer = gmaps.TrafficLayer(); - _trafficLayer.set('map', map); + _trafficLayer = gmaps.TrafficLayer()..set('map', map); } if (!attach && _trafficLayer != null) { - _trafficLayer.set('map', null); + _trafficLayer!.set('map', null); _trafficLayer = null; } } @@ -255,35 +278,61 @@ class GoogleMapController { /// Returns the [LatLngBounds] of the current viewport. Future getVisibleRegion() async { - return _gmLatLngBoundsTolatLngBounds(await _googleMap.bounds); + assert(_googleMap != null, 'Cannot get the visible region of a null map.'); + + return _gmLatLngBoundsTolatLngBounds( + await _googleMap!.bounds ?? _nullGmapsLatLngBounds, + ); } /// Returns the [ScreenCoordinate] for a given viewport [LatLng]. Future getScreenCoordinate(LatLng latLng) async { + assert(_googleMap != null, + 'Cannot get the screen coordinates with a null map.'); + assert(_googleMap!.projection != null, + 'Cannot compute screen coordinate with a null map or projection.'); + final point = - _googleMap.projection.fromLatLngToPoint(_latLngToGmLatLng(latLng)); - return ScreenCoordinate(x: point.x, y: point.y); + _googleMap!.projection!.fromLatLngToPoint!(_latLngToGmLatLng(latLng))!; + + assert(point.x != null && point.y != null, + 'The x and y of a ScreenCoordinate cannot be null.'); + + return ScreenCoordinate(x: point.x!.toInt(), y: point.y!.toInt()); } /// Returns the [LatLng] for a `screenCoordinate` (in pixels) of the viewport. Future getLatLng(ScreenCoordinate screenCoordinate) async { + assert(_googleMap != null, + 'Cannot get the lat, lng of a screen coordinate with a null map.'); + final gmaps.LatLng latLng = - _pixelToLatLng(_googleMap, screenCoordinate.x, screenCoordinate.y); + _pixelToLatLng(_googleMap!, screenCoordinate.x, screenCoordinate.y); return _gmLatLngToLatLng(latLng); } /// Applies a `cameraUpdate` to the current viewport. Future moveCamera(CameraUpdate cameraUpdate) async { - return _applyCameraUpdate(_googleMap, cameraUpdate); + assert(_googleMap != null, 'Cannot update the camera of a null map.'); + + return _applyCameraUpdate(_googleMap!, cameraUpdate); } /// Returns the zoom level of the current viewport. - Future getZoomLevel() async => _googleMap.zoom.toDouble(); + Future getZoomLevel() async { + assert(_googleMap != null, 'Cannot get zoom level of a null map.'); + assert(_googleMap!.zoom != null, + 'Zoom level should not be null. Is the map correctly initialized?'); + + return _googleMap!.zoom!.toDouble(); + } // Geometry manipulation /// Applies [CircleUpdates] to the currently managed circles. void updateCircles(CircleUpdates updates) { + assert( + _circlesController != null, 'Cannot update circles after dispose().'); _circlesController?.addCircles(updates.circlesToAdd); _circlesController?.changeCircles(updates.circlesToChange); _circlesController?.removeCircles(updates.circleIdsToRemove); @@ -291,6 +340,8 @@ class GoogleMapController { /// Applies [PolygonUpdates] to the currently managed polygons. void updatePolygons(PolygonUpdates updates) { + assert( + _polygonsController != null, 'Cannot update polygons after dispose().'); _polygonsController?.addPolygons(updates.polygonsToAdd); _polygonsController?.changePolygons(updates.polygonsToChange); _polygonsController?.removePolygons(updates.polygonIdsToRemove); @@ -298,6 +349,8 @@ class GoogleMapController { /// Applies [PolylineUpdates] to the currently managed lines. void updatePolylines(PolylineUpdates updates) { + assert(_polylinesController != null, + 'Cannot update polylines after dispose().'); _polylinesController?.addPolylines(updates.polylinesToAdd); _polylinesController?.changePolylines(updates.polylinesToChange); _polylinesController?.removePolylines(updates.polylineIdsToRemove); @@ -305,6 +358,8 @@ class GoogleMapController { /// Applies [MarkerUpdates] to the currently managed markers. void updateMarkers(MarkerUpdates updates) { + assert( + _markersController != null, 'Cannot update markers after dispose().'); _markersController?.addMarkers(updates.markersToAdd); _markersController?.changeMarkers(updates.markersToChange); _markersController?.removeMarkers(updates.markerIdsToRemove); @@ -312,22 +367,29 @@ class GoogleMapController { /// Shows the [InfoWindow] of the marker identified by its [MarkerId]. void showInfoWindow(MarkerId markerId) { + assert(_markersController != null, + 'Cannot show infowindow of marker [${markerId.value}] after dispose().'); _markersController?.showMarkerInfoWindow(markerId); } /// Hides the [InfoWindow] of the marker identified by its [MarkerId]. void hideInfoWindow(MarkerId markerId) { + assert(_markersController != null, + 'Cannot hide infowindow of marker [${markerId.value}] after dispose().'); _markersController?.hideMarkerInfoWindow(markerId); } /// Returns true if the [InfoWindow] of the marker identified by [MarkerId] is shown. bool isInfoWindowShown(MarkerId markerId) { - return _markersController?.isInfoWindowShown(markerId); + return _markersController?.isInfoWindowShown(markerId) ?? false; } // Cleanup /// Disposes of this controller and its resources. + /// + /// You won't be able to call many of the methods on this controller after + /// calling `dispose`! void dispose() { _widget = null; _googleMap = null; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart index 5e95a538c07a..692917fef4da 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart @@ -45,7 +45,7 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { @override Future updateMapOptions( Map optionsUpdate, { - @required int mapId, + required int mapId, }) async { _map(mapId).updateRawOptions(optionsUpdate); } @@ -54,7 +54,7 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { @override Future updateMarkers( MarkerUpdates markerUpdates, { - @required int mapId, + required int mapId, }) async { _map(mapId).updateMarkers(markerUpdates); } @@ -63,7 +63,7 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { @override Future updatePolygons( PolygonUpdates polygonUpdates, { - @required int mapId, + required int mapId, }) async { _map(mapId).updatePolygons(polygonUpdates); } @@ -72,7 +72,7 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { @override Future updatePolylines( PolylineUpdates polylineUpdates, { - @required int mapId, + required int mapId, }) async { _map(mapId).updatePolylines(polylineUpdates); } @@ -81,15 +81,15 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { @override Future updateCircles( CircleUpdates circleUpdates, { - @required int mapId, + required int mapId, }) async { _map(mapId).updateCircles(circleUpdates); } @override Future updateTileOverlays({ - @required Set newTileOverlays, - @required int mapId, + required Set newTileOverlays, + required int mapId, }) async { return; // Noop for now! } @@ -97,7 +97,7 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { @override Future clearTileCache( TileOverlayId tileOverlayId, { - @required int mapId, + required int mapId, }) async { return; // Noop for now! } @@ -106,7 +106,7 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { @override Future animateCamera( CameraUpdate cameraUpdate, { - @required int mapId, + required int mapId, }) async { return moveCamera(cameraUpdate, mapId: mapId); } @@ -115,7 +115,7 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { @override Future moveCamera( CameraUpdate cameraUpdate, { - @required int mapId, + required int mapId, }) async { return _map(mapId).moveCamera(cameraUpdate); } @@ -128,8 +128,8 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { /// pass full styles. @override Future setMapStyle( - String mapStyle, { - @required int mapId, + String? mapStyle, { + required int mapId, }) async { _map(mapId).updateRawOptions({ 'styles': _mapStyles(mapStyle), @@ -139,7 +139,7 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { /// Returns the bounds of the current viewport. @override Future getVisibleRegion({ - @required int mapId, + required int mapId, }) { return _map(mapId).getVisibleRegion(); } @@ -148,7 +148,7 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { @override Future getScreenCoordinate( LatLng latLng, { - @required int mapId, + required int mapId, }) { return _map(mapId).getScreenCoordinate(latLng); } @@ -157,7 +157,7 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { @override Future getLatLng( ScreenCoordinate screenCoordinate, { - @required int mapId, + required int mapId, }) { return _map(mapId).getLatLng(screenCoordinate); } @@ -170,7 +170,7 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { @override Future showMarkerInfoWindow( MarkerId markerId, { - @required int mapId, + required int mapId, }) async { _map(mapId).showInfoWindow(markerId); } @@ -183,7 +183,7 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { @override Future hideMarkerInfoWindow( MarkerId markerId, { - @required int mapId, + required int mapId, }) async { _map(mapId).hideInfoWindow(markerId); } @@ -196,7 +196,7 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { @override Future isMarkerInfoWindowShown( MarkerId markerId, { - @required int mapId, + required int mapId, }) async { return _map(mapId).isInfoWindowShown(markerId); } @@ -204,7 +204,7 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { /// Returns the zoom level of the `mapId`. @override Future getZoomLevel({ - @required int mapId, + required int mapId, }) { return _map(mapId).getZoomLevel(); } @@ -213,64 +213,64 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { // into the plugin @override - Stream onCameraMoveStarted({@required int mapId}) { + Stream onCameraMoveStarted({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onCameraMove({@required int mapId}) { + Stream onCameraMove({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onCameraIdle({@required int mapId}) { + Stream onCameraIdle({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onMarkerTap({@required int mapId}) { + Stream onMarkerTap({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onInfoWindowTap({@required int mapId}) { + Stream onInfoWindowTap({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onMarkerDragEnd({@required int mapId}) { + Stream onMarkerDragEnd({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onPolylineTap({@required int mapId}) { + Stream onPolylineTap({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onPolygonTap({@required int mapId}) { + Stream onPolygonTap({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onCircleTap({@required int mapId}) { + Stream onCircleTap({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onTap({@required int mapId}) { + Stream onTap({required int mapId}) { return _events(mapId).whereType(); } @override - Stream onLongPress({@required int mapId}) { + Stream onLongPress({required int mapId}) { return _events(mapId).whereType(); } /// Disposes of the current map. It can't be used afterwards! @override - void dispose({@required int mapId}) { - _map(mapId)?.dispose(); + void dispose({required int mapId}) { + _map(mapId).dispose(); _mapById.remove(mapId); } @@ -278,19 +278,16 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { Widget buildView( int creationId, PlatformViewCreatedCallback onPlatformViewCreated, { - @required CameraPosition initialCameraPosition, + required CameraPosition initialCameraPosition, Set markers = const {}, Set polygons = const {}, Set polylines = const {}, Set circles = const {}, Set tileOverlays = const {}, - Set> gestureRecognizers = + Set>? gestureRecognizers = const >{}, Map mapOptions = const {}, }) { - assert(creationId != null, - 'buildView needs a `_webOnlyMapCreationId` in its creationParams to prevent widget reloads in web.'); - // Bail fast if we've already rendered this map ID... if (_mapById[creationId]?.widget != null) { return _mapById[creationId].widget; @@ -314,6 +311,9 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { onPlatformViewCreated.call(creationId); - return mapController.widget; + assert(mapController.widget != null, + 'The widget of a GoogleMapController cannot be null before calling dispose on it.'); + + return mapController.widget!; } } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart index 62238fc2d86b..5b0169b565e5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart @@ -6,33 +6,35 @@ part of google_maps_flutter_web; /// The `MarkerController` class wraps a [gmaps.Marker], how it handles events, and its associated (optional) [gmaps.InfoWindow] widget. class MarkerController { - gmaps.Marker _marker; + gmaps.Marker? _marker; final bool _consumeTapEvents; - final gmaps.InfoWindow _infoWindow; + final gmaps.InfoWindow? _infoWindow; bool _infoWindowShown = false; /// Creates a `MarkerController`, which wraps a [gmaps.Marker] object, its `onTap`/`onDrag` behavior, and its associated [gmaps.InfoWindow]. MarkerController({ - @required gmaps.Marker marker, - gmaps.InfoWindow infoWindow, + required gmaps.Marker marker, + gmaps.InfoWindow? infoWindow, bool consumeTapEvents = false, - LatLngCallback onDragEnd, - ui.VoidCallback onTap, + LatLngCallback? onDragEnd, + ui.VoidCallback? onTap, }) : _marker = marker, _infoWindow = infoWindow, _consumeTapEvents = consumeTapEvents { if (onTap != null) { - _marker.onClick.listen((event) { + marker.onClick.listen((event) { onTap.call(); }); } if (onDragEnd != null) { - _marker.onDragend.listen((event) { - _marker.position = event.latLng; - onDragEnd.call(event.latLng); + marker.onDragend.listen((event) { + if (marker != null) { + marker.position = event.latLng; + } + onDragEnd.call(event.latLng ?? _nullGmapsLatLng); }); } } @@ -44,42 +46,54 @@ class MarkerController { bool get infoWindowShown => _infoWindowShown; /// Returns the [gmaps.Marker] associated to this controller. - gmaps.Marker get marker => _marker; + gmaps.Marker? get marker => _marker; /// Returns the [gmaps.InfoWindow] associated to the marker. @visibleForTesting - gmaps.InfoWindow get infoWindow => _infoWindow; + gmaps.InfoWindow? get infoWindow => _infoWindow; /// Updates the options of the wrapped [gmaps.Marker] object. + /// + /// This cannot be called after [remove]. void update( gmaps.MarkerOptions options, { - String newInfoWindowContent, + HtmlElement? newInfoWindowContent, }) { - _marker.options = options; + assert(_marker != null, 'Cannot `update` Marker after calling `remove`.'); + _marker!.options = options; if (_infoWindow != null && newInfoWindowContent != null) { - _infoWindow.content = newInfoWindowContent; + _infoWindow!.content = newInfoWindowContent; } } /// Disposes of the currently wrapped [gmaps.Marker]. void remove() { - _marker.visible = false; - _marker.map = null; - _marker = null; + if (_marker != null) { + _infoWindowShown = false; + _marker!.visible = false; + _marker!.map = null; + _marker = null; + } } /// Hide the associated [gmaps.InfoWindow]. + /// + /// This cannot be called after [remove]. void hideInfoWindow() { + assert(_marker != null, 'Cannot `hideInfoWindow` on a `remove`d Marker.'); if (_infoWindow != null) { - _infoWindow.close(); + _infoWindow!.close(); _infoWindowShown = false; } } /// Show the associated [gmaps.InfoWindow]. + /// + /// This cannot be called after [remove]. void showInfoWindow() { + assert(_marker != null, 'Cannot `showInfoWindow` on a `remove`d Marker.'); if (_infoWindow != null) { - _infoWindow.open(_marker.map, _marker); + _infoWindow!.open(_marker!.map, _marker); _infoWindowShown = true; } } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart index bc9827a20270..704577b6e3fb 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart @@ -14,8 +14,8 @@ class MarkersController extends GeometryController { /// Initialize the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. MarkersController({ - @required StreamController stream, - }) : _streamController = stream, + required StreamController stream, + }) : _streamController = stream, _markerIdToController = Map(); /// Returns the cache of [MarkerController]s. Test only. @@ -26,7 +26,7 @@ class MarkersController extends GeometryController { /// /// Wraps each [Marker] into its corresponding [MarkerController]. void addMarkers(Set markersToAdd) { - markersToAdd?.forEach(_addMarker); + markersToAdd.forEach(_addMarker); } void _addMarker(Marker marker) { @@ -35,14 +35,15 @@ class MarkersController extends GeometryController { } final infoWindowOptions = _infoWindowOptionsFromMarker(marker); - gmaps.InfoWindow gmInfoWindow; + gmaps.InfoWindow? gmInfoWindow; if (infoWindowOptions != null) { gmInfoWindow = gmaps.InfoWindow(infoWindowOptions); // Google Maps' JS SDK does not have a click event on the InfoWindow, so // we make one... if (infoWindowOptions.content is HtmlElement) { - infoWindowOptions.content.onClick.listen((_) { + final content = infoWindowOptions.content as HtmlElement; + content.onClick.listen((_) { _onInfoWindowTap(marker.markerId); }); } @@ -70,11 +71,11 @@ class MarkersController extends GeometryController { /// Updates a set of [Marker] objects with new options. void changeMarkers(Set markersToChange) { - markersToChange?.forEach(_changeMarker); + markersToChange.forEach(_changeMarker); } void _changeMarker(Marker marker) { - MarkerController markerController = _markerIdToController[marker?.markerId]; + MarkerController? markerController = _markerIdToController[marker.markerId]; if (markerController != null) { final markerOptions = _markerOptionsFromMarker( marker, @@ -83,18 +84,18 @@ class MarkersController extends GeometryController { final infoWindow = _infoWindowOptionsFromMarker(marker); markerController.update( markerOptions, - newInfoWindowContent: infoWindow?.content, + newInfoWindowContent: infoWindow?.content as HtmlElement?, ); } } /// Removes a set of [MarkerId]s from the cache. void removeMarkers(Set markerIdsToRemove) { - markerIdsToRemove?.forEach(_removeMarker); + markerIdsToRemove.forEach(_removeMarker); } void _removeMarker(MarkerId markerId) { - final MarkerController markerController = _markerIdToController[markerId]; + final MarkerController? markerController = _markerIdToController[markerId]; markerController?.remove(); _markerIdToController.remove(markerId); } @@ -106,7 +107,7 @@ class MarkersController extends GeometryController { /// See also [hideMarkerInfoWindow] and [isInfoWindowShown]. void showMarkerInfoWindow(MarkerId markerId) { _hideAllMarkerInfoWindow(); - MarkerController markerController = _markerIdToController[markerId]; + MarkerController? markerController = _markerIdToController[markerId]; markerController?.showInfoWindow(); } @@ -114,7 +115,7 @@ class MarkersController extends GeometryController { /// /// See also [showMarkerInfoWindow] and [isInfoWindowShown]. void hideMarkerInfoWindow(MarkerId markerId) { - MarkerController markerController = _markerIdToController[markerId]; + MarkerController? markerController = _markerIdToController[markerId]; markerController?.hideInfoWindow(); } @@ -122,7 +123,7 @@ class MarkersController extends GeometryController { /// /// See also [showMarkerInfoWindow] and [hideMarkerInfoWindow]. bool isInfoWindowShown(MarkerId markerId) { - MarkerController markerController = _markerIdToController[markerId]; + MarkerController? markerController = _markerIdToController[markerId]; return markerController?.infoWindowShown ?? false; } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart index 4ce1f022e586..9921d2ff3876 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart @@ -6,15 +6,15 @@ part of google_maps_flutter_web; /// The `PolygonController` class wraps a [gmaps.Polygon] and its `onTap` behavior. class PolygonController { - gmaps.Polygon _polygon; + gmaps.Polygon? _polygon; final bool _consumeTapEvents; /// Creates a `PolygonController` that wraps a [gmaps.Polygon] object and its `onTap` behavior. PolygonController({ - @required gmaps.Polygon polygon, + required gmaps.Polygon polygon, bool consumeTapEvents = false, - ui.VoidCallback onTap, + ui.VoidCallback? onTap, }) : _polygon = polygon, _consumeTapEvents = consumeTapEvents { if (onTap != null) { @@ -26,20 +26,25 @@ class PolygonController { /// Returns the wrapped [gmaps.Polygon]. Only used for testing. @visibleForTesting - gmaps.Polygon get polygon => _polygon; + gmaps.Polygon? get polygon => _polygon; /// Returns `true` if this Controller will use its own `onTap` handler to consume events. bool get consumeTapEvents => _consumeTapEvents; /// Updates the options of the wrapped [gmaps.Polygon] object. + /// + /// This cannot be called after [remove]. void update(gmaps.PolygonOptions options) { - _polygon.options = options; + assert(_polygon != null, 'Cannot `update` Polygon after calling `remove`.'); + _polygon!.options = options; } /// Disposes of the currently wrapped [gmaps.Polygon]. void remove() { - _polygon.visible = false; - _polygon.map = null; - _polygon = null; + if (_polygon != null) { + _polygon!.visible = false; + _polygon!.map = null; + _polygon = null; + } } } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart index 4671e6d77a87..ef51bd6043df 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart @@ -14,8 +14,8 @@ class PolygonsController extends GeometryController { /// Initializes the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. PolygonsController({ - @required StreamController stream, - }) : _streamController = stream, + required StreamController stream, + }) : _streamController = stream, _polygonIdToController = Map(); /// Returns the cache of [PolygonController]s. Test only. @@ -60,15 +60,15 @@ class PolygonsController extends GeometryController { } void _changePolygon(Polygon polygon) { - PolygonController polygonController = - _polygonIdToController[polygon?.polygonId]; + PolygonController? polygonController = + _polygonIdToController[polygon.polygonId]; polygonController?.update(_polygonOptionsFromPolygon(googleMap, polygon)); } /// Removes a set of [PolygonId]s from the cache. void removePolygons(Set polygonIdsToRemove) { - polygonIdsToRemove?.forEach((polygonId) { - final PolygonController polygonController = + polygonIdsToRemove.forEach((polygonId) { + final PolygonController? polygonController = _polygonIdToController[polygonId]; polygonController?.remove(); _polygonIdToController.remove(polygonId); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart index bf1dbb222555..eb4b6d88b503 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart @@ -6,15 +6,15 @@ part of google_maps_flutter_web; /// The `PolygonController` class wraps a [gmaps.Polyline] and its `onTap` behavior. class PolylineController { - gmaps.Polyline _polyline; + gmaps.Polyline? _polyline; final bool _consumeTapEvents; /// Creates a `PolylineController` that wraps a [gmaps.Polyline] object and its `onTap` behavior. PolylineController({ - @required gmaps.Polyline polyline, + required gmaps.Polyline polyline, bool consumeTapEvents = false, - ui.VoidCallback onTap, + ui.VoidCallback? onTap, }) : _polyline = polyline, _consumeTapEvents = consumeTapEvents { if (onTap != null) { @@ -26,20 +26,26 @@ class PolylineController { /// Returns the wrapped [gmaps.Polyline]. Only used for testing. @visibleForTesting - gmaps.Polyline get line => _polyline; + gmaps.Polyline? get line => _polyline; /// Returns `true` if this Controller will use its own `onTap` handler to consume events. bool get consumeTapEvents => _consumeTapEvents; /// Updates the options of the wrapped [gmaps.Polyline] object. + /// + /// This cannot be called after [remove]. void update(gmaps.PolylineOptions options) { - _polyline.options = options; + assert( + _polyline != null, 'Cannot `update` Polyline after calling `remove`.'); + _polyline!.options = options; } /// Disposes of the currently wrapped [gmaps.Polyline]. void remove() { - _polyline.visible = false; - _polyline.map = null; - _polyline = null; + if (_polyline != null) { + _polyline!.visible = false; + _polyline!.map = null; + _polyline = null; + } } } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart index e91b82fd1947..184c0d954744 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart @@ -14,8 +14,8 @@ class PolylinesController extends GeometryController { /// Initializes the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. PolylinesController({ - @required StreamController stream, - }) : _streamController = stream, + required StreamController stream, + }) : _streamController = stream, _polylineIdToController = Map(); /// Returns the cache of [PolylineContrller]s. Test only. @@ -26,7 +26,7 @@ class PolylinesController extends GeometryController { /// /// Wraps each line into its corresponding [PolylineController]. void addPolylines(Set polylinesToAdd) { - polylinesToAdd?.forEach((polyline) { + polylinesToAdd.forEach((polyline) { _addPolyline(polyline); }); } @@ -50,22 +50,22 @@ class PolylinesController extends GeometryController { /// Updates a set of [Polyline] objects with new options. void changePolylines(Set polylinesToChange) { - polylinesToChange?.forEach((polylineToChange) { + polylinesToChange.forEach((polylineToChange) { _changePolyline(polylineToChange); }); } void _changePolyline(Polyline polyline) { - PolylineController polylineController = - _polylineIdToController[polyline?.polylineId]; + PolylineController? polylineController = + _polylineIdToController[polyline.polylineId]; polylineController ?.update(_polylineOptionsFromPolyline(googleMap, polyline)); } /// Removes a set of [PolylineId]s from the cache. void removePolylines(Set polylineIdsToRemove) { - polylineIdsToRemove?.forEach((polylineId) { - final PolylineController polylineController = + polylineIdsToRemove.forEach((polylineId) { + final PolylineController? polylineController = _polylineIdToController[polylineId]; polylineController?.remove(); _polylineIdToController.remove(polylineId); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart index 10b5199a894e..ff980eb4c34b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart @@ -17,10 +17,10 @@ typedef LatLngCallback = void Function(gmaps.LatLng latLng); /// instance and our internal `mapId` value. abstract class GeometryController { /// The GMap instance that this controller operates on. - gmaps.GMap googleMap; + late gmaps.GMap googleMap; /// The map ID for events. - int mapId; + late int mapId; /// Binds a `mapId` and the [gmaps.GMap] instance to this controller. void bindToMap(int mapId, gmaps.GMap googleMap) { diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index 22df1b24afe0..5312a56cd14a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -1,7 +1,7 @@ name: google_maps_flutter_web description: Web platform implementation of google_maps_flutter homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter -version: 0.2.1 +version: 0.3.0 flutter: plugin: @@ -17,7 +17,7 @@ dependencies: sdk: flutter meta: ^1.3.0 google_maps_flutter_platform_interface: ^2.0.1 - google_maps: ^3.4.5 + google_maps: ^5.1.0 stream_transform: ^2.0.0 sanitize_html: ^2.0.0 @@ -27,5 +27,5 @@ dev_dependencies: pedantic: ^1.10.0 environment: - sdk: ">=2.3.0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" flutter: ">=1.20.0" diff --git a/script/build_all_plugins_app.sh b/script/build_all_plugins_app.sh index 56b05853fdcb..06566f059a54 100755 --- a/script/build_all_plugins_app.sh +++ b/script/build_all_plugins_app.sh @@ -59,7 +59,7 @@ fi for version in "${BUILD_MODES[@]}"; do echo "Building $version..." - (cd $REPO_DIR/all_plugins && flutter build $@ --$version --no-sound-null-safety) + (cd $REPO_DIR/all_plugins && flutter build $@ --$version) if [ $? -eq 0 ]; then echo "Successfully built $version all_plugins app." From 310fcc77f2fbca9c6f7293c728ba5fc075992995 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Thu, 1 Apr 2021 10:50:39 -0700 Subject: [PATCH 0319/1565] [google_maps_flutter] Fix NNBD migration mistake in example (#3768) --- .../google_maps_flutter/google_maps_flutter/CHANGELOG.md | 8 ++++++-- .../google_maps_flutter/example/lib/tile_overlay.dart | 6 +++--- .../google_maps_flutter/google_maps_flutter/pubspec.yaml | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index 141a096aee94..865d8f3e61ef 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,11 +1,15 @@ +## 2.0.3-dev + +* Fix incorrect typecast in TileOverlay example. + ## 2.0.2 -* Update flutter_plugin_android_lifecycle dependency to 2.0.1 to fix an R8 issue +* Update flutter\_plugin\_android\_lifecycle dependency to 2.0.1 to fix an R8 issue on some versions. ## 2.0.1 -* Update platform_plugin_interface version requirement. +* Update platform\_plugin\_interface version requirement. ## 2.0.0 diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart index a367511cb72f..1d6dd69c186b 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/tile_overlay.dart @@ -67,8 +67,8 @@ class TileOverlayBodyState extends State { @override Widget build(BuildContext context) { - Set overlays = { - if (_tileOverlay != null) _tileOverlay, + Set overlays = { + if (_tileOverlay != null) _tileOverlay!, }; return Column( mainAxisSize: MainAxisSize.min, @@ -84,7 +84,7 @@ class TileOverlayBodyState extends State { target: LatLng(59.935460, 30.325177), zoom: 7.0, ), - tileOverlays: overlays as Set, + tileOverlays: overlays, onMapCreated: _onMapCreated, ), ), diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index 5e73586e07e4..6cbd1fa1d781 100644 --- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: google_maps_flutter description: A Flutter plugin for integrating Google Maps in iOS and Android applications. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter -version: 2.0.2 +version: 2.0.3-dev dependencies: flutter: From 55b86008376a518b44da86618bd591709cff2ebd Mon Sep 17 00:00:00 2001 From: Ari Weiland Date: Thu, 1 Apr 2021 15:22:48 -0400 Subject: [PATCH 0320/1565] [webview_flutter] Fix scroll bar position for Android non-hybrid WebViews (#3765) --- packages/webview_flutter/CHANGELOG.md | 5 +++++ packages/webview_flutter/lib/src/webview_android.dart | 5 +---- packages/webview_flutter/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index 6d2b4bb26815..b8e5e0bba5e0 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.0.3 + +* Fixes bug where scroll bars on the Android non-hybrid WebView are rendered on +the wrong side of the screen. + ## 2.0.2 * Fixes bug where text fields are hidden behind the keyboard diff --git a/packages/webview_flutter/lib/src/webview_android.dart b/packages/webview_flutter/lib/src/webview_android.dart index 8850c7977e9c..ca1440d69929 100644 --- a/packages/webview_flutter/lib/src/webview_android.dart +++ b/packages/webview_flutter/lib/src/webview_android.dart @@ -47,10 +47,7 @@ class AndroidWebView implements WebViewPlatform { id, webViewPlatformCallbacksHandler)); }, gestureRecognizers: gestureRecognizers, - // WebView content is not affected by the Android view's layout direction, - // we explicitly set it here so that the widget doesn't require an ambient - // directionality. - layoutDirection: TextDirection.rtl, + layoutDirection: Directionality.maybeOf(context) ?? TextDirection.rtl, creationParams: MethodChannelWebViewPlatform.creationParamsToMap(creationParams), creationParamsCodec: const StandardMessageCodec(), diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml index 6ee9e119bd3a..a89ded4e9014 100644 --- a/packages/webview_flutter/pubspec.yaml +++ b/packages/webview_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: webview_flutter description: A Flutter plugin that provides a WebView widget on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter -version: 2.0.2 +version: 2.0.3 environment: sdk: ">=2.12.0-259.9.beta <3.0.0" From 8531d561469a9a6bc832a7f947856d74a7b3f03b Mon Sep 17 00:00:00 2001 From: Shail Patel Date: Thu, 1 Apr 2021 15:59:02 -0400 Subject: [PATCH 0321/1565] [video_player]Update README.me (#3713) --- packages/video_player/video_player/CHANGELOG.md | 4 ++++ packages/video_player/video_player/README.md | 2 +- packages/video_player/video_player/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index 6b20fd964dec..d1482d628d6d 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.1 + +* Update example code in README to reflect API changes. + ## 2.1.0 * Add `httpHeaders` option to `VideoPlayerController.network` diff --git a/packages/video_player/video_player/README.md b/packages/video_player/video_player/README.md index 7e36008cbbc3..f1c959a945ba 100644 --- a/packages/video_player/video_player/README.md +++ b/packages/video_player/video_player/README.md @@ -92,7 +92,7 @@ class _VideoAppState extends State { title: 'Video Demo', home: Scaffold( body: Center( - child: _controller.value.initialized + child: _controller.value.isInitialized ? AspectRatio( aspectRatio: _controller.value.aspectRatio, child: VideoPlayer(_controller), diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index 0215ead855e7..77b562347dea 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -1,7 +1,7 @@ name: video_player description: Flutter plugin for displaying inline video with other Flutter widgets on Android, iOS, and web. -version: 2.1.0 +version: 2.1.1 homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player flutter: From 76a417ca8456aba9d8781bb8bc6bc5b0cb219525 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 2 Apr 2021 12:53:05 -0700 Subject: [PATCH 0322/1565] [local_auth] Update Jetpack dependencies (#3786) The plugin was still using several beta version of Jetpack libraries from 2 years ago. Updates to the latest stable version of each. Fixes https://github.com/flutter/flutter/issues/52742 --- packages/local_auth/CHANGELOG.md | 4 ++++ packages/local_auth/android/build.gradle | 6 +++--- packages/local_auth/pubspec.yaml | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/local_auth/CHANGELOG.md b/packages/local_auth/CHANGELOG.md index 258144cd0daa..7e86672799e8 100644 --- a/packages/local_auth/CHANGELOG.md +++ b/packages/local_auth/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.2 + +* Update Jetpack dependencies to latest stable versions. + ## 1.1.1 * Update flutter_plugin_android_lifecycle dependency to 2.0.1 to fix an R8 issue diff --git a/packages/local_auth/android/build.gradle b/packages/local_auth/android/build.gradle index ae8e6f2828a2..714ac63d5ca6 100644 --- a/packages/local_auth/android/build.gradle +++ b/packages/local_auth/android/build.gradle @@ -34,9 +34,9 @@ android { } dependencies { - api "androidx.core:core:1.1.0-beta01" - api "androidx.biometric:biometric:1.0.0-beta01" - api "androidx.fragment:fragment:1.1.0-alpha06" + api "androidx.core:core:1.3.2" + api "androidx.biometric:biometric:1.1.0" + api "androidx.fragment:fragment:1.3.2" androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test:rules:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' diff --git a/packages/local_auth/pubspec.yaml b/packages/local_auth/pubspec.yaml index 76722c00a147..e9d406d891c5 100644 --- a/packages/local_auth/pubspec.yaml +++ b/packages/local_auth/pubspec.yaml @@ -2,7 +2,7 @@ name: local_auth description: Flutter plugin for Android and iOS devices to allow local authentication via fingerprint, touch ID, face ID, passcode, pin, or pattern. homepage: https://github.com/flutter/plugins/tree/master/packages/local_auth -version: 1.1.1 +version: 1.1.2 flutter: plugin: From 4322497bfbb13b8bff23e4d77854fa62ad2b18e7 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 5 Apr 2021 04:46:23 -0700 Subject: [PATCH 0323/1565] [google_maps_flutter] remove unnecessary test (#3787) --- .../test/android_google_map_test.dart | 56 ------------------- 1 file changed, 56 deletions(-) delete mode 100644 packages/google_maps_flutter/google_maps_flutter/test/android_google_map_test.dart diff --git a/packages/google_maps_flutter/google_maps_flutter/test/android_google_map_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/android_google_map_test.dart deleted file mode 100644 index 8ee845469e25..000000000000 --- a/packages/google_maps_flutter/google_maps_flutter/test/android_google_map_test.dart +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2013 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. - -@TestOn('android') -import 'package:flutter/services.dart'; -import 'package:flutter/widgets.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:google_maps_flutter/google_maps_flutter.dart'; - -import 'fake_maps_controllers.dart'; - -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - - final FakePlatformViewsController fakePlatformViewsController = - FakePlatformViewsController(); - - setUpAll(() { - SystemChannels.platform_views.setMockMethodCallHandler( - fakePlatformViewsController.fakePlatformViewsMethodHandler); - }); - - setUp(() { - fakePlatformViewsController.reset(); - }); - - testWidgets('Can update liteModeEnabled', (WidgetTester tester) async { - await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: GoogleMap( - initialCameraPosition: CameraPosition(target: LatLng(10.0, 15.0)), - liteModeEnabled: false, - ), - ), - ); - - final FakePlatformGoogleMap platformGoogleMap = - fakePlatformViewsController.lastCreatedView!; - - expect(platformGoogleMap.liteModeEnabled, false); - - await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: GoogleMap( - initialCameraPosition: CameraPosition(target: LatLng(10.0, 15.0)), - liteModeEnabled: true, - ), - ), - ); - - expect(platformGoogleMap.liteModeEnabled, true); - }); -} From bd2dbb151ecf0e5b381bb6be954ed3accf01a0ae Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 5 Apr 2021 13:54:05 -0700 Subject: [PATCH 0324/1565] [tool] refactor publish plugin command (#3779) --- .../tool/lib/src/publish_plugin_command.dart | 92 +++++++++++-------- .../test/publish_plugin_command_test.dart | 8 +- 2 files changed, 57 insertions(+), 43 deletions(-) diff --git a/script/tool/lib/src/publish_plugin_command.dart b/script/tool/lib/src/publish_plugin_command.dart index eb59091db34a..d00400294ab3 100644 --- a/script/tool/lib/src/publish_plugin_command.dart +++ b/script/tool/lib/src/publish_plugin_command.dart @@ -85,15 +85,24 @@ class PublishPluginCommand extends PluginCommand { final Print _print; final Stdin _stdin; // The directory of the actual package that we are publishing. - Directory _packageDir; StreamSubscription _stdinSubscription; @override Future run() async { checkSharding(); + final String package = argResults[_packageOption]; + if (package == null) { + _print( + 'Must specify a package to publish. See `plugin_tools help publish-plugin`.'); + throw ToolExit(1); + } + _print('Checking local repo...'); - _packageDir = _checkPackageDir(); - await _checkGitStatus(); + if (!await GitDir.isGitDir(packagesDir.path)) { + _print('$packagesDir is not a valid Git repository.'); + throw ToolExit(1); + } + final bool shouldPushTag = argResults[_pushTagsOption]; final String remote = argResults[_remoteOption]; String remoteUrl; @@ -102,23 +111,39 @@ class PublishPluginCommand extends PluginCommand { } _print('Local repo is ready!'); - await _publish(); - _print('Package published!'); - if (!argResults[_tagReleaseOption]) { - return await _finishSuccesfully(); + final Directory packageDir = _getPackageDir(package); + await _publishPlugin(packageDir: packageDir); + if (argResults[_tagReleaseOption] as bool) { + await _tagRelease( + packageDir: packageDir, + remote: remote, + remoteUrl: remoteUrl, + shouldPushTag: shouldPushTag); } + await _finishSuccesfully(); + } - _print('Tagging release...'); - final String tag = _getTag(); + Future _publishPlugin({@required Directory packageDir}) async { + await _checkGitStatus(packageDir); + await _publish(packageDir); + _print('Package published!'); + } + + Future _tagRelease( + {@required Directory packageDir, + @required String remote, + @required String remoteUrl, + @required bool shouldPushTag}) async { + final String tag = _getTag(packageDir); + _print('Tagging release $tag...'); await processRunner.runAndExitOnError('git', ['tag', tag], - workingDir: _packageDir); + workingDir: packageDir); if (!shouldPushTag) { - return await _finishSuccesfully(); + return; } _print('Pushing tag to $remote...'); await _pushTagToRemote(remote: remote, tag: tag, remoteUrl: remoteUrl); - await _finishSuccesfully(); } Future _finishSuccesfully() async { @@ -126,36 +151,28 @@ class PublishPluginCommand extends PluginCommand { _print('Done!'); } - Directory _checkPackageDir() { - final String package = argResults[_packageOption]; - if (package == null) { - _print( - 'Must specify a package to publish. See `plugin_tools help publish-plugin`.'); - throw ToolExit(1); - } - final Directory _packageDir = packagesDir.childDirectory(package); - if (!_packageDir.existsSync()) { - _print('${_packageDir.absolute.path} does not exist.'); + // Returns the packageDirectory based on the package name. + // Throws ToolExit if the `package` doesn't exist. + Directory _getPackageDir(String package) { + final Directory packageDir = packagesDir.childDirectory(package); + if (!packageDir.existsSync()) { + _print('${packageDir.absolute.path} does not exist.'); throw ToolExit(1); } - return _packageDir; + return packageDir; } - Future _checkGitStatus() async { - if (!await GitDir.isGitDir(packagesDir.path)) { - _print('$packagesDir is not a valid Git repository.'); - throw ToolExit(1); - } - + Future _checkGitStatus(Directory packageDir) async { final ProcessResult statusResult = await processRunner.runAndExitOnError( 'git', [ 'status', '--porcelain', '--ignored', - _packageDir.absolute.path + packageDir.absolute.path ], - workingDir: _packageDir); + workingDir: packageDir); + final String statusOutput = statusResult.stdout; if (statusOutput.isNotEmpty) { _print( @@ -169,17 +186,17 @@ class PublishPluginCommand extends PluginCommand { Future _verifyRemote(String remote) async { final ProcessResult remoteInfo = await processRunner.runAndExitOnError( 'git', ['remote', 'get-url', remote], - workingDir: _packageDir); + workingDir: packagesDir); return remoteInfo.stdout; } - Future _publish() async { + Future _publish(Directory packageDir) async { final List publishFlags = argResults[_pubFlagsOption]; _print( - 'Running `pub publish ${publishFlags.join(' ')}` in ${_packageDir.absolute.path}...\n'); + 'Running `pub publish ${publishFlags.join(' ')}` in ${packageDir.absolute.path}...\n'); final Process publish = await processRunner.start( 'flutter', ['pub', 'publish'] + publishFlags, - workingDirectory: _packageDir); + workingDirectory: packageDir); publish.stdout .transform(utf8.decoder) .listen((String data) => _print(data)); @@ -196,9 +213,9 @@ class PublishPluginCommand extends PluginCommand { } } - String _getTag() { + String _getTag(Directory packageDir) { final File pubspecFile = - fileSystem.file(p.join(_packageDir.path, 'pubspec.yaml')); + fileSystem.file(p.join(packageDir.path, 'pubspec.yaml')); final YamlMap pubspecYaml = loadYaml(pubspecFile.readAsStringSync()); final String name = pubspecYaml['name']; final String version = pubspecYaml['version']; @@ -220,7 +237,6 @@ class PublishPluginCommand extends PluginCommand { _print('Tag push canceled.'); throw ToolExit(1); } - await processRunner.runAndExitOnError('git', ['push', remote, tag], workingDir: packagesDir); } diff --git a/script/tool/test/publish_plugin_command_test.dart b/script/tool/test/publish_plugin_command_test.dart index 9a0f1d6b6e63..cfa40b9dc0a5 100644 --- a/script/tool/test/publish_plugin_command_test.dart +++ b/script/tool/test/publish_plugin_command_test.dart @@ -50,7 +50,7 @@ void main() { mockStdin = MockStdin(); commandRunner = CommandRunner('tester', '') ..addCommand(PublishPluginCommand( - mockPackagesDir, const LocalFileSystem(), + mockPackagesDir, mockPackagesDir.fileSystem, processRunner: processRunner, print: (Object message) => printedMessages.add(message.toString()), stdinput: mockStdin)); @@ -65,7 +65,6 @@ void main() { test('requires a package flag', () async { await expectLater(() => commandRunner.run(['publish-plugin']), throwsA(const TypeMatcher())); - expect( printedMessages.last, contains("Must specify a package to publish.")); }); @@ -73,7 +72,7 @@ void main() { test('requires an existing flag', () async { await expectLater( () => commandRunner - .run(['publish-plugin', '--package', 'iamerror']), + .run(['publish-plugin', '--package', 'iamerror', '--no-push-tags']), throwsA(const TypeMatcher())); expect(printedMessages.last, contains('iamerror does not exist')); @@ -84,7 +83,7 @@ void main() { await expectLater( () => commandRunner - .run(['publish-plugin', '--package', testPluginName]), + .run(['publish-plugin', '--package', testPluginName, '--no-push-tags']), throwsA(const TypeMatcher())); expect( @@ -98,7 +97,6 @@ void main() { () => commandRunner .run(['publish-plugin', '--package', testPluginName]), throwsA(const TypeMatcher())); - expect(processRunner.results.last.stderr, contains("No such remote")); }); From 00ec3cdccb3c39b86c033b0ab5748564001ab5b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Kihlstr=C3=B6m?= Date: Mon, 5 Apr 2021 23:54:21 +0200 Subject: [PATCH 0325/1565] [google_maps_flutter] Reword README (#3784) --- packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md | 4 ++++ packages/google_maps_flutter/google_maps_flutter/README.md | 2 +- packages/google_maps_flutter/google_maps_flutter/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index 865d8f3e61ef..4ac4f2ad7749 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.4-dev + +* Fix english wording in instructions. + ## 2.0.3-dev * Fix incorrect typecast in TileOverlay example. diff --git a/packages/google_maps_flutter/google_maps_flutter/README.md b/packages/google_maps_flutter/google_maps_flutter/README.md index 6bb11a8da793..767ef8c1a561 100644 --- a/packages/google_maps_flutter/google_maps_flutter/README.md +++ b/packages/google_maps_flutter/google_maps_flutter/README.md @@ -21,7 +21,7 @@ To use this plugin, add `google_maps_flutter` as a [dependency in your pubspec.y * To enable Google Maps for iOS, select "Maps SDK for iOS" in the "Additional APIs" section, then select "ENABLE". * Make sure the APIs you enabled are under the "Enabled APIs" section. -* You can also find detailed steps to get start with Google Maps Platform [here](https://developers.google.com/maps/gmp-get-started). +For more details, see [Getting started with Google Maps Platform](https://developers.google.com/maps/gmp-get-started). ### Android diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index 6cbd1fa1d781..f2484e84c180 100644 --- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: google_maps_flutter description: A Flutter plugin for integrating Google Maps in iOS and Android applications. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter -version: 2.0.3-dev +version: 2.0.4-dev dependencies: flutter: From 08f8f21e749256b02ee821a9a436b3827469ac39 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Mon, 5 Apr 2021 16:03:45 -0700 Subject: [PATCH 0326/1565] [local_auth] Fix callback thread handling (#3778) Ensure that all auth replies, which are sent on an internal framework queue per documentation, are dispatched back to the main thread for handling, as all resulting operations (method channel callbacks, display of UI) are things that must be done on the main thread In order to test this, sets up local_auth with XCTest-based tests, and adds the ability to inject a mock LAContext. (This does not do full unit test backfill, to limit the scope of the PR.) Fixes flutter/flutter#47465 --- packages/local_auth/CHANGELOG.md | 4 + packages/local_auth/example/ios/Podfile | 6 + .../ios/Runner.xcodeproj/project.pbxproj | 194 +++++++++++++++--- .../contents.xcworkspacedata | 2 +- .../xcshareddata/xcschemes/Runner.xcscheme | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../local_auth/example/ios/XCTests/Info.plist | 22 ++ .../ios/Classes/FLTLocalAuthPlugin.m | 112 +++++----- .../ios/Tests/FLTLocalAuthPluginTests.m | 189 +++++++++++++++++ packages/local_auth/pubspec.yaml | 2 +- 10 files changed, 472 insertions(+), 77 deletions(-) create mode 100644 packages/local_auth/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 packages/local_auth/example/ios/XCTests/Info.plist create mode 100644 packages/local_auth/ios/Tests/FLTLocalAuthPluginTests.m diff --git a/packages/local_auth/CHANGELOG.md b/packages/local_auth/CHANGELOG.md index 7e86672799e8..429e217cc167 100644 --- a/packages/local_auth/CHANGELOG.md +++ b/packages/local_auth/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.3 + +* Fix crashes due to threading issues in iOS implementation. + ## 1.1.2 * Update Jetpack dependencies to latest stable versions. diff --git a/packages/local_auth/example/ios/Podfile b/packages/local_auth/example/ios/Podfile index f7d6a5e68c3a..65497359e0a6 100644 --- a/packages/local_auth/example/ios/Podfile +++ b/packages/local_auth/example/ios/Podfile @@ -29,6 +29,12 @@ flutter_ios_podfile_setup target 'Runner' do flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + + target 'XCTests' do + inherit! :search_paths + + pod 'OCMock', '3.5' + end end post_install do |installer| diff --git a/packages/local_auth/example/ios/Runner.xcodeproj/project.pbxproj b/packages/local_auth/example/ios/Runner.xcodeproj/project.pbxproj index 8960fe4d8af3..708c643bdf28 100644 --- a/packages/local_auth/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/local_auth/example/ios/Runner.xcodeproj/project.pbxproj @@ -9,18 +9,26 @@ /* Begin PBXBuildFile section */ 0CCCD07A2CE24E13C9C1EEA4 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D274A3F79473B1549B2BBD5 /* libPods-Runner.a */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3398D2E426164AD8005A052F /* FLTLocalAuthPluginTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3398D2E326164AD8005A052F /* FLTLocalAuthPluginTests.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + D6C28B8B9E1BDEC22D03304F /* libPods-XCTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EB178B442E18480B8054307 /* libPods-XCTests.a */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 3398D2D226163948005A052F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXCopyFilesBuildPhase section */ 9705A1C41CF9048500538489 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; @@ -28,8 +36,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -39,15 +45,20 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3398D2CD26163948005A052F /* XCTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XCTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3398D2D126163948005A052F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 3398D2DC261649CD005A052F /* liblocal_auth.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = liblocal_auth.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 3398D2DF26164A03005A052F /* liblocal_auth.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = liblocal_auth.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 3398D2E326164AD8005A052F /* FLTLocalAuthPluginTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FLTLocalAuthPluginTests.m; path = ../../../ios/Tests/FLTLocalAuthPluginTests.m; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 4EB178B442E18480B8054307 /* libPods-XCTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-XCTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 658CDD04B21E4EA92F8EF229 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 81D8AFFB31AECDACBC5B11F8 /* Pods-XCTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-XCTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-XCTests/Pods-XCTests.debug.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; @@ -56,15 +67,22 @@ 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 9D274A3F79473B1549B2BBD5 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; EB36DF6C3F25E00DF4175422 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + F6BEBFD3433B1712765D62F7 /* Pods-XCTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-XCTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-XCTests/Pods-XCTests.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 3398D2CA26163948005A052F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D6C28B8B9E1BDEC22D03304F /* libPods-XCTests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, 0CCCD07A2CE24E13C9C1EEA4 /* libPods-Runner.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -72,12 +90,19 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 3398D2CE26163948005A052F /* XCTests */ = { + isa = PBXGroup; + children = ( + 3398D2E326164AD8005A052F /* FLTLocalAuthPluginTests.m */, + 3398D2D126163948005A052F /* Info.plist */, + ); + path = XCTests; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( - 3B80C3931E831B6300D905FE /* App.framework */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEBA1CF902C7004384FC /* Flutter.framework */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 9740EEB31CF90195004384FC /* Generated.xcconfig */, @@ -90,6 +115,7 @@ children = ( 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, + 3398D2CE26163948005A052F /* XCTests */, 97C146EF1CF9000F007C117D /* Products */, F8CC53B854B121315C7319D2 /* Pods */, E2D5FA899A019BD3E0DB0917 /* Frameworks */, @@ -100,6 +126,7 @@ isa = PBXGroup; children = ( 97C146EE1CF9000F007C117D /* Runner.app */, + 3398D2CD26163948005A052F /* XCTests.xctest */, ); name = Products; sourceTree = ""; @@ -131,7 +158,10 @@ E2D5FA899A019BD3E0DB0917 /* Frameworks */ = { isa = PBXGroup; children = ( + 3398D2DF26164A03005A052F /* liblocal_auth.a */, + 3398D2DC261649CD005A052F /* liblocal_auth.a */, 9D274A3F79473B1549B2BBD5 /* libPods-Runner.a */, + 4EB178B442E18480B8054307 /* libPods-XCTests.a */, ); name = Frameworks; sourceTree = ""; @@ -141,6 +171,8 @@ children = ( EB36DF6C3F25E00DF4175422 /* Pods-Runner.debug.xcconfig */, 658CDD04B21E4EA92F8EF229 /* Pods-Runner.release.xcconfig */, + 81D8AFFB31AECDACBC5B11F8 /* Pods-XCTests.debug.xcconfig */, + F6BEBFD3433B1712765D62F7 /* Pods-XCTests.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -148,6 +180,25 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 3398D2CC26163948005A052F /* XCTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3398D2D426163948005A052F /* Build configuration list for PBXNativeTarget "XCTests" */; + buildPhases = ( + B5AF6C7A6759E6F38749E537 /* [CP] Check Pods Manifest.lock */, + 3398D2C926163948005A052F /* Sources */, + 3398D2CA26163948005A052F /* Frameworks */, + 3398D2CB26163948005A052F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 3398D2D326163948005A052F /* PBXTargetDependency */, + ); + name = XCTests; + productName = XCTests; + productReference = 3398D2CD26163948005A052F /* XCTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 97C146ED1CF9000F007C117D /* Runner */ = { isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; @@ -159,7 +210,6 @@ 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 16CF73924D0A9C13B2100A83 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -179,6 +229,11 @@ LastUpgradeCheck = 1100; ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { + 3398D2CC26163948005A052F = { + CreatedOnToolsVersion = 12.4; + ProvisioningStyle = Automatic; + TestTargetID = 97C146ED1CF9000F007C117D; + }; 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; }; @@ -198,11 +253,19 @@ projectRoot = ""; targets = ( 97C146ED1CF9000F007C117D /* Runner */, + 3398D2CC26163948005A052F /* XCTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 3398D2CB26163948005A052F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 97C146EC1CF9000F007C117D /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -217,61 +280,68 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 16CF73924D0A9C13B2100A83 /* [CP] Embed Pods Frameworks */ = { + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "[CP] Embed Pods Frameworks"; + name = "Thin Binary"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Thin Binary"; + name = "Run Script"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; - 9740EEB61CF901F6004384FC /* Run Script */ = { + 98D96A2D1A74AF66E3DD2DBC /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); - name = "Run Script"; + name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; }; - 98D96A2D1A74AF66E3DD2DBC /* [CP] Check Pods Manifest.lock */ = { + B5AF6C7A6759E6F38749E537 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( "${PODS_PODFILE_DIR_PATH}/Podfile.lock", "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-XCTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -281,6 +351,14 @@ /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 3398D2C926163948005A052F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3398D2E426164AD8005A052F /* FLTLocalAuthPluginTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 97C146EA1CF9000F007C117D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -293,6 +371,14 @@ }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 3398D2D326163948005A052F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 3398D2D226163948005A052F /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ 97C146FA1CF9000F007C117D /* Main.storyboard */ = { isa = PBXVariantGroup; @@ -313,9 +399,55 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 3398D2D526163948005A052F /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 81D8AFFB31AECDACBC5B11F8 /* Pods-XCTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = XCTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.google.XCTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner"; + }; + name = Debug; + }; + 3398D2D626163948005A052F /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F6BEBFD3433B1712765D62F7 /* Pods-XCTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = XCTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.google.XCTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner"; + }; + name = Release; + }; 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; @@ -372,7 +504,6 @@ }; 97C147041CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; @@ -466,6 +597,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 3398D2D426163948005A052F /* Build configuration list for PBXNativeTarget "XCTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3398D2D526163948005A052F /* Debug */, + 3398D2D626163948005A052F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/packages/local_auth/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/local_auth/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed0f..919434a6254f 100644 --- a/packages/local_auth/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/packages/local_auth/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/packages/local_auth/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/local_auth/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 3bb3697ef41c..5b12c3ad032e 100644 --- a/packages/local_auth/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/local_auth/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -37,6 +37,16 @@ + + + + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/local_auth/example/ios/XCTests/Info.plist b/packages/local_auth/example/ios/XCTests/Info.plist new file mode 100644 index 000000000000..64d65ca49577 --- /dev/null +++ b/packages/local_auth/example/ios/XCTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m b/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m index 40a14b9f4b47..a00c7eed2703 100644 --- a/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m +++ b/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m @@ -6,11 +6,17 @@ #import "FLTLocalAuthPlugin.h" @interface FLTLocalAuthPlugin () -@property(copy, nullable) NSDictionary *lastCallArgs; -@property(nullable) FlutterResult lastResult; +@property(nonatomic, copy, nullable) NSDictionary *lastCallArgs; +@property(nonatomic, nullable) FlutterResult lastResult; +// For unit tests to inject dummy LAContext instances that will be used when a new context would +// normally be created. Each call to createAuthContext will remove the current first element from +// the array. +- (void)setAuthContextOverrides:(NSArray *)authContexts; @end -@implementation FLTLocalAuthPlugin +@implementation FLTLocalAuthPlugin { + NSMutableArray *_authContextOverrides; +} + (void)registerWithRegistrar:(NSObject *)registrar { FlutterMethodChannel *channel = @@ -40,6 +46,19 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result #pragma mark Private Methods +- (void)setAuthContextOverrides:(NSArray *)authContexts { + _authContextOverrides = [authContexts mutableCopy]; +} + +- (LAContext *)createAuthContext { + if ([_authContextOverrides count] > 0) { + LAContext *context = [_authContextOverrides firstObject]; + [_authContextOverrides removeObjectAtIndex:0]; + return context; + } + return [[LAContext alloc] init]; +} + - (void)alertMessage:(NSString *)message firstButton:(NSString *)firstButton flutterResult:(FlutterResult)result @@ -75,7 +94,7 @@ - (void)alertMessage:(NSString *)message } - (void)getAvailableBiometrics:(FlutterResult)result { - LAContext *context = [[LAContext alloc] init]; + LAContext *context = self.createAuthContext; NSError *authError = nil; NSMutableArray *biometrics = [[NSMutableArray alloc] init]; if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics @@ -96,9 +115,10 @@ - (void)getAvailableBiometrics:(FlutterResult)result { } result(biometrics); } + - (void)authenticateWithBiometrics:(NSDictionary *)arguments withFlutterResult:(FlutterResult)result { - LAContext *context = [[LAContext alloc] init]; + LAContext *context = self.createAuthContext; NSError *authError = nil; self.lastCallArgs = nil; self.lastResult = nil; @@ -109,27 +129,12 @@ - (void)authenticateWithBiometrics:(NSDictionary *)arguments [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:arguments[@"localizedReason"] reply:^(BOOL success, NSError *error) { - if (success) { - result(@YES); - } else { - switch (error.code) { - case LAErrorPasscodeNotSet: - case LAErrorTouchIDNotAvailable: - case LAErrorTouchIDNotEnrolled: - case LAErrorTouchIDLockout: - [self handleErrors:error - flutterArguments:arguments - withFlutterResult:result]; - return; - case LAErrorSystemCancel: - if ([arguments[@"stickyAuth"] boolValue]) { - self.lastCallArgs = arguments; - self.lastResult = result; - return; - } - } - result(@NO); - } + dispatch_async(dispatch_get_main_queue(), ^{ + [self handleAuthReplyWithSuccess:success + error:error + flutterArguments:arguments + flutterResult:result]; + }); }]; } else { [self handleErrors:authError flutterArguments:arguments withFlutterResult:result]; @@ -137,7 +142,7 @@ - (void)authenticateWithBiometrics:(NSDictionary *)arguments } - (void)authenticate:(NSDictionary *)arguments withFlutterResult:(FlutterResult)result { - LAContext *context = [[LAContext alloc] init]; + LAContext *context = self.createAuthContext; NSError *authError = nil; _lastCallArgs = nil; _lastResult = nil; @@ -148,27 +153,12 @@ - (void)authenticate:(NSDictionary *)arguments withFlutterResult:(FlutterResult) [context evaluatePolicy:kLAPolicyDeviceOwnerAuthentication localizedReason:arguments[@"localizedReason"] reply:^(BOOL success, NSError *error) { - if (success) { - result(@YES); - } else { - switch (error.code) { - case LAErrorPasscodeNotSet: - case LAErrorTouchIDNotAvailable: - case LAErrorTouchIDNotEnrolled: - case LAErrorTouchIDLockout: - [self handleErrors:error - flutterArguments:arguments - withFlutterResult:result]; - return; - case LAErrorSystemCancel: - if ([arguments[@"stickyAuth"] boolValue]) { - self->_lastCallArgs = arguments; - self->_lastResult = result; - return; - } - } - result(@NO); - } + dispatch_async(dispatch_get_main_queue(), ^{ + [self handleAuthReplyWithSuccess:success + error:error + flutterArguments:arguments + flutterResult:result]; + }); }]; } else { [self handleErrors:authError flutterArguments:arguments withFlutterResult:result]; @@ -178,6 +168,32 @@ - (void)authenticate:(NSDictionary *)arguments withFlutterResult:(FlutterResult) } } +- (void)handleAuthReplyWithSuccess:(BOOL)success + error:(NSError *)error + flutterArguments:(NSDictionary *)arguments + flutterResult:(FlutterResult)result { + NSAssert([NSThread isMainThread], @"Response handling must be done on the main thread."); + if (success) { + result(@YES); + } else { + switch (error.code) { + case LAErrorPasscodeNotSet: + case LAErrorTouchIDNotAvailable: + case LAErrorTouchIDNotEnrolled: + case LAErrorTouchIDLockout: + [self handleErrors:error flutterArguments:arguments withFlutterResult:result]; + return; + case LAErrorSystemCancel: + if ([arguments[@"stickyAuth"] boolValue]) { + self->_lastCallArgs = arguments; + self->_lastResult = result; + return; + } + } + result(@NO); + } +} + - (void)handleErrors:(NSError *)authError flutterArguments:(NSDictionary *)arguments withFlutterResult:(FlutterResult)result { diff --git a/packages/local_auth/ios/Tests/FLTLocalAuthPluginTests.m b/packages/local_auth/ios/Tests/FLTLocalAuthPluginTests.m new file mode 100644 index 000000000000..97e78e2f624b --- /dev/null +++ b/packages/local_auth/ios/Tests/FLTLocalAuthPluginTests.m @@ -0,0 +1,189 @@ +// Copyright 2013 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 LocalAuthentication; +@import XCTest; + +#import + +#if __has_include() +#import +#else +@import local_auth; +#endif + +// Private API needed for tests. +@interface FLTLocalAuthPlugin (Test) +- (void)setAuthContextOverrides:(NSArray*)authContexts; +@end + +// Set a long timeout to avoid flake due to slow CI. +static const NSTimeInterval kTimeout = 30.0; + +@interface FLTLocalAuthPluginTests : XCTestCase +@end + +@implementation FLTLocalAuthPluginTests + +- (void)setUp { + self.continueAfterFailure = NO; +} + +- (void)testSuccessfullAuthWithBiometrics { + FLTLocalAuthPlugin* plugin = [[FLTLocalAuthPlugin alloc] init]; + id mockAuthContext = OCMClassMock([LAContext class]); + plugin.authContextOverrides = @[ mockAuthContext ]; + + const LAPolicy policy = LAPolicyDeviceOwnerAuthenticationWithBiometrics; + NSString* reason = @"a reason"; + OCMStub([mockAuthContext canEvaluatePolicy:policy error:[OCMArg setTo:nil]]).andReturn(YES); + + // evaluatePolicy:localizedReason:reply: calls back on an internal queue, which is not + // guaranteed to be on the main thread. Ensure that's handled correctly by calling back on + // a background thread. + void (^backgroundThreadReplyCaller)(NSInvocation*) = ^(NSInvocation* invocation) { + void (^reply)(BOOL, NSError*); + [invocation getArgument:&reply atIndex:4]; + dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{ + reply(YES, nil); + }); + }; + OCMStub([mockAuthContext evaluatePolicy:policy localizedReason:reason reply:[OCMArg any]]) + .andDo(backgroundThreadReplyCaller); + + FlutterMethodCall* call = [FlutterMethodCall methodCallWithMethodName:@"authenticate" + arguments:@{ + @"biometricOnly" : @(YES), + @"localizedReason" : reason, + }]; + + XCTestExpectation* expectation = [self expectationWithDescription:@"Result is called"]; + [plugin handleMethodCall:call + result:^(id _Nullable result) { + XCTAssertTrue([NSThread isMainThread]); + XCTAssertTrue([result isKindOfClass:[NSNumber class]]); + XCTAssertTrue([result boolValue]); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:kTimeout handler:nil]; +} + +- (void)testSuccessfullAuthWithoutBiometrics { + FLTLocalAuthPlugin* plugin = [[FLTLocalAuthPlugin alloc] init]; + id mockAuthContext = OCMClassMock([LAContext class]); + plugin.authContextOverrides = @[ mockAuthContext ]; + + const LAPolicy policy = LAPolicyDeviceOwnerAuthentication; + NSString* reason = @"a reason"; + OCMStub([mockAuthContext canEvaluatePolicy:policy error:[OCMArg setTo:nil]]).andReturn(YES); + + // evaluatePolicy:localizedReason:reply: calls back on an internal queue, which is not + // guaranteed to be on the main thread. Ensure that's handled correctly by calling back on + // a background thread. + void (^backgroundThreadReplyCaller)(NSInvocation*) = ^(NSInvocation* invocation) { + void (^reply)(BOOL, NSError*); + [invocation getArgument:&reply atIndex:4]; + dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{ + reply(YES, nil); + }); + }; + OCMStub([mockAuthContext evaluatePolicy:policy localizedReason:reason reply:[OCMArg any]]) + .andDo(backgroundThreadReplyCaller); + + FlutterMethodCall* call = [FlutterMethodCall methodCallWithMethodName:@"authenticate" + arguments:@{ + @"biometricOnly" : @(NO), + @"localizedReason" : reason, + }]; + + XCTestExpectation* expectation = [self expectationWithDescription:@"Result is called"]; + [plugin handleMethodCall:call + result:^(id _Nullable result) { + XCTAssertTrue([NSThread isMainThread]); + XCTAssertTrue([result isKindOfClass:[NSNumber class]]); + XCTAssertTrue([result boolValue]); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:kTimeout handler:nil]; +} + +- (void)testFailedAuthWithBiometrics { + FLTLocalAuthPlugin* plugin = [[FLTLocalAuthPlugin alloc] init]; + id mockAuthContext = OCMClassMock([LAContext class]); + plugin.authContextOverrides = @[ mockAuthContext ]; + + const LAPolicy policy = LAPolicyDeviceOwnerAuthenticationWithBiometrics; + NSString* reason = @"a reason"; + OCMStub([mockAuthContext canEvaluatePolicy:policy error:[OCMArg setTo:nil]]).andReturn(YES); + + // evaluatePolicy:localizedReason:reply: calls back on an internal queue, which is not + // guaranteed to be on the main thread. Ensure that's handled correctly by calling back on + // a background thread. + void (^backgroundThreadReplyCaller)(NSInvocation*) = ^(NSInvocation* invocation) { + void (^reply)(BOOL, NSError*); + [invocation getArgument:&reply atIndex:4]; + dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{ + reply(NO, [NSError errorWithDomain:@"error" code:99 userInfo:nil]); + }); + }; + OCMStub([mockAuthContext evaluatePolicy:policy localizedReason:reason reply:[OCMArg any]]) + .andDo(backgroundThreadReplyCaller); + + FlutterMethodCall* call = [FlutterMethodCall methodCallWithMethodName:@"authenticate" + arguments:@{ + @"biometricOnly" : @(YES), + @"localizedReason" : reason, + }]; + + XCTestExpectation* expectation = [self expectationWithDescription:@"Result is called"]; + [plugin handleMethodCall:call + result:^(id _Nullable result) { + XCTAssertTrue([NSThread isMainThread]); + XCTAssertTrue([result isKindOfClass:[NSNumber class]]); + XCTAssertFalse([result boolValue]); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:kTimeout handler:nil]; +} + +- (void)testFailedAuthWithoutBiometrics { + FLTLocalAuthPlugin* plugin = [[FLTLocalAuthPlugin alloc] init]; + id mockAuthContext = OCMClassMock([LAContext class]); + plugin.authContextOverrides = @[ mockAuthContext ]; + + const LAPolicy policy = LAPolicyDeviceOwnerAuthentication; + NSString* reason = @"a reason"; + OCMStub([mockAuthContext canEvaluatePolicy:policy error:[OCMArg setTo:nil]]).andReturn(YES); + + // evaluatePolicy:localizedReason:reply: calls back on an internal queue, which is not + // guaranteed to be on the main thread. Ensure that's handled correctly by calling back on + // a background thread. + void (^backgroundThreadReplyCaller)(NSInvocation*) = ^(NSInvocation* invocation) { + void (^reply)(BOOL, NSError*); + [invocation getArgument:&reply atIndex:4]; + dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{ + reply(NO, [NSError errorWithDomain:@"error" code:99 userInfo:nil]); + }); + }; + OCMStub([mockAuthContext evaluatePolicy:policy localizedReason:reason reply:[OCMArg any]]) + .andDo(backgroundThreadReplyCaller); + + FlutterMethodCall* call = [FlutterMethodCall methodCallWithMethodName:@"authenticate" + arguments:@{ + @"biometricOnly" : @(NO), + @"localizedReason" : reason, + }]; + + XCTestExpectation* expectation = [self expectationWithDescription:@"Result is called"]; + [plugin handleMethodCall:call + result:^(id _Nullable result) { + XCTAssertTrue([NSThread isMainThread]); + XCTAssertTrue([result isKindOfClass:[NSNumber class]]); + XCTAssertFalse([result boolValue]); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:kTimeout handler:nil]; +} + +@end diff --git a/packages/local_auth/pubspec.yaml b/packages/local_auth/pubspec.yaml index e9d406d891c5..5e2dbb4e6183 100644 --- a/packages/local_auth/pubspec.yaml +++ b/packages/local_auth/pubspec.yaml @@ -2,7 +2,7 @@ name: local_auth description: Flutter plugin for Android and iOS devices to allow local authentication via fingerprint, touch ID, face ID, passcode, pin, or pattern. homepage: https://github.com/flutter/plugins/tree/master/packages/local_auth -version: 1.1.2 +version: 1.1.3 flutter: plugin: From 4bd178b9fd893140c1e982f07f96cd1485a1c89e Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 5 Apr 2021 17:34:03 -0700 Subject: [PATCH 0327/1565] [in_app_purchase] improve readme (#3731) --- .../in_app_purchase/CHANGELOG.md | 6 +- .../in_app_purchase/in_app_purchase/README.md | 254 +++++++++++------- .../in_app_purchase/doc/iap_android.gif | Bin 0 -> 427150 bytes .../in_app_purchase/doc/iap_ios.gif | Bin 0 -> 827439 bytes .../in_app_purchase/example/README.md | 3 +- .../in_app_purchase/pubspec.yaml | 2 +- 6 files changed, 166 insertions(+), 99 deletions(-) create mode 100644 packages/in_app_purchase/in_app_purchase/doc/iap_android.gif create mode 100644 packages/in_app_purchase/in_app_purchase/doc/iap_ios.gif diff --git a/packages/in_app_purchase/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase/CHANGELOG.md index 114f11aa89b3..beb4356dc398 100644 --- a/packages/in_app_purchase/in_app_purchase/CHANGELOG.md +++ b/packages/in_app_purchase/in_app_purchase/CHANGELOG.md @@ -1,10 +1,14 @@ +## 0.5.1+2 + +* Update README to provide a better instruction of the plugin. + ## 0.5.1+1 * Fix error message when trying to consume purchase on iOS. ## 0.5.1 -* [iOS] Introduce `SKPaymentQueueWrapper.presentCodeRedemptionSheet` +* [iOS] Introduce `SKPaymentQueueWrapper.presentCodeRedemptionSheet` ## 0.5.0 diff --git a/packages/in_app_purchase/in_app_purchase/README.md b/packages/in_app_purchase/in_app_purchase/README.md index 62adaa9b4dec..a51187e792ab 100644 --- a/packages/in_app_purchase/in_app_purchase/README.md +++ b/packages/in_app_purchase/in_app_purchase/README.md @@ -1,56 +1,74 @@ -# In App Purchase +A storefront-independent API for purchases in Flutter apps. -A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases -through the App Store (on iOS) and Google Play (on Android). + + +This plugin supports in-app purchases (_IAP_) through an _underlying store_, +which can be the App Store (on iOS) or Google Play (on Android). + +> This plugin is in beta. Use it with caution and +> [file any potential issues you see](https://github.com/flutter/flutter/issues/new/choose). + +

+ An animated image of the iOS in-app purchase UI +      + An animated image of the Android in-app purchase UI +

## Features -Add this to your Flutter app to: +Use this plugin in your Flutter app to: -1. Show in app products that are available for sale from the underlying shop. - Includes consumables, permanent upgrades, and subscriptions. -2. Load in app products currently owned by the user according to the underlying - shop. -3. Send your user to the underlying store to purchase your products. +* Show in-app products that are available for sale from the underlying store. + Products can include consumables, permanent upgrades, and subscriptions. +* Load in-app products that the user owns. +* Send the user to the underlying store to purchase products. +* Present a UI for redeeming subscription offer codes. (iOS 14 only) -## Getting Started +## Getting started -This plugin is in beta. Please use with caution and file any potential issues -you see on our [issue tracker](https://github.com/flutter/flutter/issues/new/choose). +This plugin relies on the App Store and Google Play for making in-app purchases. +It exposes a unified surface, but you still need to understand and configure +your app with each store. Both stores have extensive guides: -This plugin relies on the App Store and Google Play for making in app purchases. -It exposes a unified surface, but you'll still need to understand and configure -your app with each store to handle purchases using them. Both have extensive -guides: +* [App Store documentation](https://developer.apple.com/in-app-purchase/) +* [Google Play documentation](https://developer.android.com/google/play/billing/billing_overview) -* [In-App Purchase (App Store)](https://developer.apple.com/in-app-purchase/) -* [Google Play Billing Overview](https://developer.android.com/google/play/billing/billing_overview) +For a list of steps for configuring in-app purchases in both stores, see the +[example app README](https://github.com/flutter/plugins/blob/master/packages/in_app_purchase/in_app_purchase/example/README.md). -You can check out the [example app README](https://github.com/flutter/plugins/blob/master/packages/in_app_purchase/example/README.md) for steps on how -to configure in app purchases in both stores. +Once you've configured your in-app purchases in their respective stores, you +can start using the plugin. Two basic options are available: -Once you've configured your in app purchases in their respective stores, you're -able to start using the plugin. There's two basic options available to you to -use. +1. A generic, idiomatic Flutter API: [in_app_purchase](https://pub.dev/documentation/in_app_purchase/latest/in_app_purchase/in_app_purchase-library.html). + This API supports most use cases for loading and making purchases. -1. [in_app_purchase.dart](https://github.com/flutter/plugins/tree/master/packages/in_app_purchase/lib/src/in_app_purchase), - the generic idiomatic Flutter API. This exposes the most basic IAP-related - functionality. The goal is that Flutter apps should be able to use this API - surface on its own for the vast majority of cases. If you use this you should - be able to handle most use cases for loading and making purchases. If you would - like a more platform dependent approach, we also provide the second option as - below. +2. Platform-specific Dart APIs: [store_kit_wrappers](https://pub.dev/documentation/in_app_purchase/latest/store_kit_wrappers/store_kit_wrappers-library.html) + and [billing_client_wrappers](https://pub.dev/documentation/in_app_purchase/latest/billing_client_wrappers/billing_client_wrappers-library.html). + These APIs expose platform-specific behavior and allow for more fine-tuned + control when needed. However, if you use one of these APIs, your + purchase-handling logic is significantly different for the different + storefronts. -2. Dart APIs exposing the underlying platform APIs as directly as possible: - [store_kit_wrappers.dart](https://github.com/flutter/plugins/blob/master/packages/in_app_purchase/lib/src/store_kit_wrappers) and - [billing_client_wrappers.dart](https://github.com/flutter/plugins/blob/master/packages/in_app_purchase/lib/src/billing_client_wrappers). These - API surfaces should expose all the platform-specific behavior and allow for - more fine-tuned control when needed. However if you use this you'll need to - code your purchase handling logic significantly differently depending on - which platform you're on. +## Usage + +This section has examples of code for the following tasks: + +* [Initializing the plugin](#initializing-the-plugin) +* [Listening to purchase updates](#listening-to-purchase-updates) +* [Connecting to the underlying store](#connecting-to-the-underlying-store) +* [Loading products for sale](#loading-products-for-sale) +* [Loading previous purchases](#loading-previous-purchases) +* [Making a purchase](#making-a-purchase) +* [Completing a purchase](#completing-a-purchase) +* [Upgrading or downgrading an existing in-app subscription](#upgrading-or-downgrading-an-existing-in-app-subscription) +* [Presenting a code redemption sheet (iOS 14)](#presenting-a-code-redemption-sheet-ios-14) ### Initializing the plugin +The following initialization code is required for Google Play: + ```dart void main() { // Inform the plugin that this app supports pending purchases on Android. @@ -59,24 +77,32 @@ void main() { // // On iOS this is a no-op. InAppPurchaseConnection.enablePendingPurchases(); - runApp(MyApp()); } ``` +### Listening to purchase updates + +In your app's `initState` method, subscribe to any incoming purchases. These +can propagate from either underlying store. +You should always start listening to purchase update as early as possible to be able +to catch all purchase updates, including the ones from the previous app session. +To listen to the update: + ```dart -// Subscribe to any incoming purchases at app initialization. These can -// propagate from either storefront so it's important to listen as soon as -// possible to avoid losing events. class _MyAppState extends State { StreamSubscription> _subscription; @override void initState() { - final Stream purchaseUpdates = + final Stream purchaseUpdated = InAppPurchaseConnection.instance.purchaseUpdatedStream; - _subscription = purchaseUpdates.listen((purchases) { - _handlePurchaseUpdates(purchases); + _subscription = purchaseUpdated.listen((purchaseDetailsList) { + _listenToPurchaseUpdated(purchaseDetailsList); + }, onDone: () { + _subscription.cancel(); + }, onError: (error) { + // handle error here. }); super.initState(); } @@ -88,7 +114,35 @@ class _MyAppState extends State { } ``` -### Connecting to the Storefront +Here is an example of how to handle purchase updates: + +```dart +void _listenToPurchaseUpdated(List purchaseDetailsList) { + purchaseDetailsList.forEach((PurchaseDetails purchaseDetails) async { + if (purchaseDetails.status == PurchaseStatus.pending) { + _showPendingUI(); + } else { + if (purchaseDetails.status == PurchaseStatus.error) { + _handleError(purchaseDetails.error!); + } else if (purchaseDetails.status == PurchaseStatus.purchased) { + bool valid = await _verifyPurchase(purchaseDetails); + if (valid) { + _deliverProduct(purchaseDetails); + } else { + _handleInvalidPurchase(purchaseDetails); + return; + } + } + if (purchaseDetails.pendingCompletePurchase) { + await InAppPurchaseConnection.instance + .completePurchase(purchaseDetails); + } + } + }); +} +``` + +### Connecting to the underlying store ```dart final bool available = await InAppPurchaseConnection.instance.isAvailable(); @@ -100,30 +154,41 @@ if (!available) { ### Loading products for sale ```dart -// Set literals require Dart 2.2. Alternatively, use `Set _kIds = ['product1', 'product2'].toSet()`. -const Set _kIds = {'product1', 'product2'}; -final ProductDetailsResponse response = await InAppPurchaseConnection.instance.queryProductDetails(_kIds); +// Set literals require Dart 2.2. Alternatively, use +// `Set _kIds = ['product1', 'product2'].toSet()`. +const Set _kIds = {'product1', 'product2'}; +final ProductDetailsResponse response = + await InAppPurchaseConnection.instance.queryProductDetails(_kIds); if (response.notFoundIDs.isNotEmpty) { - // Handle the error. + // Handle the error. } List products = response.productDetails; ``` ### Loading previous purchases +In the following example, implement `_verifyPurchase` so that it verifies the +purchase following the best practices for each underlying store: + +* [Verifying App Store purchases](https://developer.apple.com/documentation/storekit/in-app_purchase/validating_receipts_with_the_app_store) +* [Verifying Google Play purchases](https://developer.android.com/google/play/billing/security#verify) + + ```dart -final QueryPurchaseDetailsResponse response = await InAppPurchaseConnection.instance.queryPastPurchases(); +final QueryPurchaseDetailsResponse response = + await InAppPurchaseConnection.instance.queryPastPurchases(); if (response.error != null) { - // Handle the error. + // Handle the error. } for (PurchaseDetails purchase in response.pastPurchases) { - _verifyPurchase(purchase); // Verify the purchase following the best practices for each storefront. - _deliverPurchase(purchase); // Deliver the purchase to the user in your app. - if (Platform.isIOS) { - // Mark that you've delivered the purchase. Only the App Store requires - // this final confirmation. - InAppPurchaseConnection.instance.completePurchase(purchase); - } + // Verify the purchase following best practices for each underlying store. + _verifyPurchase(purchase); + // Deliver the purchase to the user in your app. + _deliverPurchase(purchase); + if (purchase.pendingCompletePurchase) { + // Mark that you've delivered the purchase. This is mandatory. + InAppPurchaseConnection.instance.completePurchase(purchase); + } } ``` @@ -133,27 +198,9 @@ once they're marked as consumed and fails to return them here. For restoring these across devices you'll need to persist them on your own server and query that as well. -### Listening to purchase updates - -You should always start listening to purchase update as early as possible to be able -to catch all purchase updates, including the ones from the previous app session. -To listen to the update: - -```dart - Stream purchaseUpdated = - InAppPurchaseConnection.instance.purchaseUpdatedStream; - _subscription = purchaseUpdated.listen((purchaseDetailsList) { - _listenToPurchaseUpdated(purchaseDetailsList); - }, onDone: () { - _subscription.cancel(); - }, onError: (error) { - // handle error here. - }); -``` - ### Making a purchase -Both storefronts handle consumable and non-consumable products differently. If +Both underlying stores handle consumable and non-consumable products differently. If you're using `InAppPurchaseConnection`, you need to make a distinction here and call the right purchase method for each type. @@ -161,35 +208,39 @@ call the right purchase method for each type. final ProductDetails productDetails = ... // Saved earlier from queryPastPurchases(). final PurchaseParam purchaseParam = PurchaseParam(productDetails: productDetails); if (_isConsumable(productDetails)) { - InAppPurchaseConnection.instance.buyConsumable(purchaseParam: purchaseParam); + InAppPurchaseConnection.instance.buyConsumable(purchaseParam: purchaseParam); } else { - InAppPurchaseConnection.instance.buyNonConsumable(purchaseParam: purchaseParam); + InAppPurchaseConnection.instance.buyNonConsumable(purchaseParam: purchaseParam); } -// From here the purchase flow will be handled by the underlying storefront. +// From here the purchase flow will be handled by the underlying store. // Updates will be delivered to the `InAppPurchaseConnection.instance.purchaseUpdatedStream`. ``` -### Complete a purchase +### Completing a purchase The `InAppPurchaseConnection.purchaseUpdatedStream` will send purchase updates after you initiate the purchase flow using `InAppPurchaseConnection.buyConsumable` or `InAppPurchaseConnection.buyNonConsumable`. -After delivering the content to the user, you need to call `InAppPurchaseConnection.completePurchase` to tell the `GooglePlay` -and `AppStore` that the purchase has been finished. +After delivering the content to the user, call +`InAppPurchaseConnection.completePurchase` to tell the App Store and +Google Play that the purchase has been finished. -WARNING! Failure to call `InAppPurchaseConnection.completePurchase` and get a successful response within 3 days of the purchase will result a refund. +> **Warning:** Failure to call `InAppPurchaseConnection.completePurchase` and +> get a successful response within 3 days of the purchase will result a refund. -### Upgrading or Downgrading an existing InApp Subscription +### Upgrading or downgrading an existing in-app subscription -In order to upgrade/downgrade an existing InApp subscription on `PlayStore`, -you need to provide an instance of `ChangeSubscriptionParam` with the old -`PurchaseDetails` that the user needs to migrate from, and an optional `ProrationMode` -with the `PurchaseParam` object while calling `InAppPurchaseConnection.buyNonConsumable`. -`AppStore` does not require this since they provides a subscription grouping mechanism. -Each subscription you offer must be assigned to a subscription group. -So the developers can group related subscriptions together to prevents users from -accidentally purchasing multiple subscriptions. -Please refer to the 'Creating a Subscription Group' sections of [Apple's subscription guide](https://developer.apple.com/app-store/subscriptions/) +To upgrade/downgrade an existing in-app subscription in Google Play, +you need to provide an instance of `ChangeSubscriptionParam` with the old +`PurchaseDetails` that the user needs to migrate from, and an optional +`ProrationMode` with the `PurchaseParam` object while calling +`InAppPurchaseConnection.buyNonConsumable`. +The App Store does not require this because it provides a subscription +grouping mechanism. Each subscription you offer must be assigned to a +subscription group. Grouping related subscriptions together can help prevent +users from accidentally purchasing multiple subscriptions. Refer to the +[Creating a Subscription Group](https://developer.apple.com/app-store/subscriptions/#groups) section of +[Apple's subscription guide](https://developer.apple.com/app-store/subscriptions/). ```dart final PurchaseDetails oldPurchaseDetails = ...; @@ -202,7 +253,17 @@ InAppPurchaseConnection.instance .buyNonConsumable(purchaseParam: purchaseParam); ``` -## Development +### Presenting a code redemption sheet (iOS 14) + +The following code brings up a sheet that enables the user to redeem offer +codes that you've set up in App Store Connect. For more information on +redeeming offer codes, see [Implementing Offer Codes in Your App](https://developer.apple.com/documentation/storekit/in-app_purchase/subscriptions_and_offers/implementing_offer_codes_in_your_app). + +```dart +InAppPurchaseConnection.instance.presentCodeRedemptionSheet(); +``` + +## Contributing to this plugin This plugin uses [json_serializable](https://pub.dev/packages/json_serializable) for the @@ -211,3 +272,6 @@ editing any of the serialized data structs, rebuild the serializers by running `flutter packages pub run build_runner build --delete-conflicting-outputs`. `flutter packages pub run build_runner watch --delete-conflicting-outputs` will watch the filesystem for changes. + +If you would like to contribute to the plugin, check out our +[contribution guide](https://github.com/flutter/plugins/blob/master/CONTRIBUTING.md). diff --git a/packages/in_app_purchase/in_app_purchase/doc/iap_android.gif b/packages/in_app_purchase/in_app_purchase/doc/iap_android.gif new file mode 100644 index 0000000000000000000000000000000000000000..86348e4f629420294ac49a6b67c14515325b657a GIT binary patch literal 427150 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%0AhgL5b7zl_E!uL=esAUXlOmm-5VG4g82AP}^C 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

W3WSDh8L@!Jao|KkjPL!B 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

=>8?_CEJ-d*~POxD@y2y(`tj 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

Hnhz&`@^u?@GW$fkTuZea)x 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 yYI3+E~3r@rB=n2+)&eaN>x0T)V(T4&P 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